網頁載入效能
本文包含 CSS/JS 載入等相關優化問題。
打包
正確做法是 50KB 內直接全部打包即可,更大就按照功能拆分,大型 vendor JS 則做拆分 chunk。
多檔案打包在 HTTP/1.1 是必要的,因為每個檔案都要佔用一條 TCP 連線,瀏覽器限制約 6 條並行連線。HTTP/2 之後理論上打包已經不必要,可多工多個檔案並行傳輸,然而打包還是有很多好處,比如:
- 每個 request 都有 HTTP header
- 字串更多,壓縮效率更高
- 小檔案可能填不滿一個 TLS Record 造成資源浪費
JS
現代已經不再需要為了效能把所有 JS 移動到 body 標籤結束前才載入了,async/defer/type="module" 都可以延後執行避免阻塞,defer 和 type="module" 都會讓 script 標籤等到網頁渲染結束才執行 JS,async 作用相似只是下載完成後立刻執行,而瀏覽器會同時下載多個資源,因此會看到 HTML/CSS/JS 幾乎同時下載,然後 JS 等到渲染完成後才執行。
只要是 defer/type="module" 載入的都不會被記入 PageSpeed Insights 分數,但是 JS 裡面又要求其他 JS 還是會被抱怨 dependency tree 太深。
實際測試 defer 和 type="module" 使用同一個佇列。
CSS
總建議就是把所有東西都打包成唯一一個 CSS,除非你的網站 CSS 很大超過 100 KB,不過個人網站應該不會出現這種問題。最常造成效能的問題只有在 head 以外的地方載入 CSS 導致 CSSOM 需要修改,因此效能扣分。
設定 media="print" onload="this.media='all'" 可以非同步載入樣式,雖然能上場的地方不多,但是能上場時是真的很有用,簡單有效 (Resource inlining in JavaScript frameworks)。
關鍵 CSS
關鍵 CSS 壓在 14KB 以內可以在 TCP initcwnd 第一次傳輸就直接把數據一起傳完,不需要等 ACK 回應,但是實際上很少看到有人做關鍵 CSS 拆分。
圖片
WebP 是 21 世紀的神,永遠該用他,傳統 JPG/PNG 要等到完全下載之後才能解析圖片,WebP 不只壓縮率高,更可以下載到一半就開始解析圖片,各種硬體裝置也都支援良好,其他次世代格式 APNG/JXL/AVIF 全都輸在支援度上。
你應該在上傳圖片前就先在本地將圖片轉好檔而不是透過 Hugo 幫你轉,否則每次 CI 都在浪費資源,本地轉好也就不需要處理 Cloudflare 上 Hugo 糟糕的支援度,連設定快取都困難重重。
你可以參考我的工作流程:使用 automator 簡化日常工作流程,或是使用開源專案 FotoKilof 也能輕鬆轉檔。
屬性設定
- fetchpriority: 改了之後沒感覺到差別,別浪費時間設定他。
- loading: 可手動設定 lazy,明顯有感。