סקריפטים של צד שלישי משפיעים על הביצועים, ולכן חשוב לסקור אותם באופן קבוע ולהשתמש בשיטות יעילות לטעינה שלהם. בשיעור הזה תלמדו איך לבצע אופטימיזציה של טעינת משאבים של צד שלישי. המאמר עוסק בטכניקות הבאות:
דחיית טעינת הסקריפט
טעינה מדורגת של משאבים לא קריטיים
התחברות מראש למקורות נדרשים
האפליקציה לדוגמה הכלולה כוללת דף אינטרנט פשוט עם שלוש תכונות שמגיעות ממקורות צד שלישי:
הטמעת סרטון
ספריית נתונים להמחשת נתונים לעיבוד תרשים קו
ווידג'ט לשיתוף ברשתות חברתיות
מתחילים במדידת הביצועים של האפליקציה, ולאחר מכן מחילים כל שיטה כדי לשפר היבטים שונים של ביצועי האפליקציה.
מדידת ביצועים
קודם כול פותחים את האפליקציה לדוגמה בתצוגת מסך מלא:
- לוחצים על רמיקס לעריכה כדי שיהיה אפשר לערוך את הפרויקט.
- כדי לראות תצוגה מקדימה של האתר, מקישים על View App ואז על Fullscreen .
אפשר להריץ בדיקת ביצועים של Lighthouse כדי לקבוע את רמת הביצועים הבסיסית:
- לוחצים על 'Control+Shift+J' (או 'Command+Option+J' ב-Mac) כדי לפתוח את כלי הפיתוח.
- לוחצים על הכרטיסייה Lighthouse.
- לוחצים על נייד.
- מסמנים את התיבה ביצועים. (אפשר למחוק את שאר התיבות בקטע 'ביקורות'.)
- לוחצים על Simulated Fast 3G, 4x CPU Slowdown.
- מסמנים את התיבה פינוי נפח אחסון.
- לוחצים על הרצת ביקורות.
כשאתם מריצים ביקורת במחשב, התוצאות המדויקות עשויות להשתנות, אבל אתם שמים לב שמשך הזמן הנדרש להצגת הצגת תוכן ראשוני (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>
של המסמך, מיד אחרי הרכיב D3 <script>
. עכשיו הוא כבר לא חוסם את המנתח, וההורדה מתחילה מוקדם יותר.
<script src="https://d3js.org/d3.v3.min.js" defer></script>
<script src="./script.js" defer></script>
טעינה מדורגת של משאבי צד שלישי
כל המשאבים שמופיעים בחלק הנגלל הם מועמדים טובים לטעינה מדורגת.
באפליקציה לדוגמה יש סרטון YouTube שמוטמע ב-iframe. כדי לבדוק כמה בקשות הדף שולח ומגיעות מה-iframe המוטמע של YouTube:
- כדי לראות תצוגה מקדימה של האתר, מקישים על View App ואז על Fullscreen .
- לוחצים על 'Control+Shift+J' (או 'Command+Option+J' ב-Mac) כדי לפתוח את כלי הפיתוח.
- לוחצים על הכרטיסייה רשתות.
- מסמנים את התיבה Disable cache (השבתת המטמון).
- בוחרים באפשרות Fast 3G בתפריט הנפתח Throttling.
- לטעון מחדש את הדף.
בחלונית רשת, נחשף שהדף שלח 28 בקשות בסך הכול והועבר כמעט 1MB של משאבים דחוסים.
כדי לזהות את הבקשות שנשלחו על ידי iframe
ב-YouTube, צריך לחפש את מזהה הווידאו 6lfaiXM6waw
בעמודה יוזם. כדי לקבץ את כל הבקשות לפי דומיין:
בחלונית רשת, לוחצים לחיצה ימנית על כותרת העמודה.
בתפריט הנפתח, בוחרים את העמודה דומיינים.
כדי למיין את הבקשות לפי דומיין, לוחצים על כותרת העמודה דומיינים.
המיון החדש חושף שיש בקשות נוספות לדומיינים של Google. בסך הכול, ה-iframe של YouTube שולח 14 בקשות לסקריפטים, לדפי סגנונות, לתמונות ולגופנים. אבל אלא אם המשתמשים ממש גוללים למטה כדי להפעיל את הסרטון, הם לא צריכים את כל הנכסים האלה.
כשאתם ממתינים לטעינה מדורגת של הסרטון עד שמשתמש גולל למטה לקטע הזה בדף, אתם מקצרים את מספר הבקשות שהדף שולח בהתחלה. גישה זו חוסכת את נתוני המשתמשים ומזרזת את הטעינה הראשונית.
אחת מהדרכים להטמיע טעינה מושהית היא באמצעות Intersection Exploreer – ממשק 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 Exploreer כדי לטעון את הסרטון בהדרגה
כדי לטעון את הסרטון כאשר משתמש גולל אליו, עליכם לדעת מתי זה קורה. כאן נכנס לתמונה ה-Intersection Overer API. ממשק ה-API של Intersection Exploreer מאפשר לרשום פונקציית קריאה חוזרת שמופעלת בכל פעם שרכיב שרוצים לעקוב אחריו נכנס לאזור התצוגה או יוצא ממנו.
כדי להתחיל, צרו קובץ חדש ותנו לו את השם 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 של הסרטון) על ידי העברתו כארגומנט ב-method 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);
});
});
- כדי לראות תצוגה מקדימה של האתר, מקישים על View App ואז על Fullscreen .
- לוחצים על '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: הערכה מחדש של הביצועים
כדי לראות את השינויים בגודל ובמספר של המשאבים, צריך לפתוח את החלונית Network של כלי הפיתוח ולטעון מחדש את הדף שוב. בחלונית רשת נחשף שהדף שלח 14 בקשות ו-260KB בלבד. זהו שיפור משמעותי!
עכשיו גוללים למטה בדף ומעיינים בחלונית רשת. כשתגיעו לסרטון, תוכלו לראות שהדף הפעיל בקשות נוספות.
יש להתחבר מראש למקורות נדרשים
דחיתם את רכיבי JavaScript שאינם קריטיים וטענתם באופן הדרגתי את הבקשות מ-YouTube, לכן הגיע הזמן לבצע אופטימיזציה של שאר התוכן של צד שלישי.
הוספת המאפיין rel=preconnect
לקישור מורה לדפדפן ליצור חיבור לדומיין לפני שליחת הבקשה למשאב. מומלץ להשתמש במאפיין הזה במקורות שמספקים משאבים שאתם בטוחים שנדרשים לדף.
הביקורת של Lighthouse שהרצת בשלב הראשון הוצעה בקישור מראש למקורות נדרשים. הבדיקה הזו מאפשרת לך לחסוך כ-400 אלפיות השנייה על ידי יצירת חיבורים מוקדמים אל staticxx.facebook.com ו-youtube.com:
מאחר שהסרטון ב-YouTube נטען עכשיו בצורה מדורגת, נשאר רק staticxx.facebook.com, המקור של ווידג'ט השיתוף של המדיה החברתית. יצירת חיבור מוקדם לדומיין הזה פשוטה כמו הוספת תג <link>
ל-<head>
של המסמך:
<link rel="preconnect" href="https://staticxx.facebook.com">
הערכה מחדש של הביצועים
זה מצב הדף אחרי האופטימיזציה. פועלים לפי השלבים שבקטע Measure performance (מדידת הביצועים) ב-Codelab כדי להריץ ביקורת נוספת של Lighthouse.