סקריפטים של צד שלישי משפיעים על הביצועים, ולכן חשוב לבדוק אותם באופן קבוע ולהשתמש בשיטות יעילות לטעינה. ב-Codelab הזה מוסבר איך לייעל את הטעינה של משאבים של צד שלישי. הוא עוסק בשיטות הבאות:
דחייה של טעינת הסקריפט
טעינה מדורגת של משאבים לא קריטיים
התחברות מראש למקורות נדרשים
האפליקציה לדוגמה הכלולה באפליקציה כוללת דף אינטרנט פשוט עם שלוש תכונות שמגיעות ממקורות של צד שלישי:
הטמעת סרטון
ספריית הצגה חזותית של נתונים לעיבוד גרף קו
ווידג'ט לשיתוף במדיה חברתית
מתחילים במדידת הביצועים של האפליקציה, ולאחר מכן מיישמים כל שיטה כדי לשפר היבטים שונים של ביצועי האפליקציה.
מדידת ביצועים
קודם פותחים את האפליקציה לדוגמה בתצוגת מסך מלא:
- לוחצים על רמיקס לעריכה כדי לערוך את הפרויקט.
- כדי לראות תצוגה מקדימה של האתר, לוחצים על הצגת האפליקציה. לאחר מכן לוחצים על מסך מלא .
מפעילים בדיקת ביצועים של Lighthouse בדף כדי לבדוק את רמת הביצועים הבסיסית:
- מקישים על 'Control+Shift+J' (או על 'Command+Option+J' ב-Mac) כדי לפתוח את כלי הפיתוח.
- לוחצים על הכרטיסייה Lighthouse.
- לוחצים על Mobile (נייד).
- מסמנים את התיבה Performance (ביצועים). (אפשר למחוק את שאר תיבות הסימון בקטע 'ביקורות').
- לוחצים על Simulated Fast 3G, 4x CPU Slowdown.
- מסמנים את התיבה נקה נפח אחסון.
- לוחצים על Run Reviews.
כשמריצים ביקורת במחשב, התוצאות המדויקות עשויות להשתנות, אבל כדאי להבחין שזמן המהירות שבה נטען רכיב התוכן הראשון (FCP) די ארוך, וש-Lighthouse מציע שתי הזדמנויות שכדאי לבדוק: ביטול משאבים שחוסמים משאבים וקישור מראש למקורות נדרשים. (גם אם כל המדדים בצבע ירוק, פעולות אופטימיזציה עדיין יניבו שיפורים).
דחיית JavaScript של צד שלישי
הביקורת הסרת משאבים חוסמי עיבוד זיהתה שאפשר לחסוך זמן על ידי דחייה של סקריפט שמגיע מ-d3js.org:
D3.js היא ספריית JavaScript ליצירת תצוגות חזותיות של נתונים. הקובץ script.js
באפליקציה לדוגמה משתמש בפונקציות שירות D3 כדי ליצור את תרשים הקו מסוג SVG ולצרף אותו לדף. סדר הפעולות כאן חשוב: script.js
צריך לפעול לאחר ניתוח המסמך וספריית D3 נטענה, ולכן הוא נכלל מיד לפני תג </body>
הסוגר ב-index.html
.
עם זאת, סקריפט D3 נכלל ב<head>
של הדף, שחוסם את הניתוח של המסמך הנותר:
שני מאפייני קסם יכולים לבטל את חסימת המנתח כשמוסיפים אותם לתג הסקריפט:
async
מבטיח שהסקריפטים יורדים ברקע ויופעלו בהזדמנות הראשונה בסיום ההורדה.defer
מבטיח שהסקריפטים יורדים ברקע ופועלים לאחר שהניתוח מסתיים.
מכיוון שהתרשים הזה לא ממש קריטי לדף הכולל, וסביר להניח שהוא יופיע בחלק הנגלל, צריך להשתמש ב-defer
כדי לוודא שאין חסימה של המנתח.
שלב 1: טוענים את הסקריפט באופן אסינכרוני עם המאפיין defer
בשורה 17 ב-index.html
, מוסיפים את המאפיין defer
לרכיב <script>
:
<script src="https://d3js.org/d3.v3.min.js" defer></script>
שלב 2: מוודאים שהסדר הנכון של הפעולות
עכשיו ש-D3 נדחה, script.js
יפעל לפני ש-D3 מוכן, תתקבל שגיאה.
סקריפטים עם המאפיין defer
מופעלים לפי הסדר שבו צוינו. כדי לוודא שscript.js
יופעל אחרי ש-D3 מוכן, צריך להוסיף אליו את defer
ולהעביר אותו אל <head>
של המסמך, מיד אחרי הרכיב <script>
D3. עכשיו הוא לא חוסם יותר את המנתח, וההורדה מתחילה מוקדם יותר.
<script src="https://d3js.org/d3.v3.min.js" defer></script>
<script src="./script.js" defer></script>
טעינה מדורגת של משאבים של צד שלישי
כל המשאבים שנמצאים בחלק התחתון והקבוע יכולים להתאים לטעינה מדורגת.
באפליקציה לדוגמה יש סרטון YouTube שמוטמע ב-iframe. כדי לבדוק כמה בקשות הדף שולח ואילו מגיעות מה-iframe המוטמע של YouTube:
- כדי לראות תצוגה מקדימה של האתר, לוחצים על הצגת האפליקציה. לאחר מכן לוחצים על מסך מלא .
- מקישים על 'Control+Shift+J' (או על 'Command+Option+J' ב-Mac) כדי לפתוח את כלי הפיתוח.
- לוחצים על הכרטיסייה רשתות.
- מסמנים את התיבה Disable cache (השבתת מטמון).
- בוחרים באפשרות Fast 3G בתפריט הנפתח Throttling.
- לטעון מחדש את הדף.
בחלונית רשת אפשר לראות שהדף ביצע 28 בקשות בסך הכול והועבר כמעט 1MB של משאבים דחוסים.
כדי לזהות את הבקשות שנשלחו על ידי iframe
ב-YouTube, צריך לחפש את מזהה הווידאו 6lfaiXM6waw
בעמודה יוזם. כדי לקבץ יחד את כל הבקשות לפי דומיין:
בחלונית רשת, לוחצים לחיצה ימנית על כותרת העמודה.
בתפריט הנפתח, בוחרים בעמודה דומיינים.
כדי למיין את הבקשות לפי דומיין, לוחצים על שם העמודה דומיינים.
שיטת המיון החדשה חושפת שיש בקשות נוספות לדומיינים של Google. בסך הכול, ה-iframe של YouTube שולח 14 בקשות לסקריפטים, לגיליונות סגנונות, לתמונות ולגופנים. אבל אם המשתמשים לא גוללים למטה כדי להפעיל את הסרטון, הם לא באמת צריכים את כל הנכסים האלה.
בהמתנה לטעינה מדורגת של הסרטון עד שמשתמש יגלול לקטע הזה בדף, וכך תקצר את מספר הבקשות שהדף ישלח בהתחלה. הגישה הזאת חוסכת ומאיצה את הטעינה הראשונית.
אחת הדרכים להשתמש בטעינה מדורגת היא באמצעות Intersection Observer – ממשק API של דפדפן לקבלת התראה כשרכיב נכנס לאזור התצוגה של הדפדפן או יוצא ממנו.
שלב 1: מניעת טעינה ראשונית של הסרטון
כדי לבצע טעינה מדורגת של ה-iframe של הסרטון, תחילה עליכם למנוע ממנו להיטען בדרך הרגילה. כדי לעשות את זה, צריך להחליף את המאפיין src
במאפיין data-src
כדי לציין את כתובת ה-URL של הסרטון:
<iframe width="560" height="315" data-src="https://www.youtube.com/embed/lS9D6w1GzGY" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe>
data-src
הוא מאפיין נתונים, שמאפשר לאחסן מידע נוסף על רכיבי HTML רגילים. אפשר לתת למאפיין נתונים כל שם, כל עוד הוא מתחיל ב-'data- '.
iframe ללא src
פשוט לא ייטען.
שלב 2: משתמשים ב-Intersection Observer כדי לבצע טעינה מדורגת של הסרטון
כדי לטעון את הסרטון כשמשתמש גולל אליו, אתם צריכים לדעת מתי זה קורה. כאן נכנסים לתמונה Intersection Observer API. ממשק ה-API של Intersection Observer מאפשר לרשום פונקציית קריאה חוזרת שמופעלת בכל פעם שרכיב שרוצים לעקוב אחריו נכנס לאזור התצוגה או יוצא ממנו.
כדי להתחיל, יוצרים קובץ חדש ונותנים לו את השם lazy-load.js
:
- לוחצים על קובץ חדש ונותנים לו שם.
- לוחצים על Add This File (הוספת הקובץ הזה).
מוסיפים את תג הסקריפט לראש המסמך:
<script src="/lazy-load.js" defer></script>
ב-lazy-load.js
, יוצרים IntersectionObserver
חדש ומעבירים אליו פונקציית קריאה חוזרת כדי להריץ אותו:
// create a new Intersection Observer
let observer = new IntersectionObserver(callback);
עכשיו צריך להעביר ל-observer
רכיב יעד לצפייה (במקרה הזה, ה-iframe של הסרטון) על ידי העברתו כארגומנט בשיטה observe
:
// the element that you want to watch
const element = document.querySelector('iframe');
// register the element with the observe method
observer.observe(element);
callback
מקבל רשימה של IntersectionObserverEntry
אובייקטים והאובייקט IntersectionObserver
עצמו. כל רשומה מכילה רכיב ומאפיינים של target
שמתארים את המידות, המיקום, השעה שבה נכנסה לאזור התצוגה ועוד. אחד המאפיינים של IntersectionObserverEntry
הוא isIntersecting
– ערך בוליאני ששווה ל-true
כשהרכיב נכנס לאזור התצוגה.
בדוגמה הזו, הערך target
הוא iframe
. isIntersecting
שווה ל-true
כש-target
נכנס לאזור התצוגה. כדי לראות את המידע הזה בפעולה, מחליפים את callback
בפונקציה הבאה:
let observer = new IntersectionObserver(callback);
let observer = new IntersectionObserver(function(entries, observer) {
entries.forEach(entry => {
console.log(entry.target);
console.log(entry.isIntersecting);
});
});
- כדי לראות תצוגה מקדימה של האתר, לוחצים על הצגת האפליקציה. לאחר מכן לוחצים על מסך מלא .
- מקישים על 'Control+Shift+J' (או על 'Command+Option+J' ב-Mac) כדי לפתוח את כלי הפיתוח.
- לוחצים על הכרטיסייה מסוף.
נסו לגלול למעלה ולמטה. הערך של השינוי של isIntersecting
אמור להופיע ורכיב היעד נרשם במסוף.
כדי לטעון את הסרטון כשהמשתמש גולל למיקום שלו, משתמשים ב-isIntersecting
כתנאי להרצת פונקציה loadElement
, שמקבלת את הערך מהdata-src
של הרכיב iframe
ומגדירה אותו כמאפיין src
של הרכיב iframe
. ההחלפה הזו מפעילה את טעינת הסרטון. לאחר מכן, אחרי שהסרטון נטען, מפעילים את השיטה unobserve
ב-observer
כדי להפסיק את הצפייה ברכיב היעד:
let observer = new IntersectionObserver(function (entries, observer) {
entries.forEach(entry => {
console.log(entry.target);
console.log(entry.isIntersecting);
});
});
if (entry.isIntersecting) {
// do this when the element enters the viewport
loadElement(entry.target);
// stop watching
observer.unobserve(entry.target);
}
});
});
function loadElement(element) {
const src = element.getAttribute('data-src');
element.src = src;
}
שלב 3: הערכה מחדש של הביצועים
כדי לראות איך הגודל והמספר של המשאבים השתנו, פותחים את החלונית רשת של כלי הפיתוח וטוענים מחדש את הדף. בחלונית רשת רואים שהדף שלח 14 בקשות ורק 260KB. זהו שיפור משמעותי!
עכשיו גוללים למטה בדף ועוקבים אחרי החלונית רשת. כשתגיעו לסרטון, הדף אמור להפעיל בקשות נוספות.
צריך להתחבר מראש למקורות הנדרשים
דחית את כל הבקשות מ-YouTube שהן לא קריטיות והטענת בהדרגה את הבקשות ל-YouTube. לכן הגיע הזמן לבצע אופטימיזציה של שאר התוכן של צד שלישי.
הוספה של המאפיין rel=preconnect
לקישור מורה לדפדפן ליצור חיבור לדומיין לפני שליחת הבקשה למשאב הזה. מומלץ להשתמש במאפיין הזה במקורות שמספקים משאבים שאתם בטוחים שהדף צריך.
הביקורת של Lighthouse שהרצת בשלב הראשון, שהוצעה בקטע Preconnect למקורות נדרשים. ניתן לחסוך כ-400 אלפיות השנייה על ידי יצירת חיבורים מוקדמים ל-staticxx.facebook.com ול-youtube.com:
מכיוון שהסרטון ב-YouTube נטען עכשיו באופן מדורג, רק staticxx.facebook.com הוא המקור של ווידג'ט השיתוף במדיה החברתית. כדי ליצור חיבור מוקדם לדומיין הזה בקלות, אפשר להוסיף תג <link>
ל-<head>
של המסמך:
<link rel="preconnect" href="https://staticxx.facebook.com">
הערכה מחדש של הביצועים
זהו מצב הדף לאחר אופטימיזציה. יש לפעול לפי השלבים שבקטע מדידת ביצועים ב-Codelab כדי להריץ ביקורת נוספת של Lighthouse.