ישנן דרכים רבות לשפר את מהירות הטעינה של אתרים. אחת מהדרכים היא לטעון מראש קבצים מסוימים שאתם יודעים כי יידרשו מאוחר יותר והם חשובים לרינדור מהיר של אותו עמוד.
הערך preload של התכונה rel באלמנט <link> מאפשר לכם להכריז ב HTML head כי יש צורך על נכסים מסוימים להטען מוקדם ככל הניתן במהלך חייו של עמוד.
preload מאפשר ליזום בקשה לקובץ מסוים ולשמור אותו בזכרון עוד לפני הצורך הממשי בקובץ. פעולה זו מבטיחה כי הקובץ יהיה נגיש מוקדם ככל הניתן ומצמצמת את הסבירות שיעכב את רינדור העמוד.
טעינה של נכסים בעמוד בצורה הנכונה היא אספקט חשוב ועליכם לבצעה נכון בכדי להשיג תוצאה טובה בCore Web Vitals, ובמיוחד בנתון Largest Contentful Paint (LCP).
בעולם האמיתי, אתרים טוענים מספר קבצי CSS, פונטים, Javascript ותמונות; ונכסים אלו חוסמים טעינה כברירת מחדל, סיטואציה המשפיעה על זמן הטעינה של האתר או ההאפליקציה.
אז בפוסט זה אנו נתמקד ב <link rel="preload"> – אפשרות אחת מפיצ׳ר מבוסס הנקרא Resource Hints, הנתמך כיום על ידי כל הדפדפנים המודרניים.
קיים גם מאמר על השימוש ב preconnect עבור Google Fonts שמתאים למצבים מסוים, אך במקרה של פונטים השימוש ב preload עליו אנו מדברים בפוסט זה הוא בדרך התשובה.
על התכונה "rel="preload בהרחבה
השימוש ב preload מתבצע בצורה הבאה:
<link rel="preload" href="style.css" as="style">
<link rel="preload" href="main.js" as="script">- את הנתיב לנכס (resource) ניתן לציין בתכונה
href. - את סוג הנכס ניתן לציין באמצעות התכונה
as.
אילו סוגי תוכן ניתן לטעון מראש באמצעות preload?
ניתן להשתמש ב preload עבור מספר סוגים או פורמטים של קבצים הכוללים בין היתר קבצי CSS, Javascript, פונטים, תמונות ועוד. הנה רשימה חלקית של סוגי הקבצים הנתמכים:
- אודיו (audio) – קובץ אודיו בו משתמשים עם התגית <audio>.
- מסמך (document) – מסמך HTML שנועד להיות מוטמע באמצעות <frame> או <iframe>.
- הטמעה (embed) – נכס המוטמע באמצעות האלמנט <embed>.
- פונט (font) – קובץ פונט.
- תמונה (image) – קובץ תמונה.
- סקריפט (script) – קובץ Javascript.
- קובץ עיצוב (css) – קבצי CSS Stylesheets.
קיימים עוד סוגי תוכן שלא ציינו ברשימה זו, תנו מבט ב MDN web docs אם מעניין אתכם.
הכרזת MIME type
האלמנט <link> יכול לקבל את התכונה type בה ניתן לרשום את ה MIME type של הנכס אליו האלמנט מצביע.
הכרזת MIME type שימושית במיוחד כאשר מבצעים preloading לנכסים מפני שהיא תגרום לדפדפן לבדוק האם הוא כלל תומך בסוג הקובץ המופיע ב type ויוריד זה רק במידה והוא אכן תומך בו.
<link rel="preload" href="movie.mp4" as="video" type="video/mp4">לא נרחיב מעבר לכך על MIME types, מוזמנים לתת מבט באותם MDN docs שהזכרנו קודם לכן.
שימוש ב media queries
כפי שאתם יודעים, ניתן להשתמש ב media queries באלמנט <link>, ומכאן שניתן לבצע preloading על בסיס ה viewport של המשתמש.
נאמר וקיימת תמונה חשובה בחלקו העליון הקריטי של העמוד אותה אתם מעוניינים לטעון מראש. בהרבה מצבים תרצו להציג במובייל תמונה שונה למשתמש מהתמונה בדסקטופ, בין אם ברמה העיצובית או בין אם לטובת טעינת תמונה בעלת משקל קטן יותר עבור משתמשי מובייל.
בשני המקרים תרצו לטעון תמונה זו מראש באמצעות preload וזאת בכדי לוודא שאתם מציגים את התוכן העיקרי כמה שיותר מהר.
<link rel="preload" href="mobile-img.jpg" as="image" media="(max-width: 600px)">
<link rel="preload" href="desktop-img.jpg" as="image" media="(min-width: 601px)">מספר מילים על Cross-origin
במידה ו CORS מוגדר בשרת שלכם כראוי, תוכלו לבצע preloading לנכסים ממקור אחר (דומיין אחר) כל עוד אתם מוסיפים את התכונה crossorigin לאלמנט <link>.
מסיבות שונות, פונטים הם יוצאים מן הכלל ועבורם עליכם לספק את התכונה crossorigin גם אם אותם פונטים נמצאים בשרת שלכם.
<link crossorigin rel="preload" href="fonts/assistant.woff2" as="font" type="font/woff2">מתי עלינו להשתמש ב preload?
preload מציין לדפדפן להוריד ולשמור בזיכרון נכס מסוים כמה שיותר מהר. הוא עוזר במקרה בו אתם יודעים שאתם צריכים נכס כלשהו ישר לאחר טעינת העמוד ואתם מעוניינים להתחיל לטעון זה מוקדם יותר.
חשוב להבין כי הדפדפן לא מבצע שום פעולה עם אותו נכס לאחר שהוריד אותו. הוא אינו מריץ סקריפטים והוא לא מיישם CSS.
הדבר היחיד ש <link rel="preload"> מבצע הוא לשמור את הנכס בזכרון, כך שברגע שמישהו דורש אותו – הוא יהיה זמין מיידית. בואו ניתן שתי דוגמאות פשוטות:
דוגמה א׳
למשל, במקרה בו אתם טוענים פונט רשת כלשהו ע״י font-face@ וה CSS של פונט זה נמצא בקובץ חיצוני. אז לצורך הדוגמה נניח וזה קובץ ה HTML שלנו:
<link rel="stylesheet" href="index.css" />ונניח שזה קובץ ה CSS:
@font-face {
src: url('assistant.woff2') format('woff2');
}כברירת מחדל, assistant.woff2 יתחיל לרדת רק בנקודה בה index.css ייטען ויתממש.
במקום להמתין לנקודה זו ניתן באמצעות preload ליזום את הבקשה מוקדם יותר. מכיוון והוא יהיה נגיש מהר יותר לטובת רינדור העמוד, הגולשים יסבלו פחות מתופעת ה FOUT עליה דיברנו בפוסט על התכונה font-display.
זה המקום לומר שרצוי ואפילו מומלץ להשתמש ב preload וגם יחד עם התכונה font-display בכדי לבצע אופטימיזציה לטעינת פונטים.
דוגמה ב׳
דוגמה נוספת היא מצב בו אתם מחלקים את קבצי העיצוב שלכם לטובת הצגה מהירה יותר של החלק העליון הקריטי של העמוד (Critical Path). קובץ אחד לחלקו הקריטי של העמוד וקובץ שני לשאר העמוד:
<style>
/* Inlined critical styles */
</style>
<link rel="preload" href="/non-critical.css" as="style" />
<script>
/* Non-critical styles */
loadCSS('/non-critical.css');
</script>במצב זה, קובץ העיצוב שאינו קריטי יתחיל לרדת רק כאשר ה Javascript ירוץ, מה שיכול להתרחש בשלב די מאוחר לאחר הרינדור הראשוני. במקום להמתין ניתן ליזום טעינה של זה מראש ולחסוך זמן יקר.
אז מהם בעצם נכסים החוסמים טעינה?
לפני שנמשיך, בואו נסביר מה הכוונה בנכסים שחוסמים טעינה (Render-Blocking Resources).
כאשר בקשה לנכס מסוים חוסמת טעינה, זה אומר בגדול כי ה event בשם window.onload לא יופעל (triggered) עד שהבקשה תסתיים והנכס יירד במלואו.
אפליקציות דף יחיד מודרניות (SPA) למשל, מסתמכות במרביתן על event זה בכדי להתחיל לפעול.
זה אומר שחלקים מממשק המשתמש לא ירונדרו עד שאותן בקשות החוסמות טעינה יסיימו להטען.
תנו מבט בקוד הבא:
<html>
<head>
<link
rel="stylesheet"
href='https://fonts.googleapis.com/css?family=Roboto:400,600|Material+Icons'>
<style>
html {
font-family: Roboto;
}
</style>
</head>
<body>
Hello
<script>
window.onload = function () {
console.log('Loaded');
}
</script>
</body>
</html>אם אטען קובץ HTML זה בדפדפן ואתן מבט בלשונית Network ב Chrome Dev Tools, אראה כי הטקסט Loaded נרשם בקונסול בדיוק לאחר שקובץ ה CSS נטען כפי שהתמונה הבאה ממחישה:

בכדי להבחין בתוצאה שיניתי את מהירות החיבור (throttling) ל Slow 3G.
בואו נשנה את תגית ה link בכדי ליזום את הבקשה מוקדם יותר:
<link
rel="preload"
as="style"
href='https://fonts.googleapis.com/css?family=Roboto:100,900|Material+Icons'>כעת, אם ננקה את הקאש ונרענן את העמוד, נגלה כי הטקסט Loaded מוצג בדיוק לפני שהבקשה ל CSS החלה:

רגע, שמתם לב במקרה שקפצה לה הערה כתומה בקונסול? ההערה באה להזהיר אותנו כי ביצענו preloading לנכס אך לא השתמשנו בו בפועל.
כפי שהסברנו, הדבר היחיד ש preload מבצע הוא שמירת הנכס בזכרון אך הוא אינו מיישם אותו בפועל. כלומר ההחלטה מתי להשתמש בנכס זה נתונה לבחירתכם במקרה ספציפי זה.
מממ… אז כיצד מיישמים את ה CSS?
במקרה של דוגמה זו, נרצה ליישם את קובץ ה CSS כמה שיותר מהר מרגע שזה נטען וזאת בכדי להציג את הטקסט מיידית עם אותו פונט רשת. בכדי לבצע זאת ניתן לשנות את הקוד כך:
<link
rel="preload"
as="style"
onload="this.rel = 'stylesheet'"
href='https://fonts.googleapis.com/css?family=Roboto:100,900|Material+Icons'>על ידי קביעת התכונה rel ל stylesheet אנו מציינים לדפדפן כי עליו להשתמש בנכס זה.
מכיוון וזה כבר שמור בזכרון מפאת השימוש ב preload, הדפדפן אינו מוריד נכס זה שוב ומיישם אותו מיידית.
מאחר ופתרון זה מסתמך על Javascript, נכון יהיה להוסיף את התגית <noscript> כעתודה למקרה בו Javascript מבוטל:
<link
rel="preload"
as="style"
onload="this.rel = 'stylesheet'"
href='https://fonts.googleapis.com/css?family=Roboto:100,900|Material+Icons'>
<noscript>
<link
rel="stylesheet"
href='https://fonts.googleapis.com/css?family=Roboto:100,900|Material+Icons'>
</noscript>זוהי הגישה המודרנית והנכונה לטעינת CSS ויישומו מיידית באמצעות preload. למידע נוסף על טעינת CSS ו-JavaScript בוורדפרס, עיינו במדריך הייעודי.
ומה לגבי טעינה מראש של Javascript
היישום של JavaScript מתבצע אחרת. נכסים הנטענים באמצעות preload נשמרים לוקאלית בדפדפן והם לא בשימוש עד לרגע בו נדרשים, כלומר עד לרגע בו ה DOM מצביע אליהם.
הדוגמה הבאה נלקחה ממאמר בגוגל ומראה שיישום JavaScript שנטען מראש מתבצע בצורה קצת שונה. עבור סקריפטים שאינם קריטיים, שקלו טעינת עצלה של JavaScript במקום.
בכדי ליישם סקריפט שנטען מראש, עליכם לקבוע את התכונה src של הקובץ ולהוסיפו ל-DOM:
<link rel="preload" href="used-later.js" as="script">
<!-- ... -->
<script>
var usedLaterScript = document.createElement('script');
usedLaterScript.src = 'used-later.js';
document.body.appendChild(usedLaterScript)
</script>התכונה fetchpriority
בנוסף ל preload, דפדפנים מודרניים תומכים בתכונה fetchpriority (הידועה גם כ Fetch Priority API). תכונה זו מעניקה לכם שליטה ישירה על עדיפות הטעינה של נכסים:
<img src="hero-image.jpg" fetchpriority="high" alt="Hero Image">
<img src="below-fold.jpg" fetchpriority="low" alt="Below the fold">
<link rel="preload" href="critical-font.woff2" as="font" fetchpriority="high" crossorigin>התכונה fetchpriority מקבלת שלושה ערכים:
- high – טעינת הנכס בעדיפות גבוהה יחסית לנכסים אחרים מאותו סוג.
- low – טעינת הנכס בעדיפות נמוכה יחסית לנכסים אחרים מאותו סוג.
- auto – ברירת המחדל. הדפדפן יחליט על העדיפות.
השתמשו ב fetchpriority="high" על תמונת ה LCP שלכם לשיפור ה Largest Contentful Paint. Google Flights שיפרו את ה LCP שלהם מ-2.6 שניות ל-1.9 שניות באמצעות טכניקה זו. שלבו זאת עם preload לתוצאות הטובות ביותר.
preload מול preconnect מול prefetch
חשוב להבין את ההבדלים בין שלושת ה resource hints הללו:
- preload – מוריד נכס הנדרש בעמוד הנוכחי. השתמשו עבור פונטים, CSS קריטי, תמונות בחלק העליון של העמוד וסקריפטים מרכזיים.
- preconnect – יוצר חיבור לשרת חיצוני (DNS + TCP + TLS) מבלי להוריד דבר. השתמשו עבור דומיינים חיצוניים שאתם יודעים שתצטרכו, כמו CDN או ספקי פונטים.
- prefetch – מוריד נכס שסביר שיידרש בניווט לעמוד עתידי. השתמשו עבור נכסים הנדרשים בעמוד הבא שהמשתמש צפוי לבקר בו.
שאלות נפוצות
שאלות נפוצות בנושא טעינת נכסים מראש:
לסיכום
טעינה מראש של נכסים קריטיים מספקת לכם יותר שליטה על כיצד נכסים נטענים ויכולה לשפר משמעותית את ה-Core Web Vitals של האתר, ובמיוחד את ה-Largest Contentful Paint (LCP).
השתמשו ב preload עבור נכסים קריטיים לרינדור הראשוני שהדפדפן מגלה מאוחר, כגון פונטים הנטענים דרך CSS, תמונות hero וסקריפטים מרכזיים. שלבו זאת עם התכונה fetchpriority לשליטה עדינה עוד יותר על עדיפות הטעינה.
שימו לב שאינכם משתמשים ב preload בהגזמה. אם תטענו מראש את כל הנכסים, האתר שלכם עלול דווקא להאט מכיוון שתמנעו מהדפדפן לתזמן את טעינת הנכסים בחוכמה.
אל תתבלבלו בין preload ל prefetch. השתמשו ב preload רק עבור נכסים הנדרשים מיידית לאחר טעינת העמוד.
עבור נכסים הנדרשים בעמודים עתידיים, השתמשו ב prefetch במקום.


שלום רב,
בתוצאת הבדיקה של גוגל פייג Page Speed הודעה שאני צריך לעשות link rel=preload לכתובת הבאה:
https://bshcpa.co.il/wp-content/themes/oceanwp/assets/fonts/simple-line-icons/Simple-Line-Icons.woff2?v=2.4.0.
לא ברור איזה קוד נדרש ובאיזה קובץ בתבנית אני אמור לשתול אותו. אשמח להכוונה.
תודה
היי אמנון,
הוסף את הקוד הבא לקובץ functions.php של התבנית שלך:
מה אני אמור להטמיע והיכן? בעיה אחרת Preload key requests מה מטמיעים והיכן?
תודה רועי,
הוספתי את הקוד לתבנית וניקיתי קאש ואין שינוי עדיין מקבל את ההודעה שנדרש rel=preload.
כעת גם התווספה אזהרה:
אזהרות: מערכת Lighthouse לא הצליחה לבדוק באופן אוטומטי את ערך תצוגת הגופן של כתובת ה-URL הבאה: https://bshcpa.co.il/wp-content/themes/oceanwp/assets/fonts/simple-line-icons/Simple-Line-Icons.woff2.
כנס לקובץ https://bshcpa.co.il/wp-content/themes/oceanwp/assets/css/third/simple-line-icons.min.css והחלף את השורות הבאות:
באלו:
היי,
איך אני מגיע לקובץ ששלחת בקישור לצורך העריכה שלו? האם השורות נמצאות גם בקובץ functions.php? אם כן, אני לא מוצא את השורות..
כנס באמצעות FTP לספרייה שציינתי וערוך את הקובץ. אם אין זה ברור לך אני מאד ממליץ לך להעזר במתכנת.
היי,
בוצע! נכנסתי לספרייה והוספתי לקובץ רק את השורה font-display: swap (כי זו השורה שמבדילה בין המצב לפני לאחרי). התוצאה היא שזה צמצם את הזמן, אבל עדיין נותרה ההערה לאחר בדיקת המהירות ב- PS שיש לטעון מראש.
1. השאלה – האם בעקבות הפעולות שהמלצת, ההערה אמורה להיעלם לגמרי או רק לצמצם את זמן הטעינה?
2. האם נדרש לבצע את שתי הפעולות שהמלצת במקביל: גם את הקוד בקובץ functions.php ובנוסף את השינוי בקובץ שעתה השלמתי.
ביצעתי את השינויים על דומיין משוכפל למקרה ותרצה לבדוק
https://stage.bshcpa.co.il/
כן, עלייך לבצע את שתי הפעולות. איני יכול לעזור לך מעבר לכך לצערי…. בהצלחה!
עזרת מעל ומעבר. תודה רבה!
wow רועי, קראתי את ההתכתבות כאן. אתה ממש נדיב. לדעתי, זה דווקא משרת אותך. לפחות, בעיניי.
מאמר מעולה וכל הכבוד על העזרה לאחרים פה 🙂
תודה שי, חזור לבקר 🙂
אם אני רוצה להשתמש באפשרות של preload לפונטים, צריך לערוך ידנית את הקוד או שיש אפשרות למשהו אוטומטי? אני משתמש ב-litespeed.
זה מה שהכלי של גוגל טוען שצריך לשפר
lightspeed לא מאפשר preload של פונטים, יש לעשות זאת ידנית…
תודה, אני צריך להשתמש בדוגמה שכתבת בתגובה הראשונה ולהתאים את הקוד לכל קובץ שהכלי של גוגל טען שצריך לשפר? אפשר להכניס כמה שרוצים בתוך הפונקציה? זה יחליף את מה שקיים כרגע?
כן, כן ולא…
תודה, איך מחליפים את מה שקיים עכשיו?