כדי לצמצם חסימת רינדור, זהו איזה CSS ו-JavaScript נדרשים לפני הופעת תוכן שימושי והעבירו עבודה מיותרת מחוץ לנתיב הזה. השאירו עיצוב חיוני זמין, בחרו צורת טעינת סקריפט מתאימה ואל תטענו מראש כל משאב. המטרה היא תצוגה נכונה מוקדמת יותר, ולא מחיקת אזהרה במחיר דף לא מעוצב או פגום.
הפרידו בין רינדור, פענוח ועבודת התהליכון הראשי
הדפדפן מפרש HTML ל-DOM וסגנונות למידע תצוגה. הוא משלב מבנה וכללים, מחשב פריסה ומצייר פיקסלים. קובץ CSS שחל על הדף יכול לעכב רינדור, משום שהדפדפן צריך את כלליו לקביעת המראה.
סקריפט קלאסי ללא async או defer יכול לעצור את פענוח ה-HTML בזמן הורדה והרצה. חסימת הפענוח שונה מהוראת חסימת רינדור מפורשת, אף שהיא עלולה לעכב גילוי ותצוגה. סקריפט עשוי גם להמתין ל-CSS קודם, כי הוא יכול לקרוא סגנונות. שרשרת התלויות חשובה יותר מסיומת הקובץ.
גם סקריפט שיורד אסינכרונית רץ בתהליכון הראשי, אלא אם עבודתו הועברה במפורש למקום אחר. הרצה ארוכה יכולה לעכב ציור ועיבוד קלט לאחר ההורדה. מאפיין טעינה משנה תזמון, ולא מבטל עבודה.
זהו את האירוע הנראה שנפגע. בתמונה מאוחרת, הפרידו הורדה מ-CSS או JavaScript שמונעים הצגה. מדריך LCP מפריד את השלבים. אם הדף מופיע מהר אך מגיב לאט, השתמשו בניתוח זמן הרצת JavaScript.
קראו את התלויות בכלים העדכניים
הניסוח הישן של הסרת משאבים חוסמי רינדור עדיין מופיע בחיפושים ובדוחות. Lighthouse 13 העביר בדיקות רבות לתובנות, ודוחות חדשים עשויים להציג תובנה על בקשות חוסמות. העיקרון נשאר, אך מזהים ומיקומים ישנים עשויים לא להתקיים עוד ב-JSON.
הקליטו ניווט בחלונית Performance ובדקו את מפל Network. זהו מסמך, CSS, סקריפטים, גופנים ומשאב LCP. חפשו בקשות שמתגלות רק לאחר קובץ אחר ובדקו מי יזם אותן. CSS קטן דרך שרשרת @import עשוי להתחיל אחרי קובץ גדול יותר שמקושר ישירות ב-HTML.
שמרו צילום מסך או רצף תמונות לבסיס. ציור מוקדם עם ניווט שבור או תוכן לא מעוצב אינו בהכרח שיפור. בדקו את כל הדף: קוד שלא נדרש במסך הראשון יכול לשרת תוכן בהמשך.
אל תחברו הערכות חיסכון מתובנות שונות כאילו הן מדידות עצמאיות. הן יכולות לתאר אותה שרשרת. בדקו שינוי עקבי אחד ואז תזמון ותצוגה בפועל.
שמרו על CSS קריטי קטן וניתן לתחזוקה
CSS קריטי הוא העיצוב שנדרש לפריסה הראשונית הנראית. הטמעת קבוצה שנבחרה היטב יכולה לחסוך בקשה. הטמעת כל עיצוב האתר שונה: היא מגדילה כל תגובת HTML ומונעת שימוש חוזר בקובץ CSS עצמאי שמור.
המסך הראשון תלוי במכשיר, שפה, הסכמה ותוכן. חילוץ מצילום מחשב אחד עלול להחמיץ ניווט מובייל, כותרת מתורגמת ארוכה או הודעת שגיאה. התייחסו לחילוץ כתהליך בנייה עם תבניות מייצגות ובדיקות חזותיות.
הדוגמה משאירה פריסה חיונית במסמך וטוענת קובץ להדפסה באמצעות תנאי מדיה.
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Performance notes</title>
<style>
body { margin: 0; font-family: system-ui, sans-serif; line-height: 1.6; }
header, main { max-width: 70rem; margin-inline: auto; padding: 1rem; }
img { max-width: 100%; height: auto; }
</style>
<link rel="stylesheet" href="/styles/print.css" media="print">
</head>
<body>
<header>Performance notes</header>
<main><h1>A readable first render</h1><p>Essential content is available immediately.</p></main>
</body>
</html>תנאי שאינו מתאים למדיה הנוכחית מונע חסימת רינדור עבורה, אך הדפדפן עדיין יכול להוריד את הקובץ. אל תגדירו CSS למסך כ-media="print" ותשאירו כך, משום שהכללים יחולו בהקשר אחר. פתרונות שמשנים מדיה לאחר טעינה צריכים לטפל בכשל סקריפט, ב-CSP ובהצגה ללא עיצוב.
CSS מוטמע צריך להתאים למדיניות Content Security Policy באמצעות nonce או hash המיועדים לכך. אל תחלישו מדיניות קיימת כדי להעתיק דוגמה. הבנייה צריכה לסנכרן כללים קריטיים ומלאים, כדי שכללים ישנים לא ייצרו קפיצה בהמשך.
פצלו CSS לפי צורך אמיתי
בסיס משותף קטן וסגנונות לפי נתיב או רכיב מונעים ממאמר פשוט לטעון את כל עיצוב האפליקציה. טענו סגנון כשהרכיב בשימוש. קבצים זעירים רבים מוסיפים עומס תזמון ותחזוקה, ולכן בחרו גבולות לפי תפקוד משמעותי.
הסירו שרשראות @import מיותרות אם אתם שולטים בבנייה. קובץ שמתגלה בתוך קובץ אחר מוסיף תלות לבקשה. קישור ישיר ב-HTML או פתרון הייבוא בזמן בנייה מאפשרים גילוי ברור. זו בעיית שרשרת בקשות, לא טענה שכל כלל מיובא איטי.
בדקו CSS-in-JS בזמן ריצה. חלק מהיישומים צריכים להוריד ולהריץ JavaScript לפני הכנסת סגנונות. הדבר מעכב גילוי ועלול להוסיף חישוב סגנון. חילוץ בשרת או בבנייה יכול לשנות את הנתיב, בהתאם לספרייה, למסגרת ולגרסה.
בדקו תגובה שנוצרה ולא רק מקור רכיב. ייתכן שהמסגרת כבר מחלצת CSS, בעוד הגדרה אחרת מזריקה אותו בזמן ריצה. ודאו אם יש סגנונות שימושיים ב-HTML הראשוני לפני החלפת ספרייה.
בחרו async, defer ומודולים לפי תלות
סקריפט עצמאי יכול לסבול סדר שונה; קוד שתלוי ב-DOM או בספרייה לא בהכרח. הוספת async לכל הקבצים יכולה ליצור מצב מרוץ.
מצבי הטעינה המקובלים של קבצים חיצוניים שונים זה מזה.
| צורה | הורדה | הרצה וסדר |
|---|---|---|
| קלאסי ללא מאפיינים | יכולה לעצור פענוח | רץ לפני המשך הפענוח |
קלאסי עם defer |
במקביל לפענוח | לאחר הפענוח, בסדר המסמך, לפני DOMContentLoaded |
קלאסי עם async |
במקביל לפענוח | כשהוא מוכן, ללא הבטחת סדר מסמך |
type="module" ללא async |
מוריד גרף מודולים במקביל לפענוח | דחוי כברירת מחדל, עם תלויות בגרף |
שמרו על סדר קבצים קלאסיים תלויים באמצעות defer.
<script src="/scripts/vendor.js" defer></script>
<script src="/scripts/navigation.js" defer></script>לנקודת כניסה מודולרית הגדירו סוג ותארו תלויות באמצעות ייבוא.
<script type="module" src="/scripts/app.js"></script>לסקריפט עצמאי באמת אפשר להתאים async.
<script src="/scripts/independent-widget.js" async></script>אלה חלופות למשאבים שונים, ולא הנחיה לכלול שלוש גרסאות של אותה פונקציה. ל-defer אין השפעה שימושית על סקריפט קלאסי מוטמע. מודולים כבר דחויים, והוספת async משנה את מועד ריצת הגרף. בדקו את תיעוד script לפני שינוי דף ישן מעורב.
בדקו אחר כך תפריטים, חיפוש, אימות, תשלום והסכמה לפי הצורך, ועברו על שגיאות במסוף. סקריפט קלאסי מוטמע בהמשך יכול לפנות מוקדם מדי לספרייה עם defer. תקנו את התלות במקום להחליף מאפיינים עד שטעינה אחת מצליחה במקרה.
השתמשו ב-preload וב-preconnect לעיכוב מוגדר
Preload מודיע על משאב לדף הנוכחי לפני גילויו הרגיל. הוא אינו מחיל CSS, מריץ קוד או מציג תמונה בעצמו. הצרכן הרגיל עדיין דרוש, והבקשה המאוחרת צריכה להתאים.
הדוגמה מקדימה גופן ש-CSS ישתמש בו מיד.
<link rel="preload" href="/fonts/site-regular.woff2"
as="font" type="font/woff2" crossorigin>השתמשו ב-as ובמצב בקשה נכונים. רמז שגוי יכול ליצור הורדה כפולה או לא מנוצלת. אל תטענו הכול מראש: עדיפות למשאב מיותר יוצרת תחרות עם משאבים קריטיים.
Preconnect מטפל בהקמת חיבור, לא בגודל או בזמן הרצה. הוא עשוי לעזור למקור חיצוני חשוב שמתגלה מאוחר. הגבילו למקורות שנדרשים מוקדם ולמצב CORS המתאים. חיבור לאותו מקור שכבר שימש למסמך בדרך כלל אינו צריך רמז נוסף רק בגלל קבצים נוספים.
ל-modulepreload משמעות ייעודית להורדת מודולים ולהכנתם. השתמשו ברמזים שהמסגרת יוצרת ובדקו את הפלט. אל תחליפו אותם אוטומטית ב-preload רגיל בלי להבין גרף ומצב בקשה.
התייחסו ל-Coverage כרישום ולא כהוראת מחיקה
Coverage מציג חלקי CSS ו-JavaScript שנעשה בהם שימוש במהלך ההקלטה. התחילו בטעינה מחדש והפעילו תפריטים, חלונות, גלילה, לשוניות ופריסות רספונסיביות שמציגות רכיבים שונים.
קוד שלא שימש בהקלטה יכול להידרש בנתיב אחר, באינטראקציה מאוחרת, בשגיאה או בשפה אחרת. כללי מובייל נראים מיותרים בבדיקת מחשב בלבד. אל תמחקו כל אזור אדום מהקלטה אחת.
קשרו חבילות גדולות ולא מנוצלות למודולים, לתבניות או לתוספים המקוריים. הסירו תכונה שכבר אינה נחוצה, טענו תלות רק בנתיב שלה או הגדירו הסרת קוד שבאמת אינו נגיש בבנייה. אל תערכו חבילה שנוצרה ותידרס בבנייה הבאה.
בדקו שוב ורשמו אילו אינטראקציות נכללו. Coverage יעיל עם גרף תלויות ובדיקות חזותיות ותפקודיות. הוא אינו מוכיח שאפליקציה דינמית לעולם לא צריכה פונקציה מסוימת.
בדקו יחד המרות של מערכת התוכן
ערכת עיצוב, מטמון ותוספים יכולים כולם לאחד סגנונות, לדחות סקריפטים ולשכתב רמזים. ה-HTML הסופי עלול להיות שונה מאוד ממסך ההגדרות. בדקו תגובה ויוזמי בקשות.
אל תפעילו את כל אפשרויות הדחייה יחד. שמרו בסיס מובן, שנו שכבה אחת ובדקו מסלולים חיוניים. סקריפטים מסוימים חייבים להקדים אתחול מוטמע, וסגנונות יכולים לשרת באנר או תפריט מובייל שאינם בבדיקת מחשב בסיסית.
בטלו מטמון רלוונטי לאחר שינוי תבנית ובדקו תשובות חדשות ושמורות. חוסר עקביות יכול להיות שתי גרסאות דף, ולא תעלומת תזמון בדפדפן. שמרו אפשרות לחזור להגדרה הקודמת.
ודאו שתצוגה נכונה מגיעה מוקדם יותר
חזרו על אותו ניווט בתנאים עקביים והשוו תוכן שימושי ראשון, LCP, תזוזות ועבודת תהליכון ראשי. בדקו דף מלא ואינטראקציות חשובות. צמצום בקשות חוסמות הוא ראיה שימושית כשהמראה והתפקוד נשארים תקינים.
כללו מסך צר, כותרת מתורגמת ארוכה ומטמון ריק. אם גילוי גופנים מעכב טקסט, המשיכו לאופטימיזציה של גופני רשת. תעדו תלויות ברשימת בדיקת הביצועים והשתמשו במדריכי מהירות הדף לצוואר הבקבוק הבא. שמרו שינויים שהתועלת שלהם נשמרת בבדיקה חוזרת.