עודכן: 07 בספטמבר 2026
Early Hints (HTTP 103) הוא קוד סטטוס מקדים ש-Chrome, Edge, Firefox ו-Safari 18 יודעים לצרוך. השרת מחזיר 103 Early Hints עם כותרות Link: rel=preload ו-rel=preconnect עוד לפני שה-200 OK מוכן, והדפדפן מתחיל לפתוח חיבורי TLS ולמשוך נכסים קריטיים תוך כדי שהמקור עדיין מרנדר את ה-HTML. בקצה, זה מוריד בדרך כלל 100–400ms מ-LCP באתרים שה-TTFB שלהם עולה על 300ms, וזה מה שאני רואה שוב ושוב ב-CrUX וב-RUM של לקוחות. אז בואו נצלול פנימה, אני אראה לכם איך להפעיל את זה בפועל.
מה זה בעצם Early Hints (HTTP 103)?
Early Hints הוא קוד סטטוס אינפורמטיבי (1xx) ש-RFC 8297 הגדיר עוד ב-2017, אבל רק ב-2022 הוא באמת התחיל לפעול בפרודקשן. הרעיון פשוט: כשהדפדפן שולח בקשה ל-HTML, המקור לרוב צריך לחכות לבסיס נתונים, ל-API חיצוני או ל-render של framework לפני שהוא יכול להתחיל לשלוח את התגובה הסופית. בזמן ההמתנה הזאת (במדידות שלי היא בין 120ms ל-800ms אצל אתרים ישראליים) הדפדפן פשוט יושב בטל. Early Hints ממלא את החלל: השרת שולח HTTP/1.1 103 Early Hints עם כותרות Link כמעט מיד, וההסכם עם הדפדפן הוא "תתחיל למשוך את הדברים האלה, אני מבטיח שהתגובה האמיתית מגיעה בקרוב".
בניגוד ל-preload שיושב בתוך ה-HTML, ה-hint מגיע לפני שגם בייט אחד של HTML הגיע לדפדפן. זה יוצר חלון של מאות אלפיות שנייה שבו TLS handshakes ל-CDN שלישי, פענוח DNS, ומשיכת LCP image כבר קורים במקביל למחשוב בשרת. עבור אתרים עם TTFB איטי (למשל Next.js SSR עם fetch ל-CMS), זה בדרך כלל ההבדל בין LCP של 3.4s ל-2.6s ב-p75.
HTTP/1.1 103 Early Hints
Link: </hero.avif>; rel=preload; as=image; fetchpriority=high
Link: </fonts/inter-var.woff2>; rel=preload; as=font; type=font/woff2; crossorigin
HTTP/1.1 200 OK
Content-Type: text/html; charset=utf-8
Cache-Control: public, max-age=60
Link: </hero.avif>; rel=preload; as=image; fetchpriority=high
<!doctype html>
<html>...שימו לב שאני מחזיר את אותן כותרות Link גם ב-200 OK. זה חשוב מסיבה שאסביר בהמשך: אם ה-hint לא הגיע (למשל ה-CDN לא תומך, או מפעיל סלולרי חתך את ה-Informational response), הדפדפן עדיין יבצע את ה-preload מהתגובה הרגילה. זו רשת ביטחון הכרחית.
איך Early Hints משפרים את LCP ואת TTFB?
קודם כל צריך להבין ש-Early Hints לא משפרים את ה-TTFB של הבקשה הראשית. ה-TTFB, בהגדרה של web.dev, נמדד עד ה-200 OK, לא עד ה-103. אבל הם משפרים את ה-Perceived TTFB ואת ה-Resource Load Delay של המשאב שקובע את LCP. בפרויקט האחרון שהרצתי על Next.js 16 עם origin באיוואי ומשתמשים בישראל, הנתונים היו:
- ללא Early Hints: TTFB p75 = 480ms, LCP p75 = 3.2s, Resource Load Delay של תמונת ה-hero = 620ms.
- עם Early Hints מפעילים מ-Cloudflare: TTFB p75 = 490ms (זהה כמעט), LCP p75 = 2.55s, Resource Load Delay = 180ms.
המנגנון: ברגע שה-CDN מקבל את הבקשה ומזהה שיש cache miss, הוא שולח ל-Origin בקשה, אבל במקביל שולח ללקוח את ה-103 עם ה-Link headers ששמור לו ב-cache מהתגובה הקודמת. הדפדפן שלכם מתחיל לפתוח TLS ל-fonts.googleapis.com, מתחיל להוריד את ה-hero AVIF מה-image CDN, ומחפש את הפונט הראשי. הכול תוך כדי שה-Origin עדיין מרנדר. כשה-HTML סוף סוף מגיע, המשאבים כבר בזיכרון או במעבר. ה-מדריך Core Web Vitals ל-2026 שלנו מפרט את חלוקת הזמנים הזאת של LCP (TTFB + Resource Load Delay + Resource Load Duration + Element Render Delay), וזה בדיוק ה-Load Delay שנפגע כאן. אה, וכדאי גם לקרוא את אופטימיזציית TTFB, CDN ו-Caching ב-2026, כי בלי TTFB סביר, Early Hints לא באמת יעזור.
תמיכת דפדפנים ב-2026
סטטוס התמיכה נכון לספטמבר 2026:
- Chrome / Edge: תמיכה מלאה מאז Chrome 103 (יוני 2022) לניווטים ראשיים. תמיכה ב-cross-origin preconnect ו-preload פעילה כברירת מחדל.
- Firefox: תמיכה משיצא Firefox 120 (נובמבר 2023). ב-Firefox 128+ יש גם תמיכה ב-
Priorityhint בתוך ה-Link header. - Safari: תמיכה סופית הגיעה ב-Safari 18 (ספטמבר 2024) על macOS Sequoia ו-iOS 18. זה שינה את המשוואה, כי לפני זה כ-30% מהתעבורה שלי לא נהנתה מזה בכלל. כיום, בכל אתר ישראלי שאני מנטרת, מעל 92% מהמכשירים תומכים.
- WebKit ב-iOS 17 ומטה: מתעלם מ-
103באדיבות. לא נזק, פשוט לא רווח.
חשוב לזכור: Early Hints נשלחים רק על ניווט ראשי (top-level navigation). הם לא רלוונטיים ל-XHR/fetch או ל-iframes.
איך להפעיל Early Hints ב-Nginx?
Nginx לא תומך ב-Early Hints באופן מקורי גם ב-2026. יש שלוש דרכים לעקוף את זה, בסדר יורד של פשטות:
1. שימוש ב-OpenResty עם Lua
אם אתם כבר על OpenResty, אפשר לשלוח את ה-103 ידנית מ-rewrite_by_lua. הבעיה: זה דורש שה-Origin שלכם ישלח את ה-Link headers גם בתגובה הראשית, ואתם צריכים לזכור לא לחסום את ה-processing:
server {
listen 443 ssl http2;
server_name example.com;
location / {
rewrite_by_lua_block {
-- Send Early Hints before upstream call
ngx.status = 103
ngx.header["Link"] = {
"</assets/hero.avif>; rel=preload; as=image; fetchpriority=high",
"</fonts/inter-var.woff2>; rel=preload; as=font; type=font/woff2; crossorigin"
}
ngx.send_headers()
ngx.flush(true)
}
proxy_pass http://origin_upstream;
}
}2. פרוקסי דרך CDN שתומך (מומלץ)
הפתרון שאני מיישמת אצל כל לקוח: להשאיר את Nginx כ-Origin ולעטוף אותו עם Cloudflare או Fastly. ה-CDN שולח את ה-Early Hints, ו-Nginx רק צריך לחזור עם Link headers רגילים ב-200 OK. פחות סיכון, יותר תחזוקתי.
3. Nginx Unit או Nginx Plus
Nginx Plus מגרסה R32 (2024) תומך ב-ngx_http_early_hints_module. הוא מאפשר להגדיר hints סטטיים לפי location:
location / {
early_hints on;
add_early_hint Link "</hero.avif>; rel=preload; as=image";
add_early_hint Link "</critical.css>; rel=preload; as=style";
proxy_pass http://backend;
}איך להפעיל Early Hints ב-Cloudflare?
ל-Cloudflare יש את המימוש הבוגר ביותר של Early Hints וזאת גם הדרך שאני ממליצה עליה לרוב האתרים הישראליים. הם משתמשים במטמון פנימי של ה-Link headers שראו בתגובות קודמות, כך שאפילו על cache miss הם יכולים לשלוח 103 באופן ספקולטיבי.
ההפעלה היא ב-3 שלבים:
- בדשבורד: Speed → Optimization → Early Hints, הפעילו את המתג.
- ודאו שה-Origin שלכם שולח
Linkheaders ב-200 OK. בלי זה, אין ל-Cloudflare מה לשמור ולשלוח כ-hint. דוגמה מ-Node/Express:
app.get('/*', (req, res, next) => {
res.set('Link', [
'</hero.avif>; rel=preload; as=image; fetchpriority=high',
'</fonts/inter-var.woff2>; rel=preload; as=font; type=font/woff2; crossorigin'
].join(', '));
next();
});כדי לוודא שזה עובד, הריצו מ-CLI:
curl -sIv --http2 https://example.com/ 2>&1 | grep -E "HTTP/|link:"
# Expected:
# < HTTP/2 103
# < link: </hero.avif>; rel=preload; as=image
# < HTTP/2 200
# < link: </hero.avif>; rel=preload; as=imageאם אתם רואים רק את ה-200, בדקו שאתם על תוכנית Pro ומעלה, ושה-Origin באמת מחזיר את ה-Link header. מסמכי Cloudflare Early Hints מסבירים גם איך לנקות את ה-cache של ה-hints כשמעדכנים משאבים.
Early Hints ב-Vercel ו-Next.js
Vercel הפעיל תמיכה מובנית ב-Early Hints על Edge Network ב-2023, ומאז שגם ה-Next.js 16 Cache Components ו-PPR יצאו, זה הפך לחלק אינטגרלי מזרימת הרינדור ההיברידי. עבור דפים עם generateStaticParams או PPR, Vercel שולח את ה-hints ישירות מהקצה, בלי אפילו לגעת ב-Origin שלכם.
עבור דפים דינמיים (SSR מלא), אתם צריכים לפלוט Link headers מ-middleware.ts או מ-next.config.js:
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
const response = NextResponse.next();
// Only add hints to top-level document navigations
const accept = request.headers.get('accept') ?? '';
if (accept.includes('text/html')) {
response.headers.append(
'Link',
'</hero.avif>; rel=preload; as=image; fetchpriority=high'
);
response.headers.append(
'Link',
'</fonts/inter-var.woff2>; rel=preload; as=font; type=font/woff2; crossorigin'
);
}
return response;
}
export const config = {
matcher: [
// Only home and product pages need Early Hints for LCP
'/',
'/products/:path*',
],
};עבור Netlify, ההגדרה זהה למעשה: צריך רק להוסיף את ה-Link headers ב-_headers או דרך Edge Function, ו-Netlify Edge יוציא 103 אוטומטית כשמזוהה שהיעד תומך.
Early Hints ב-Fastly VCL
ל-Fastly יש שליטה עמוקה יותר אבל דורש VCL מותאם. הנה דוגמה מתוך production של אתר eCommerce ישראלי שאני מלווה:
sub vcl_recv {
if (req.http.Accept ~ "text/html" && req.method == "GET") {
// Send Early Hints for known LCP resources
h2.early_hints("link: </static/hero-v3.avif>; rel=preload; as=image; fetchpriority=high");
h2.early_hints("link: </static/fonts/heebo-var.woff2>; rel=preload; as=font; type=font/woff2; crossorigin");
}
}ההבדל הקריטי: Fastly שולח את ה-103 לפני שהוא בכלל פונה ל-Origin. זה חיסכון של ה-full round-trip. במקרה שלי, זה קיצץ את ה-LCP p75 ב-320ms בממוצע על מובייל 4G. בכנות, זו הייתה ההפתעה הגדולה שלי בפרויקט ההוא.
Early Hints מול Preload ו-Fetch Priority — מה משתמשים במה?
זו השאלה הכי נפוצה שאני מקבלת. שלוש הטכניקות פותרות בעיות דומות אבל שונות במהותן. הטבלה הבאה מסכמת את הבחירה:
| מאפיין | Early Hints (103) | <link rel="preload"> | fetchpriority="high" |
|---|---|---|---|
| מתי נשלח | לפני ה-HTML כולו | אחרי parsing של <head> | אחרי גילוי המשאב |
| משפר Load Delay | כן, משמעותית | חלקית | כמעט לא |
| דורש שינוי HTML | לא | כן | כן (על <img>) |
| דורש תמיכת CDN | כן | לא | לא |
| עובד על משאבים דינמיים | מוגבל (רק hint סטטי) | כן | כן |
| סיכון להוריד את המשאב הלא נכון | גבוה יחסית | בינוני | נמוך |
| מקרה שימוש עיקרי | hero image, hero font | קבצי CSS, JS קריטיים | קביעת סדר בין תחרים |
בפועל, הן משלימות: אני משתמשת ב-Early Hints כדי שהדפדפן יתחיל לפתוח TLS ולמשוך את ה-LCP image, ב-<link rel="preload"> כגיבוי בתוך ה-HTML, וב-fetchpriority="high" על ה-<img> עצמו כדי לוודא שהדפדפן מבין שזה המשאב החשוב ביותר. פירוט מלא של הטכניקות המשלימות ב-מדריך Resource Hints ו-Fetch Priority.
מלכודות נפוצות שאסור להתעלם מהן
1. שליחת יותר מדי hints
ראיתי אתרים שדוחפים 15 hints שונים. זה גורם לדפדפן לפתוח 8–10 חיבורי TLS במקביל, מה שמציף את מנוע ה-network של ה-user agent ופוגע ב-INP על מכשירים חלשים. ההגבלה שלי: מקסימום 4 hints, ותמיד הכי קריטיים (hero image, hero font, לפעמים critical CSS chunk).
2. שכחת ה-crossorigin על פונטים
Preload של פונט ללא crossorigin פשוט לא נספר, והדפדפן ימשוך את הפונט פעמיים. תמיד להוסיף crossorigin על as=font. נכוויתי מזה בפרויקט של לקוח וזה הכפיל את משקל הפונטים למשך שבועיים לפני שתפסנו.
3. שליחת hints ל-URLs עם hash שמשתנה בכל build
אם ה-hero image שלכם הוא /assets/hero.abc123.avif וה-hash משתנה בכל deploy, ה-hint שנשמר ב-CDN יצביע על קובץ ישן שכבר לא קיים. פתרון: hero image רץ עם שם קבוע (/assets/hero.avif) עם Cache-Control: max-age=60, s-maxage=31536000, stale-while-revalidate=86400.
4. Early Hints לא נשלח על 404 או 500
אם ה-Origin שלכם נופל, ה-CDN לא ישלח 103, וזה בסדר. אבל אם אתם משתמשים ב-fallback מותאם, ודאו שהוא לא מונע את ה-hint לכל התעבורה בגלל שגיאה של רבע אחוז.
5. חסימה ע"י Proxy או Middleware של הארגון
Corporate proxies ישנים (בעיקר של גופים ממשלתיים ובנקים) חותכים תגובות 1xx. אם אתם רואים ב-CrUX תעבורה שמגיעה עם TTFB גבוה במיוחד ו-LCP חלש, זה לפעמים ההסבר. הפתרון היחיד: ודאו שיש לכם <link rel="preload"> ב-HTML כרשת ביטחון.
איך למדוד את ההשפעה ב-RUM?
זה החלק שאני הכי אוהבת, כי כאן רואים את האמת. Lighthouse סינתטי לא יראה לכם כמעט שום שיפור מ-Early Hints. הוא רץ ב-DevTools עם חיבור מדומה שאין לו את ה-latency האמיתי של ה-Origin שלכם ליוזרים בעולם. ההוכחה חייבת להיות ב-RUM ו-CrUX.
עם ספריית web-vitals v4, אני מוסיפה attribution ל-LCP כדי לפצל את הזמן ולראות איפה החיסכון קרה:
import { onLCP } from 'web-vitals/attribution';
onLCP((metric) => {
const attr = metric.attribution;
// These four sum up to LCP
const ttfb = attr.timeToFirstByte;
const loadDelay = attr.resourceLoadDelay;
const loadDuration = attr.resourceLoadDuration;
const renderDelay = attr.elementRenderDelay;
navigator.sendBeacon('/rum', JSON.stringify({
lcp: metric.value,
ttfb, loadDelay, loadDuration, renderDelay,
hasEarlyHints: performance.getEntriesByType('navigation')[0]
?.responseStart < performance.getEntriesByType('resource')
.find(r => r.name.includes('hero'))?.startTime,
url: location.pathname,
connection: navigator.connection?.effectiveType,
}));
});המדד לעקוב אחריו הוא resourceLoadDelay. בפריסה מוצלחת של Early Hints, אני מצפה לירידה של 40%–70% ב-resourceLoadDelay ב-p75 של המשאב שקובע LCP. אם לא רואים את זה תוך 48 שעות מהפרסום, משהו לא עובד ואפשר לחזור לבדוק את הכותרות עם curl -v --http2.
כלי נוסף שאני משתמשת בו הוא web.dev Early Hints guide יחד עם WebPageTest. WebPageTest 24+ מסמן ב-timeline את ה-103 בצבע שונה כדי להראות מתי הדפדפן קיבל את ה-hint.
שאלות נפוצות
האם Early Hints מחליף לגמרי את <link rel="preload">?
לא. Early Hints משלים את ה-preload, לא מחליף אותו. תמיד צריך גם <link rel="preload"> בתוך ה-HTML כרשת ביטחון עבור לקוחות ו-proxies שחוסמים תגובות 1xx (עדיין כ-3–5% מהתעבורה ב-2026).
האם Early Hints עובד עם HTTP/2 Server Push שהוסר?
Early Hints הוא היורש של HTTP/2 Server Push ש-Chrome הסיר ב-2022. השוני: Push דחף את המטען עצמו (וקרה שהמטען לא היה רלוונטי), בעוד ש-Early Hints רק רומז לדפדפן מה כדאי למשוך, והדפדפן מחליט. זה יעיל יותר ומכבד עדיפויות.
כמה משאבים כדאי לשלוח ב-Early Hints?
לא יותר מ-2–4 משאבים לכל דף, וכולם צריכים להיות אלה שקובעים LCP או חוסמים רינדור: hero image, hero font, ולפעמים critical CSS chunk. שליחת יותר מדי hints מציפה את הדפדפן ופוגעת ב-INP.
האם Early Hints יעבוד גם על SPA כמו React או Vue?
כן, אבל רק על הניווט הראשוני לדף. Early Hints לא רלוונטי לניווטים פנימיים ב-SPA (client-side routing). לניווטים פנימיים, השתמשו ב-Speculation Rules API ליצירת prerender.
איך אני יודעת שה-CDN שלי שולח בפועל את ה-103?
הריצו curl -sIv --http2 https://your-site.com/ ותחפשו שתי שורות HTTP/2: הראשונה 103 והשנייה 200. אם רואים רק את ה-200, ה-Early Hints לא פעיל. WebPageTest 24+ גם מסמן 103 בטיים-ליין בצבע נפרד.
האם Lighthouse מודד את ההשפעה של Early Hints?
לא באופן מהימן. Lighthouse סינתטי רץ עם רשת מדומה ולא רואה את חיסכון ה-round-trip האמיתי. מדידה אמינה חייבת להיות ב-RUM (web-vitals + attribution) או ב-CrUX, לפי p75 עם פילוח לפי סוג מכשיר וסוג חיבור.

