סקירה כללית
בעזרת מהדר סגירה עם compilation_level
מתוך ADVANCED_OPTIMIZATIONS
אפשר לקבל שיעורי דחיסה טובים יותר מאשר האיסוף עם SIMPLE_OPTIMIZATIONS
או WHITESPACE_ONLY
. ההידור עם ADVANCED_OPTIMIZATIONS
מקבל דחיסה נוספת בכך שהוא אגרסיבי יותר באופן שבו הוא משנה את הקוד ויוצר שם חדש לסמלים. עם זאת, בגישה אגרסיבית זו תצטרכו להיות זהירים יותר כשאתם משתמשים ב-ADVANCED_OPTIMIZATIONS
, כדי לוודא שקוד הפלט פועל כמו בקוד הקלט.
במדריך הזה נסביר איך רמת האוסף ADVANCED_OPTIMIZATIONS
פועלת ומה אפשר לעשות כדי לוודא שהקוד שלכם עובד לאחר הידור האפליקציה ADVANCED_OPTIMIZATIONS
. הוא גם מציג את הקונספט של ה-exter: סמל שמוגדר בקוד חיצוני לקוד שמעובד על ידי המהדר.
לפני קריאת המדריך הזה, כדאי שתכירו את התהליך של הידור JavaScript עם אחד הכלים מהדר סגירה (ממשק המשתמש של מהדר), ממשק ה-API של שירות המהדר או אפליקציית המהדר).
הערה לגבי טרמינולוגיה: הדגל --compilation_level
בשורת הפקודה תומך בקיצורים המקובלים יותר ב-ADVANCED
וב-SIMPLE
, וכן ב-ADVANCED_OPTIMIZATIONS
וב-SIMPLE_OPTIMIZATIONS
המדויקים יותר.
המסמך משתמש בצורה ארוכה יותר, אבל אפשר להחליף בין השמות האלה בשורת הפקודה.
- דחיסה טובה יותר
- איך מפעילים את ADVANCED_LDIMIZATIONS
- למה כדאי לשים לב בעת שימוש ב-ADVANCED_PEIMIZATIONS
דחיסה טובה יותר
בעזרת רמת האיסוף של ברירת המחדל ב-SIMPLE_OPTIMIZATIONS
, מהדר סגירה מבצע הקטנה של JavaScript על ידי שינוי שמות של משתנים מקומיים. עם זאת, יש סמלים אחרים, מלבד משתנים מקומיים, שאפשר לקצר, ויש דרכים לכווץ קוד מלבד שינוי שמות של סמלים. הידור עם ADVANCED_OPTIMIZATIONS
מנצל את כל האפשרויות של כיווץ הקוד.
משווים בין הפלט של SIMPLE_OPTIMIZATIONS
לבין ADVANCED_OPTIMIZATIONS
של הקוד הבא:
function unusedFunction(note) { alert(note['text']); } function displayNoteTitle(note) { alert(note['title']); } var flowerNote = {}; flowerNote['title'] = "Flowers"; displayNoteTitle(flowerNote);
הידור עם SIMPLE_OPTIMIZATIONS
מקצר את הקוד כך:
function unusedFunction(a){alert(a.text)}function displayNoteTitle(a){alert(a.title)}var flowerNote={};flowerNote.title="Flowers";displayNoteTitle(flowerNote);
הידור עם ADVANCED_OPTIMIZATIONS
מקצר את הקוד באופן מלא כך:
alert("Flowers");
שני הסקריפטים האלה מפיקים התראה המציינת את "Flowers"
, אבל הסקריפט השני קטן בהרבה.
ברמה ADVANCED_OPTIMIZATIONS
יש יותר מקיצור של שמות משתנים בכמה דרכים, כולל:
- שינוי שמות אגרסיבי יותר:
כשמשתמשים בשילוב עם
SIMPLE_OPTIMIZATIONS
, אפשר לשנות את השם של הפרמטריםnote
של הפונקציותdisplayNoteTitle()
ו-unusedFunction()
בלבד, כי אלו המשתנים היחידים בסקריפט שהם מקומיים לפונקציה.ADVANCED_OPTIMIZATIONS
גם משנה את השם של המשתנה הגלובליflowerNote
. - הסרת קוד מת:
עריכה עם
ADVANCED_OPTIMIZATIONS
מסירה את הפונקציהunusedFunction()
לגמרי, כי היא אף פעם לא נקראת בקוד. - פונקציה בתוך השורה:
אוסף עם הערך
ADVANCED_OPTIMIZATIONS
מחליף את הקריאה ל-displayNoteTitle()
ב-alert()
שמרכיבים את גוף הפונקציה. ההחלפה הזו של קריאה לפונקציה בגוף הטקסט נקראת "inline". אם הפונקציה הייתה מסובכת יותר או מורכבת יותר, הטבעה עשויה לשנות את ההתנהגות של הקוד, אבל מהדר החסימות קובע שבמקרה הזה הטבעה בטוחה וחוסכת מקום. השילוב עםADVANCED_OPTIMIZATIONS
מאפשר גם להציב קבועים קבועים ומשתנים מסוימים, כאשר הוא קובע שניתן לעשות זאת בצורה בטוחה.
הרשימה הזו היא רק דוגמה לטרנספורמציות של הקבצים שהגודל שלהם יכול לרדת, כך שADVANCED_OPTIMIZATIONS
יוכל לעשות זאת.
איך להפעיל את ADVANCED_LDIMIMZATIONS
בממשק המשתמש של Cloud Compiler API, בשירות ה-API של השירות ובאפליקציה, קיימות שיטות שונות להגדרת compilation_level
בתור ADVANCED_OPTIMIZATIONS
.
איך מפעילים את ADVANCED_OPIMIZATIONS בממשק המשתמש של הכלי לעריכת חסימות
כדי להפעיל את ADVANCED_OPTIMIZATIONS
בממשק המשתמש של
מהדר סגירה, יש ללחוץ על לחצן הבחירה 'מתקדם'.
איך מפעילים את ADVANCED_OPTIMIZATIONS
ב-Clsure Compiler Service API
כדי להפעיל את ADVANCED_OPTIMIZATIONS
ב-Closion Service Compiler API, צריך לכלול פרמטר בקשה בשם compilation_level
עם הערך ADVANCED_OPTIMIZATIONS
, כמו בתוכנית python הבאה:
#!/usr/bin/python2.4 import httplib, urllib, sys params = urllib.urlencode([ ('code_url', sys.argv[1]), ('compilation_level', 'ADVANCED_OPTIMIZATIONS'), ('output_format', 'text'), ('output_info', 'compiled_code'), ]) headers = { "Content-type": "application/x-www-form-urlencoded" } conn = httplib.HTTPSConnection('closure-compiler.appspot.com') conn.request('POST', '/compile', params, headers) response = conn.getresponse() data = response.read() print data conn.close()
איך מפעילים את ADVANCED_OPTIMIZATIONS
באפליקציה מהדר סגירה
כדי להפעיל את ADVANCED_OPTIMIZATIONS
באפליקציית מהדר
סגירה, יש לכלול את הדגל של שורת הפקודה
--compilation_level ADVANCED_OPTIMIZATIONS
, כמו בפקודה הבאה:
java -jar compiler.jar --compilation_level ADVANCED_OPTIMIZATIONS --js hello.js
למה צריך לשקול שימוש ב-ADVANCED_PEIMIZATIONS
בהמשך מפורטות כמה השפעות נפוצות לא מכוונות של ADVANCED_PEIMIZATIONS, ופירוט של הפעולות שניתן לבצע כדי למנוע אותן.
הסרת קוד שברצונך להשאיר
אם תרכיבו רק את הפונקציה הבאה באמצעות ADVANCED_OPTIMIZATIONS
, הכלי להשלמת סגירה יוצר פלט ריק:
function displayNoteTitle(note) { alert(note['myTitle']); }
מכיוון שהפונקציה אף פעם לא נקראת ב-JavaScript שמעבירים אל המהדר, ההנחה של מהדר ההנחה מניחה שאין צורך בקוד הזה!
במקרים רבים, זה בדיוק מה שאתם רוצים. לדוגמה, אם אתם מהדרים את הקוד שלכם בספרייה גדולה, מהדר סגירה יכול לקבוע אילו פונקציות יש בספרייה בפועל, ולמחוק את אלה שאתם לא משתמשים בהן.
עם זאת, אם גיליתם שהכלי לאישור חסימות מסיר את הפונקציות שאתם רוצים לשמור, יש שתי דרכים למנוע זאת:
- מעבירים את הפונקציות לפונקציה לקוד שמעובד על ידי מהדר סגירה.
- יש לכלול את הפרטים החיצוניים של הפונקציות שרוצים לחשוף.
בחלקים הבאים אנחנו מפרטים כל אפשרות בפירוט.
פתרון: העברת הקריאות לפונקציה אל הקוד שעברו עיבוד על ידי מהדר הסגירה
ייתכן שתיתקלו בהסרת קוד לא רצויה אם תכללו רק חלק מהקוד באמצעות מהדר סגירה. לדוגמה, יכול להיות שיש לכם קובץ ספרייה שמכיל רק הגדרות של פונקציות, וקובץ HTML שמכיל את הספרייה עם הקוד שמפעיל את הפונקציות האלה. במקרה כזה, אם תוסיפו את קובץ הספרייה ל-ADVANCED_OPTIMIZATIONS
, הכלי מהדקי חסימות יסיר את כל פונקציות הספרייה.
הפתרון הפשוט ביותר לבעיה הזו הוא להרכיב את הפונקציות שלכם יחד עם החלק של התוכנה שמפעיל את הפונקציות האלה.
לדוגמה, מהדר סגירה לא יסיר את displayNoteTitle()
כאשר הוא כולל את התוכנית:
function displayNoteTitle(note) { alert(note['myTitle']); } displayNoteTitle({'myTitle': 'Flowers'});
הפונקציה displayNoteTitle()
לא הוסרה במקרה הזה, כי מהדר סגירה רואה שהיא נקראת.
במילים אחרות, תוכלו למנוע הסרה לא רצויה של קוד על ידי ציון נקודת הכניסה של התוכנית בקוד שאתם מעבירים ל'הכלי להיסגר'. נקודת הכניסה של תוכנית היא המקום בקוד שבו התוכנית מתחילה לבצע. לדוגמה, בתוכנית הערות לגבי פרחים מהקטע הקודם, שלוש השורות האחרונות מופעלות ברגע ש-JavaScript נטען בדפדפן. זוהי נקודת הכניסה לתוכנית הזו. כדי להחליט איזה קוד עליכם לשמור, מהדר סגירה מתחיל בנקודת הכניסה הזו ומאתר את זרימת הבקרה של התוכנית הלאה.
פתרון: הוספת תוספים לפונקציות שאתם רוצים לחשוף
מידע נוסף על הפתרון הזה מופיע בהמשך ובדף מידע על ייצוא וייצוא.
שמות נכס לא עקביים
אוסף ההידור של 'סגירה' אף פעם לא משנה את 'מחרוזת' של מחרוזות בקוד, בלי קשר לרמת ההידור שבה אתם משתמשים. כלומר, השילוב עם ADVANCED_OPTIMIZATIONS
מתייחס לנכסים שונים בהתאם לקוד הגישה שלהם, באמצעות מחרוזת. אם תשלבו הפניות ממחרוזות לנכס עם הפניות של תחביר נקודה, שם של מהדק סגירה משנה את השם של חלק מההפניות לנכס הזה, אבל לא של אחרות. כתוצאה מכך, סביר להניח שהקוד שלכם לא יפעל כמו שצריך.
לדוגמה, צריך להשתמש בקוד הבא:
function displayNoteTitle(note) { alert(note['myTitle']); } var flowerNote = {}; flowerNote.myTitle = 'Flowers'; alert(flowerNote.myTitle); displayNoteTitle(flowerNote);
שתי ההצהרות האחרונות בקוד המקור הזה
עושות בדיוק את אותו הדבר. עם זאת, כשדוחסים את הקוד עם ADVANCED_OPTIMIZATIONS
, אפשר לקבל:
var a={};a.a="Flowers";alert(a.a);alert(a.myTitle);
ההצהרה האחרונה בקוד הדחוס יוצרת שגיאה. השם של ההפניה הישירה לנכס myTitle
שונה ל-a
, אבל ההפניה המצוטטת ל-myTitle
בתוך הפונקציה displayNoteTitle
לא השתנתה. כתוצאה מכך, ההצהרה האחרונה מתייחסת
לנכס myTitle
שכבר לא קיים.
פתרון: לשמור על עקביות בשמות הנכסים
הפתרון הזה פשוט למדי. לכל מטרה או סוג נתונים, השתמשו אך ורק במחרוזות נקודה-תחביר או במירכאות. אל תשלבו בין התחבירים, במיוחד בהקשר של אותו נכס.
כמו כן, אם הדבר אפשרי, עדיף להשתמש בתחביר של נקודה-פסיק מאחר שהוא תומך בבדיקות ובאופטימיזציות טובות יותר. להשתמש בגישה עם מאפיין של מחרוזת במירכאות רק כשלא רוצים לשנות את השם של מהדר סגירה, למשל כשהשם מגיע ממקור חיצוני, כמו JSON מפוענח.
הכנת שני חלקים של קוד בנפרד
אם פיצלתם את האפליקציה לחלקים שונים של קוד, מומלץ לחבר את הקטעים בנפרד. עם זאת, אם שני קטעי קוד מקיימים אינטראקציה בכלל, זה עלול לגרום קושי. גם אם תצליחו, הפלט של שתי ההפעלות של מהדרי החסימות לא יהיה תואם.
לדוגמה, נניח שיישום מחולק לשני חלקים: חלק שמאחזר נתונים, וחלק שמציג נתונים.
הנה הקוד לאחזור הנתונים:
function getData() { // In an actual project, this data would be retrieved from the server. return {title: 'Flower Care', text: 'Flowers need water.'}; }
הנה הקוד להצגת הנתונים:
var displayElement = document.getElementById('display'); function displayData(parent, data) { var textElement = document.createTextNode(data.text); parent.appendChild(textElement); } displayData(displayElement, getData());
אם תנסו להדר את שני קטעי הקוד האלה בנפרד, תיתקלו בכמה בעיות. תחילה, מהדר החסימות מסיר את הפונקציה getData()
מהסיבות שמפורטות בהסרת הקוד שרוצים לשמור. שנית, מהדר סגירה יוצר שגיאה חמורה בעת עיבוד הקוד שמציג את הנתונים.
input:6: ERROR - variable getData is undefined displayData(displayElement, getData());
מכיוון שלדור המהדר אין גישה לפונקציה getData()
בזמן ההידור של הקוד שמציג את הנתונים, הוא מתייחס ל-getData
כ"לא מוגדר".
פתרון: עריכת כל הקוד לדף אחד
כדי להבטיח הידור מתאים, הרכב את כל הקוד של דף יחד ברכיב הידור אחד. מהדר סגירה יכול לקבל קובצי JavaScript ומחרוזות JavaScript מרובות כקלט, כדי שתוכלו להעביר ביחד את קוד הספרייה וקוד אחר בבקשת הידור אחת.
הערה: הגישה הזו לא תפעל אם צריך לשלב קוד מהודר וגם קוד לא מורכב. לקבלת טיפים להתמודדות עם מצב זה, יש לעיין בקטע הפניות קטועות בין קוד מהדר וקוד לא מרוכב.
הפניות קטועות בין קוד שנוצר לבין קוד ללא הידור
שינוי השם של הסמל ב-ADVANCED_OPTIMIZATIONS
ישבש את התקשורת בין הקוד שעובד על ידי מהדר החסימות לבין כל קוד אחר. קומפילציה משנה את השם של הפונקציות שמוגדרות בקוד המקור. כל קוד חיצוני שמפעיל את הפונקציות שלכם יקטע לאחר הידור, מפני שהוא עדיין מתייחס לשם הפונקציות הישן. באופן דומה, קובצי עזר שהקוד שלהם עבר הידור לסמלים המוגדרים באופן חיצוני עשויים להשתנות גם כן על ידי מהדר סגירה.
חשוב לזכור שהקטע "קוד לא מורכב" כולל כל קוד שמועבר לפונקציה eval()
כמחרוזת. מהדר סגירה לא משנה אף פעם ליטרל מחרוזות בקוד, אז מהדר סגירה לא משנה מחרוזות שהועברו להצהרות eval()
.
חשוב לדעת שמדובר בבעיות קשורות אך ייחודיות: שמירה על תקשורת עם קלט מבחוץ ושמירה על תקשורת חיצונית עם הידור. לבעיות הנפרדות האלה יש פתרון נפוץ, אבל יש הבדלים דקים בכל צד. כדי להפיק את המקסימום מהמהדר לסגירה, חשוב להבין מה בקשות התמיכה שלכם.
לפני שתמשיכו, כדאי להכיר את המידע החיצוני והייצוא.
פתרון קריאה לקוד חיצוני מקוד הידור: עריכה עם תוספות
אם אתם משתמשים בקוד שקיבלתם בדף כתוצאה מסקריפט אחר, עליכם לוודא שמהדר החסימות לא משנה את השם של הסמלים שהספרייה החיצונית שלהם מגדירה. כדי לעשות את זה, אתם צריכים לצרף לאוסף קובץ שמכיל את החלקים החיצוניים של הספרייה החיצונית. על סמך המידע הזה, מהדר סגירה יקבע אילו שמות אינם בשליטתכם, ולכן לא ניתן יהיה לשנות אותם. הקוד צריך להשתמש באותם שמות שבקובץ החיצוני.
דוגמאות נפוצות לכך הן ממשקי API כמו OpenSocial API ו-Google Maps API. לדוגמה, אם הקוד שלכם מבצע קריאה לפונקציה OpenSocial opensocial.newDataRequest()
, ללא הפונקציות החיצוניות, מהדר הסגירה יהפוך את הקריאה הזו ל-a.b()
.
פתרון לקריאת קוד שהורכב מקוד חיצוני: הטמעת רכיבים חיצוניים
אם יש לכם קוד JavaScript שמשמש אתכם כספרייה, כדאי להשתמש בכלי מהדר סגירה כדי לכווץ רק את הספרייה, ובמקביל לאפשר לקוד לא מעובד להפעיל פונקציות בספרייה.
במקרה כזה, צריך להטמיע קבוצה של כלים חיצוניים שמגדירים את ממשק ה-API הציבורי של הספרייה. הקוד יספק הגדרות של הסמלים המוצהרים בתוסף הזה. כלומר, כל המחלקה או הפונקציות החיצוניות. ייתכן גם שיהיה צורך להכריז על ממשקי ההטמעה של הכיתות החיצוניים.
התוספים האלה שימושיים גם לאחרים, ולא רק לך. הצרכנים של הספרייה שלכם יצטרכו לכלול אותם אם הם מכינים את הקוד שלהם, כי הספרייה מייצגת סקריפט חיצוני מנקודת המבט שלהם. חשוב על החלק החיצוני כחוזה בינך לבין הצרכנים שלך, שניכם צריכים עותק.
לשם כך, כשאתם מכינים את הקוד, עליכם לכלול גם את החלק החיצוני של האוסף. זה לא נראה חריג, מכיוון שלעיתים קרובות אנחנו חושבים שמקור התוכן הוא "מגיע ממקור אחר", אבל צריך להסביר ל"מה של היוצר שסבל" אילו סמלים אתם חושפים, כך שהשם שלהם לא משתנה.
חשוב לשים לב שכאן ניתן לקבל אבחון של "הגדרה כפולה" לגבי הקוד שמגדיר את הסמלים החיצוניים. ההנחה לגבי סגירת המידע היא שכל סמל חיצוני סופק על ידי ספרייה חיצונית, ואין לו אפשרות להבין בשלב זה שאתם מספקים הגדרה באופן מכוון. הניתוחים האלה בטוחים להסתרה, ואפשר לראות בהם דיכוי של אישור הביצוע בפועל של ה-API.
בנוסף, מהדר סגירה עשוי לבדוק שההגדרות שלך תואמות את סוגי ההצהרות החיצוניות. זה מספק אישור נוסף שההגדרות שלכם נכונות.