好,今天要來聊的主題是「預加載關鍵資源」,以及它要怎麼去…呃…提升網站的 SEO 效能。很多人聽到這個,可能覺得很技術,但其實…說真的,它背後的邏輯還蠻直觀的。
簡單講,就是你先「偷跑」,在瀏覽器真正需要某個檔案之前,就先跟它說:「欸,這個東西很重要,你先去下載放著」。 這樣一來,等輪到它要上場的時候,就不用再花時間去下載,頁面自然就顯示得比較快。速度快,使用者體驗就好,Google 也會給你比較好的評價,這對 SEO 當然是有幫助的。
先說結論:為什麼 SEO 要管到 preload?
嗯…直接講重點,就是為了改善「網站體驗核心指標」,也就是 Core Web Vitals。 這東西是 Google 衡量使用者體驗的一組指標,而且它也直接或間接的影響 SEO 排名。 其中最直接相關的就是 LCP,也就是「最大內容繪製」(Largest Contentful Paint)。
LCP 指的是頁面上那個最大的圖片或文字區塊,從載入到完全顯示出來要花多久時間。 通常,這個最大的元素就是你網站的「門面」,例如首頁的大 banner 圖、文章的特色圖片等等。如果這個門面要等老半天才出來,使用者會覺得你的網站很慢,然後可能就直接跳走了。 所以,透過預先載入 (preload) 這個 LCP 圖片,我們就能確保它能盡快被下載和顯示,直接改善 LCP 分數。
所以,整個邏輯串起來就是:你用 `preload` → LCP 圖片提早載入 → LCP 分數變好 → Core Web Vitals 過關 → 使用者體驗變好 → Google 可能會因此提升你的排名。就這麼簡單。
怎麼做?preload、preconnect 這些是在幹嘛的?
好,那實際上要怎麼做?最核心的工具就是 HTML 裡的一個 `` 標籤,然後搭配 `rel` 屬性。主要有幾個我們會用到的:`preload`、`preconnect`、還有 `dns-prefetch`。這幾個長很像,但做的事情…呃…層級不太一樣。
我把它們整理成一個表格,這樣比較好懂。
| 屬性 | 白話文解釋 | 使用時機 |
|---|---|---|
rel="preload" |
「喂!這個檔案超重要,你現在、立刻、馬上去下載,但先不要執行。」 | 用在當頁一定會用到的關鍵資源,特別是那種藏在 CSS 或 JS 裡,瀏覽器很晚才會發現的東西。例如 LCP 圖片、關鍵的字型檔、或是核心的 CSS 檔案。 |
rel="preconnect" |
「我等下會跟這個網站 (域名) 要東西,你先去跟他打個招呼、建立連線吧。」 | 當你知道頁面很快就會從某個第三方域名下載資源時。例如 Google Fonts、或是放圖片的 CDN 服務器。先連線可以省下 DNS 查詢、TCP 交握、TLS 驗證的時間。 |
rel="dns-prefetch" |
「你先幫我查一下這個網址的 IP 是多少,放著備用。」 | 這個是 `preconnect` 的輕量版,只做 DNS 查詢。可以用在那些「可能」會用到,但沒那麼緊急的第三方域名。或是當作不支援 `preconnect` 的瀏覽器的備案。 |
所以你看,`preload` 是最霸道的,直接叫瀏覽器去拿檔案。 `preconnect` 只是先去敲門,`dns-prefetch` 更只是問路而已。 那實際要 preload LCP 圖片的話,程式碼大概會長這樣,加在 HTML 的 `
` 裡面:<!-- 預載入一張重要的圖片 -->
<link rel="preload" as="image" href="/path/to/your-lcp-image.webp" imagesrcset="/path/to/your-lcp-image-400w.webp 400w, /path/to/your-lcp-image-800w.webp 800w" imagesizes="100vw" fetchpriority="high">
這邊有幾個重點要注意:
- `as="image"`:你一定要跟瀏覽器說你要載入的是什麼「類型」的檔案。 如果不寫,瀏覽器可能會重複下載,反而更慘。
- `imagesrcset` 和 `imagesizes`:如果你的 LCP 圖片有做響應式設計(不同螢幕寬度用不同大小的圖),那 `preload` 這裡也要對應寫好,不然可能會載錯圖,白忙一場。
- `fetchpriority="high"`:這是個比較新的屬性,你可以明確地告訴瀏覽器:「這個資源的優先級是最高的!」算是給 preload 再加上一個保險。
- `crossorigin`:如果你要 preload 的資源是放在不同的網域(例如 CDN),記得要加上這個屬性,不然瀏覽器可能會因為安全策略而不去載入。
真的有用嗎?來看個實際案例
講那麼多,不如直接看結果。你可以自己用 Chrome 的開發者工具 (DevTools) 裡面的 Network 面板來觀察。你看,在沒有用 preload 之前,瀏覽器要先下載 HTML,然後解析 CSS,才發現「啊!原來這裡要一張背景圖」,這時候才開始去下載 LCP 圖片。
但是用了 `preload` 之後,情況就不一樣了。瀏覽器在看到 HTML 裡那行 `preload` 指令時,就會跟下載 CSS 同時、甚至更早去下載那張 LCP 圖片。 從下面的瀑布圖就可以看到,圖片的下載時間整個往前拉了。
這中間省下來的時間,就是 LCP 的改善空間。對於網路慢的使用者來說,這個感受會非常明顯。 國外像 web.dev 這種很權威的網站,也一直強調 `preload` 對於改善 LCP 的重要性。 而在台灣,很多效能優化的文章或案例分享,也都會提到要優先處理 LCP 圖片,例如透過 CDN 或是像這樣的 preload 手法。
亂用會出事:Preload 的限制與反效果
不過,`preload` 也不是萬靈丹,它其實是一把雙面刃。你把它想成是「插隊券」,你讓某個資源插隊,就代表其他資源要排隊。如果你給了太多資源插隊券,那結果就是…呃…大家一起塞在前面,等於沒有人插隊,甚至比原本更糟,因為瀏覽器一開始就被迫下載一堆它可能還不需要的東西,反而拖慢了真正重要的初始渲染。
所以,千萬記得幾個原則:
- 只對「關鍵資源」用:只 preload 那些確定在「首次渲染」中絕對必要,而且瀏覽器自己又很晚才會發現的資源。LCP 圖片和字體是最好的例子。
- 不要什麼都 preload:千萬不要手癢把所有 CSS、JS 都加上去。很多資源其實是可以延後載入或非同步載入的。
- 測試再測試:每次做了 `preload` 調整,都要用 PageSpeed Insights 或 DevTools 看看結果是不是真的變好。有時候你以為的「關鍵資源」,對瀏覽器來說可能不是。
總結來說,`rel="preload"` 是一個很強大,但需要小心使用的工具。我自己是覺得,你只要專注在解決 LCP 這個問題上,基本上就不會錯得太離譜。與其想著要 preload 一大堆東西,不如先用工具找出 LCP 元素,然後只針對它來做優化,這樣通常效果最好,也最安全。
好,那這次大概就分享到這邊。你可以去檢查一下自己網站的 LCP 元素是什麼,看看它是不是有被延遲載入?如果有的話,也許可以試試看今天提到的方法。你在優化網站速度時,有沒有踩過什麼有趣的坑呢?歡迎在下面留言分享一下!
