前端黑科技:美團網頁首幀最佳化實踐
導讀
美團支付前端團隊支援著美團錢包及支付業務,涉及專案眾多,並且專案迭代很快,挑戰巨大。在總結經驗之後,我們舉辦了第40期美團技術沙龍,與大家分享我們的實戰經驗。
(圖片來自寒陽分享現場)
自JavaScript誕生以來,前端技術發展非常迅速。移動端白屏最佳化是前端介面體驗的一個重要最佳化方向,Web 前端誕生了 SSR 、CSR、預渲染等技術。在美團支付的前端技術體系裡,透過預渲染提升網頁首幀最佳化,從而最佳化了白屏問題,提升使用者體驗,並形成了最佳實踐。
在前端渲染領域,主要有以下幾種方式可供選擇:
透過對比,同構方案集合 CSR 與 SSR 的優點,可以適用於大部分業務場景。但由於在同構的系統架構中,連線前後端的 Node 中間層處於核心鏈路,系統可用性的瓶頸就依賴於 Node ,一旦作為短板的 Node 掛了,整個服務都不可用。
結合到我們團隊負責的支付業務場景裡,由於支付業務追求極致的系統穩定性,服務不可用直接影響到客訴和資損,因此我們採用瀏覽器端渲染的架構。在保證系統穩定性的前提下,還需要保障使用者體驗,所以採用了預渲染的方式。
那麼究竟什麼是預渲染呢?什麼是 FCP/FMP 呢?我們先從最常見的 CSR 開始說起。
以 Vue 舉例,常見的 CSR 形式如下:
一切看似很美好。然而,作為以使用者體驗為首要目標的我們發現了一個體驗問題:首屏白屏問題。
為什麼會首屏白屏
瀏覽器渲染包含 HTML 解析、DOM 樹構建、CSSOM 構建、JavaScript 解析、佈局、繪製等等,大致如下圖所示:
要搞清楚為什麼會有白屏,就需要利用這個理論基礎來對實際專案進行具體分析。透過 DevTools 進行分析:
等待 HTML 文件返回,此時處於白屏狀態。
對 HTML 文件解析完成後進行首屏渲染,因為專案中對加了灰色的背景色,因此呈現出灰屏。
進行檔案載入、JS 解析等過程,導致介面長時間出於灰屏中。
當 Vue 例項觸發了 mounted 後,介面顯示出大體框架。
呼叫 API 獲取到時機業務資料後才能展示出最終的頁面內容。
由此得出結論,因為要等待檔案載入、CSSOM 構建、JS 解析等過程,而這些過程比較耗時,導致使用者會長時間出於不可互動的首屏灰白屏狀態,從而給使用者一種網頁很“慢”的感覺。那麼一個網頁太“慢”,會造成什麼影響呢?
“慢”的影響
Global Web Performance Matters for ecommerce的報告中指出:
57%的使用者更在乎網頁在3秒內是否完成載入。
52%的線上使用者認為網頁開啟速度影響到他們對網站的忠實度。
每慢1秒造成頁面 PV 降低11%,使用者滿意度也隨之降低降低16%。
近半數移動使用者因為在10秒內仍未開啟頁面從而放棄。
我們團隊主要負責美團支付相關的業務,如果網站太慢會影響使用者的支付體驗,會造成客訴或資損。既然網站太“慢”會造成如此重要的影響,那要如何最佳化呢?
最佳化思路
在User-centric Performance Metrics一文中,共提到了4個頁面渲染的關鍵指標:
基於這個理論基礎,再回過頭來看看之前專案的實際表現:
可見在 FP 的灰白屏介面停留了很長時間,使用者不清楚網站是否有在正常載入,使用者體驗很差。
試想:如果我們可以將 FCP 或 FMP 完整的 HTML 文件提前到 FP 時機預渲染,使用者看到頁面框架,能感受到頁面正在載入而不是冷冰冰的灰白屏,那麼使用者更願意等待頁面載入完成,從而降低了流失率。並且這種改觀在弱網環境下更明顯。
透過對比 FP、FCP、FMP 這三個時期 DOM 的差異,發現區別在於:
FP:僅有一個 div 根節點。
FCP:包含頁面的基本框架,但沒有資料內容。
FMP:包含頁面所有元素及資料。
仍然以 Vue 為例, 在其生命週期中,mounted 對應的是 FCP,updated 對應的是 FMP。那麼具體應該使用哪個生命週期的 HTML 結構呢?
透過以上的對比,最終選擇在 mounted 時觸發構建時預渲染。由於我們採用的是 CSR 的架構,沒有 Node 作為中間層,因此要實現 DOM 內容的預渲染,就需要在專案構建編譯時完成對原始模板的更新替換。
至此,我們明確了構建時預渲染的大體方案。
構建時預渲染方案
構建時預渲染流程:
配置讀取
由於 SPA 可以由多個路由構成,需要根據業務場景決定哪些路由需要用到預渲染。因此這裡的配置檔案主要是用於告知編譯器需要進行預渲染的路由。
在我們的系統架構裡,腳手架是基於 Webpack 自研的,在此基礎上可以自定義自動化構建任務和配置。
觸發構建
專案中主要是使用 TypeScript,利用 TS 的裝飾器,我們封裝了統一的預渲染構建的鉤子方法,從而只用一行程式碼即可完成構建時預渲染的觸發。
裝飾器:
使用:
構建編譯
從流程圖上,需要在釋出機上啟動模擬的瀏覽器環境,並透過預渲染的事件鉤子獲取當前的頁面內容,生成最終的 HTML 檔案。
由於我們在預渲染上的嘗試比較早,當時還沒有 Headless Chrome 、 Puppeteer、Prerender SPA Plugin等,因此在選型上使用的是 phantomjs-prebuilt(Prerender SPA Plugin 早期版本也是基於 phantomjs-prebuilt 實現的)。
透過 phantom 提供的 API 可獲得當前 HTML,示例如下:
為了提高構建效率,並行對配置的多個頁面或路由進行預渲染構建,保證在 5S 內即可完成構建,流程圖如下:
方案最佳化
理想很豐滿,現實很骨感。在實際投產中,構建時預渲染方案遇到了一個問題。
我們梳理一下簡化後的專案上線過程:
開發 -> 編譯 -> 上線
假設本次修改了靜態檔案中的一個 JS 檔案,這個檔案會透過 CDN 方式在 HTML 裡引用,那麼最終在 HTML 文件中的引用方式是 <script src="
。然而由於專案還沒有上線,所以其實透過完整 URL 的方式是獲取不到這個檔案的;而預渲染的構建又是在上線動作之前,所以問題就產生了:
構建時預渲染無法正常獲取檔案,導致編譯報錯
怎麼辦?
請求劫持
因為在做預渲染時,我們使用啟動了一個模擬的瀏覽器環境,根據 phantom 提供的 API,可以對發出的請求加以劫持,將獲取 CDN 檔案的請求劫持到本地,從而在根本上解決了這個問題。示例程式碼如下:
構建時預渲染研發流程及效果
最終,構建時預渲染研發流程如下:
開發階段:
透過 TypeScript 的裝飾器單行引入預渲染構建觸發的方法。
釋出前修改編譯構建的配置檔案。
釋出階段:
先進行常規的專案構建。
若有預渲染相關配置,則觸發預渲染構建。
透過預渲染得到最終的檔案,並完成釋出上線動作。
完整的使用者請求路徑如下:
透過構建時預渲染在專案中的使用,FCP 的時間相比之前減少了 75%。
作者簡介
寒陽,美團資深研發工程師,多年前端研發經歷,負責美團支付錢包團隊和美團支付前端基礎技術。
原文連結:https://mp.weixin.qq.com/s/20yJV3D8SeI-cM0PCqTDAQ
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31559353/viewspace-2220374/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 前端黑科技:美團網頁首幀優化實踐前端網頁優化
- 前端黑科技:使用 JavaScript 實現網頁掃碼功能前端JavaScript網頁
- 網頁前端黑科技PWA的優劣對比網頁前端
- 毫秒必爭,前端網頁效能最佳實踐前端網頁
- 頁面CLS 最佳化實踐
- Vue+Django 旅遊網專案 首頁前端實現VueDjango前端
- HarmonyOS:幀率和丟幀分析實踐
- 網頁上的微服務—微前端架構實踐網頁微服務前端架構
- 美團掃碼付的前端可用性保障實踐前端
- 美團掃碼付的前端可用性保障實踐!前端
- 前端效能最佳化實踐方向與方法前端
- 美團視覺GPU推理服務部署架構最佳化實踐視覺GPU架構
- JS實現把網頁設定為首頁JS網頁
- 京東微信購物首頁效能優化實踐優化
- 評書:《美團機器學習實踐》機器學習
- 美團DSP廣告策略實踐
- Android自動化頁面測速在美團的實踐Android
- 黑科技開戶神器黑科技開戶神器黑科技開戶神器黑科技開戶神器黑科技開戶神器
- 實踐指南-網頁生成PDF網頁
- Vue SPA(單頁應用)首屏優化實踐Vue優化
- 前端必知必會--操作URL的黑科技前端
- OpenGL 之 幀緩衝 使用實踐
- phpcms後臺生成首頁成功,前端首頁空白的解決方法PHP前端
- 美團配送資料治理實踐
- Flutter原理與美團的實踐Flutter
- 美團BERT的探索和實踐
- 優酷播放黑科技 | 自由視角技術體驗優化實踐優化
- 自定義 behavior 完美仿 QQ 瀏覽器首頁,美團商家詳情頁瀏覽器
- 網頁中隱藏幀的妙用 (轉)網頁
- 京喜小程式首頁無障礙優化實踐優化
- 前端面試題 — 前端頁面效能最佳化前端面試題
- 圖計算黑科技:開啟中文詞嵌入訓練實踐新模式模式
- 2019前端必會黑科技之PWA前端
- JS 網頁列印 頁邊距 頁首頁尾JS網頁
- 《美團機器學習實踐》—— 讀後總結機器學習
- Threejs實現滴滴官網首頁地球動畫JS動畫
- 強化工控網路安全 綠盟科技竟祭出黑科技!
- 實現不同頁面不同頁首