[譯] Netflix 的 Web 性能案例研究

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

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

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

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

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

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

新用戶和已登出用戶的Netflix.com 主頁性能優化

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

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

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

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

經過 Chrome DevTools 的網絡限速功能,查看未優化的Netflix.com 的表現。開發工具

經過關閉瀏覽器中的 JavaScript 來觀察站點中仍在起做用的元素,開發者團隊能夠決定 React 在未登陸主頁是否真正必要。fetch

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

移植到原生 JavaScript 的組件徹底列表:

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

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

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

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

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

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

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

爲後續頁面預加載 React

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

經過兩項技術完成 —— 內置的 <link rel=prefetch> 瀏覽器 API 和 XHR 預加載。

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

預加載技術對比

另外一方面,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 開發者能夠經過分析頁面減小的可交互時間數據來觀察性能提高效果,一樣使用 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 是否適合你的站點的流程。若是你確實須要使用庫,那麼嘗試只嵌入你的用戶須要的代碼。預加載技術能夠幫助優化將來瀏覽頁面的加載時間。

原文連接:https://www.jianshu.com/p/83c...

相關文章
相關標籤/搜索