本篇重點
- 資源連線與載入的時間線
- 縮短首次繪製時間(First Paint)的方法
rel="preconnect"
、rel="preload"
、fetchpriority
的用意與差異- 有/無用這些屬性時,載入時間的差異
fetchpriority
與preload
的差異crossorigin
屬性的用途與使用時機onload="this.rel='stylesheet'"
的動態載入樣式
資源連線與載入的時間線
瀏覽器載入網頁時,通常會經歷以下階段:
- DNS 查詢:查詢網域名稱對應的 IP。
- TCP 連線:建立與伺服器的連線。
- TLS 握手(HTTPS 時):建立安全通道。
- HTTP 請求與回應:正式請求與接收資源。
- 解析 HTML → 載入資源(CSS、JS、字型、圖片等)。
若外部資源(例如字型、CSS、圖片)位於不同網域,這三個階段(DNS、TCP、TLS)都要重新建立一次。
因此,若能「提前建立連線」或「提前載入關鍵資源」,就能減少等待時間,縮短「首次繪製時間(First Paint)」。
rel=”preconnect”
preconnect
可讓瀏覽器先幫該網域建立連線(包含 DNS、TCP、TLS),後續正式請求資源時,可以直接跳過連線階段,加速載入。
- 不會下載資源,只提前連線
- 不會影響 HTML 解析與 DOM 建立流程
- 適合第三方資源(CDN、字型、API 域名)
差異說明
- 無使用:瀏覽器碰到真正要下載資源的 HTML/CSS/JS(例如
<link href="...">
、@font-face
的字型 URL)時,才開始 DNS → TCP → TLS 等連線流程。 - 有使用:瀏覽器解析到
<link rel="preconnect" href="...">
,就會在此階段開始 DNS → TCP → TLS。之後當資源被引用,連線步驟已完成,可以立即發送請求。
範例
Google Fonts 官方載入範例
1 | <link rel="preconnect" href="https://fonts.googleapis.com"> |
rel=”preload”
preload
告訴瀏覽器「這個資源很重要,請優先載入」,即使該資源稍後才會在 CSS 或 JS 中被引用。下載後並不會直接執行資源,只是讓瀏覽器先行下載。
- 控制載入順序、避免延遲渲染
- 不會影響 HTML 解析與 DOM 建立流程
- 適合關鍵字型、首屏圖片等
差異說明
- 無使用:瀏覽器會在解析到資源引用(例如在 CSS 裡發現 @font-face 或 HTML 中發現
<img> / <link rel="stylesheet">
)時才下載;若 CSS 在較後才解析,資源下載會被延後。 - 有使用:在瀏覽器解析
<link rel="preload" href="..." as="...">
那一刻就開始下載該資源,因此能顯著縮短關鍵資源的可用時間。
範例
1 | <link rel="preload" href="https://fonts.gstatic.com/s/foo.woff2" as="font" type="font/woff2" crossorigin /> |
Fetch Priority API
HTML5 新增的屬性,允許開發者為單一資源標記優先順序(high
、low
、auto
),讓瀏覽器在其內部的排程中更傾向先下載或後下載該資源,但瀏覽器可能根據自身策略(例如當前網路情況、連線數量、瀏覽器內部優化、節能模式等)決定是否完全遵從 。
- 控制資源載入優先順序
- 適用於關鍵圖片、主樣式表、首屏腳本等
- 常用於
<img>
、<link>
、<script>
瀏覽器載入優先級(Chrome)
優先度 | 資源類型 | 備註 |
---|---|---|
Highest | HTML、CSS、fonts | 首屏必要資源 |
High | 主程式 script、defer script、首屏圖片(in-viewport) | 主要邏輯與畫面 |
Medium | 一般 script(例如次要互動) | 非立即需要 |
Low | async script、lazyload 圖片/影音 | 非同步載入、不影響首屏 |
Lowest | prefetch 、非當前頁面資源 | 未來可能用到 |
差異說明
- 無使用:照原瀏覽器載入順序下載資源
- 有使用:影響該資源在下載排程的優先順序
範例
1 | <img src="/hero.webp" fetchpriority="high" alt="Main Banner"> |
- 提醒瀏覽器「這個資源對渲染很重要」,應該盡早下載
- 相反地,背景圖片、懸浮區塊可標註為
fetchpriority="low"
,節省頻寬
與 preload 差異:
preload
是「強制提前下載」fetchpriority
是「建議調整優先權」
項目 | fetchpriority | <link rel="preload"> |
---|---|---|
是否強制下載 | 不會強制(僅建議) | 強制瀏覽器預先載入資源 |
適用資源 | 任何可下載資源(img, script, css, font) | 通常用於關鍵字體、CSS、首屏圖片 |
時機差異 | 等瀏覽器解析到資源時才決定下載順序 | 在解析 HTML 初期就主動開始下載 |
是否影響渲染 | 不直接影響渲染,只影響載入排序 | 可顯著縮短首屏渲染時間 |
動態載入樣式
可讓瀏覽器延遲樣式表的應用,避免同步的 CSS 阻塞初始渲染。
- 使用
rel="preload"
先下載 CSS,但不立即套用 - 當
onload
觸發後,再將rel
改為"stylesheet"
,瀏覽器才正式套用樣式 - 避免 render-blocking
- 常用於「非關鍵 CSS」
範例:
1 | <link rel="preload" href="/css/print.css" as="style" onload="this.onload=null;this.rel='stylesheet'"> |
說明:
onload=null
避免載入後重複觸發事件<noscript>
提供給沒有 JS 環境的用戶- 可避免 CSS 阻塞渲染(Render-blocking),提升 LCP(Largest Contentful Paint)
crossorigin
屬性的用途與時機
給需要使用 CORS(Cross-Origin Resource Sharing)驗證的資源,不是所有跨源資源都需要使用 crossorigin
。
值 | 說明 |
---|---|
anonymous | 不帶憑證(cookies、授權資訊)。 |
use-credentials | 帶憑證發送請求。 |
使用時機:
- 字型、圖片、影片、JS 來自不同網域時。
- 需要通過 CORS 驗證的資源(否則會被視為失敗)。
範例:
1 | // 字型檔屬於「需要 CORS 驗證」的資源 |
結論
preconnect
、preload
、fetchpriority
是優化前端中互補的三個屬性:
- preconnect:提前連線,解決「網路握手延遲」,不下載資源,適合重要的第三方域名。
- preload:提前下載,解決「關鍵資源延後載入」,適合關鍵字型/圖片效果顯著。
- fetchpriority:精細調整優先權,解決「資源搶占頻寬問題」,是建議而非強制。
整體而言,這些屬性的目的都是讓「瀏覽器提早行動」,減少等待,提升用戶的載入體驗,但也要控制使用數量與範圍,避免造成頻寬壅塞或預載過多無效資源的問題。