長久以來,我一直認為高 Lighthouse 分數主要是調校的結果。壓縮圖片、延遲載入腳本、修復版面位移、調整主題、更換外掛,並在每次出現新警告時重複這個循環。
隨著時間推移,這個假設開始與我在實務中看到的情況不符。
持續獲得高分的網站並非投入最多優化努力的網站。它們是瀏覽器只需執行較少工作的網站。
從那時起,Lighthouse 不再像是一個優化工具,而開始像是架構選擇的診斷訊號。
Lighthouse 不評估框架或工具。它評估結果。
有意義的內容出現的速度有多快。
JavaScript 阻塞主執行緒的程度有多少。
版面在載入期間保持穩定的程度如何。
文件結構的可存取性和可檢索性如何。
這些結果是在技術堆疊中更早做出的決策所產生的下游效應。特別是,它們反映了在執行時期有多少運算被延遲到瀏覽器。
當頁面依賴大型客戶端套件才能使用時,分數不佳並不令人意外。當頁面主要是靜態 HTML 且客戶端邏輯有限時,效能就會變得更可預測。
在我執行的稽核和參與的專案中,JavaScript 執行是 Lighthouse 退步最常見的來源。
這不是因為程式碼品質低落。這是因為 JavaScript 在頁面載入期間競爭單執行緒的執行環境。
框架執行階段、水合邏輯、相依性圖表和狀態初始化都會在頁面變得可互動之前消耗時間。即使是小型互動功能也經常需要不成比例的大型套件。
預設使用 JavaScript 的架構需要持續努力才能控制效能。將 JavaScript 視為明確選擇性加入的架構往往會產生更穩定的結果。
預先渲染的輸出從效能方程式中移除了幾個變數。
在請求時沒有伺服器端渲染成本。
內容出現不需要客戶端啟動程序。
瀏覽器接收可預測、完整的 HTML。
從 Lighthouse 的角度來看,這改善了 TTFB、LCP 和 CLS 等指標,而無需進行針對性的優化工作。靜態生成不保證完美分數,但它顯著縮小了失敗模式的範圍。
在重建我的個人部落格之前,我探索了幾種常見方法,包括預設依賴水合的 React 架構。它們靈活且強大,但效能需要持續關注。每個新功能都會引入關於渲染模式、資料擷取和套件大小的問題。
出於好奇,我嘗試了一種不同的方法,先假設靜態 HTML,並將 JavaScript 視為例外。我選擇 Astro 進行這個實驗,因為它的預設限制與我想測試的問題一致。
突出的不是初始分數有多驚人,而是隨著時間推移維持效能所需的努力有多少。發布新內容不會引入退步。小型互動元素不會級聯到無關的警告。基準線更難被侵蝕。
我在一份獨立的技術筆記中記錄了建置流程和架構權衡,同時在具有完美 Lighthouse 分數的個人部落格上進行這個實驗。
這種方法並非普遍更好。
靜態優先架構不適合高度動態、有狀態的應用程式。它們可能會使嚴重依賴已驗證使用者資料、即時更新或複雜客戶端狀態管理的情境變得複雜。
假設客戶端渲染的框架在這些情況下提供更多彈性,代價是更高的執行時期複雜性。重點不是某種方法更優越,而是權衡直接反映在 Lighthouse 指標中。
Lighthouse 呈現的不是努力,而是熵。
依賴執行時期運算的系統會隨著功能增加而累積複雜性。在建置時期執行更多工作的系統預設限制了這種複雜性。
這種差異解釋了為什麼有些網站需要持續的效能工作,而其他網站只需最少干預就能保持穩定。
高 Lighthouse 分數很少是積極優化過程的結果。它們通常自然地從最小化瀏覽器在首次載入時必須執行的工作的架構中產生。
工具來來去去,但基本原則保持不變。當效能是預設限制而非目標時,Lighthouse 就不再是你追逐的東西,而是你觀察的東西。
這種轉變與其說是選擇正確的框架,不如說是選擇允許複雜性存在的位置。


