「譯」Netflix 的 Web 性能案例研究


「譯」Netflix 的 Web 性能案例研究


提綱:Web 性能優化沒有銀彈。簡單的靜態網頁得益於使用極少 JavaScript 代碼的服務端渲染。庫的謹慎使用可以為複雜的頁面帶來巨大的價值。

Netflix 是最受歡迎的視頻流服務之一。自 2016 年在全球推出以來,公司發現許多新用戶不僅通過移動設備完成註冊,而且還使用了不太理想的網絡連接。

通過改進用於Netflix.com 註冊過程 JavaScript 代碼和使用預加載技術,開發人員團隊可以為移動和桌面用戶提供更好的用戶體驗,並提供多項改進。

  • 減少 50% 的加載和可交互時間(適用於Netflix.com 桌面端未登錄的主頁)
  • 通過把 React 和其他客戶端庫改為原生的 JavaScript 使打包大小減少 200 KB。React 仍在服務端使用
  • 為將來的操作預獲取 HTML,CSS 和 JavaScript(React)使可交互時間減少 30%

通過嵌入更少的代碼來減少可交互時間

Netflix 開發者優化性能的地方是未登錄主頁,用戶在此頁面註冊並登錄站點。


「譯」Netflix 的 Web 性能案例研究


新用戶和已登出用戶的Netflix.com 主頁

此頁面初始包含 300KB 的 JavaScript 代碼,其中一些是 React 和其他客戶端代碼(例如像 Lodash 的工具庫),而且還有一些是必要的上下文數據用來給 React 的狀態注水(hydrate)。

所有 Netflix 的網頁都由服務端 React 渲染,這些頁面為生成的 HTML 和客戶端應用提供服務,因此維持新優化的主頁結構不變和保持開發人員體驗的一致性同樣重要。


「譯」Netflix 的 Web 性能案例研究


Homepage 選項卡是最初使用 React 編寫的組件的示例

使用 Chrome 的 DevTools 和 Lighthouse 來模擬 3G 網絡下加載未登錄主頁,結果顯示未登錄主頁需要 7 秒時間來加載,這段時間對於一個簡單的入口頁面來說實在是太久了,所以我們開始調查改進的可能性。通過一些性能審查,Netflix 發現他們的客戶端 JS 有過高的開銷。


「譯」Netflix 的 Web 性能案例研究


通過 Chrome DevTools 的網絡限速功能,查看未優化的Netflix.com 的表現。

通過關閉瀏覽器中的 JavaScript 來觀察站點中仍在起作用的元素,開發者團隊可以決定 React 在未登錄主頁是否真正必要。

由於頁面中的多數元素是基本的 HTML,剩下的元素比如 JavaScript 點擊處理和添加類可以用原生 JavaScript 來替換,而頁面原來使用 React 實現的語言切換器則使用不到 300 行的原生 JavaScript 代碼重構。

移植到原生 JavaScript 的組件完全列表:

  • 基礎交互(主頁中的選項卡)
  • 語言切換器
  • Cookie 橫幅(針對非美國訪問者)
  • 分析用的客戶端日誌
  • 性能評估和記錄
  • 廣告來源引導代碼(出於安全考慮,沙盒化放在 iframe 裡)


「譯」Netflix 的 Web 性能案例研究


雖然 React 的初始代碼僅僅 45 KB,在客戶端移除 React、一些庫和相應的 App 代碼 減少的 JavaScript 代碼總量超多 200 KB ,由此在 Netflix 的未登錄主頁降低了超過 50% 的可交互時間。


「譯」Netflix 的 Web 性能案例研究


移除客戶端 React、Lodash 和其他一些庫前後的負載比較。

在實驗環境下,我們可以使用Lighthouse(trace)快速測驗用戶是否能與 Netflix 主頁交互。結果桌面端的 TTI 少於 3.5s。


「譯」Netflix 的 Web 性能案例研究


可交互時間優化後的 Lighthouse 報告。

那麼這個領域的度量標準呢?使用Chrome 用戶體驗報告我們可以看到首次輸入延遲 —— 從用戶首次與你的站點交互時間到瀏覽器真正響應那次交互的時間 —— 對於 97% 的 Netflix 桌面用戶來說很快。結果非常棒。


「譯」Netflix 的 Web 性能案例研究


首先輸入延遲(FID)度量用戶在與頁面交互時的延遲體驗。

為後續頁面預加載 React

為了進一步提高瀏覽登錄主頁的性能,Netflix 利用用戶在入口頁面上花費的時間針對可能會登錄的下一個頁面進行資源 預加載

通過兩項技術完成 —— 內置的 瀏覽器 API 和 XHR 預加載。

內置的瀏覽器 API 包含頁面頭部標籤內的簡單鏈接標籤。它會建議瀏覽器資源(例如 HTML、JS、CSS、圖片)可以被預加載,雖然它並不保證瀏覽器真的 預加載資源,並且它缺少其他瀏覽器的全面支持。


「譯」Netflix 的 Web 性能案例研究


預加載技術對比

另一方面,XHR 預加載已經成為瀏覽器標準很多年了,當 Netflix 團隊提示瀏覽器緩存資源時,其成功率達到 95%。但是 XHR 預加載不能預加載 HTML 文檔,Netflix 用它來為後續頁面預加載 JavaScript 和 CSS 打包文件。

注意:Netflix 配置的 HTTP 響應頭禁止使用 XHR 緩存 HTML(它們確實不緩存(no-cache)第二個頁面的 HTML)。鏈接預加載會按預期工作,因為它對 HTML 有效,即使設置了不緩存(no-cache)。

// 創建新的 XHR 請求
const xhrRequest = new XMLHttpRequest();
// open the request for the resource to "prefetch"
// 打開請求來“預加載”資源
xhrRequest.open('GET', '../bundle.js', true);
// 發送!
xhrRequest.send();

通過使用瀏覽器內置 API 和 XHR 預加載 HTML、CSS 和 JS,可交互時間減少了 30%。這個實現不需要重寫 JavaScript,也不會對未登錄主頁的性能造成負面影響,而且從此以後,能以極低的風險為提升頁面性能提供了非常有價值的工具。


「譯」Netflix 的 Web 性能案例研究


預加載實現之後,Netflix 開發者可以通過分析頁面減少的可交互時間數據來觀察性能提升效果,同樣使用 Chrome 開發工具直接度量資源緩存的命中情況。

Netflix 未登錄主頁 —— 優化總結

通過預加載 Netflix 未登錄主頁資源和優化客戶端代碼,Netflix 可以在註冊過程中出色地提升可交互時間指標。通過使用瀏覽器內置 API 和 XHR 預加載來預獲取未來頁面,Netflix 可以把可交互時間降低 30%。這是針對下一頁面的加載,其中包含單頁應用註冊過程的引導代碼。

Netflix 團隊進行的代碼優化表明,React 是一個十分有用的庫,不過它可能無法為每個問題提供足夠的解決方案。通過從第一個用於註冊的入口頁面的客戶端代碼中刪除 React,可交互時間減少了 50% 以上。縮短客戶端上的可交互時間還可以讓用戶以更快地速度單擊註冊按鈕,這表明代碼優化完全可以帶來更好的用戶體驗。

雖然 Netflix 沒有在主頁中使用 React,但他們為後續的頁面預加載。這使得他們整個頁面應用程序流程中的其他部分可以利用客戶端 React。

更多關於這些優化的細節,請觀看 Tony Edwards 的出色演講:

  • YouTube 視頻鏈接:youtu.be/V8oTJ8OZ5S0

總結

通過密切關注 JavaScript 的開銷,Netflix 發現了改善可交互時間的機會。若想發現你的站點是否有機會在這點上做得更好,可以藉助你的性能工具。

Netflix 決定做出的權衡是使用 React 對入口頁面進行服務器渲染,同時也在其上預先獲取 React 和其餘註冊流程的代碼。這樣可以優化首次加載性能,同時還可以優化其餘註冊流的加載時間,因為它是一個單頁應用程序,因此需要下載更大的 JS 打包文件。

考慮一下是否使用原生 JavaScript 是否適合你的站點的流程。如果你確實需要使用庫,那麼嘗試只嵌入你的用戶需要的代碼。預加載技術可以幫助優化未來瀏覽頁面的加載時間。

需要前端資料或者想學前端的小夥伴可以私信“前端”“前端資料”免費獲取


分享到:


相關文章: