課程介紹
高性能極致用戶體驗前端開發實戰課程適合所有前端開發學習或者從業者,結合目前前端開發的最佳實踐,提供前端網頁性能分析優化知識,結合實際項目經驗分析可以采用的優化思路,並給出開發高性能極致體驗網頁的通用方法和技巧。 課程官方博客:前端學堂
在開始學習本課程之前,先提2個基本要求:
了解業務
作為一名合格的前端開發,我們的開發工作不是盲目的,我們的優化目標需要明確,所以首先要了解你所做的業務。不僅要知道整個業務背景,還需要了解業務需求,業務目的,最后最好能拿到業務結果。
了解業務的目的是能讓你更好的分配開發的權重,合理安排開發的重點。比如開發的是視頻類網站,那么開發的重點自然在於播放器加載和流暢播放以及降級方案。如果是天氣類業務,那么核心業務是要保障穩定快速的展示出天氣相關數據,然后是加載展示其他內容。如果是博文類網站,那么重點在於首屏的信息加載和展示。
了解用戶
了解用戶也是至關重要,如果連自己所做業務的受眾都不知道,那么何談用戶體驗,何談極致性能? 這一部分至少你要知道現在做的業務主要是面向PC用戶還是移動web用戶,PC用戶所用的瀏覽器都是什么版本,比例分布是怎樣?移動端用戶android和ios比例多少,各自平台版本分布情況如何?這是最基本的要求,因為我們開發的代碼是在這些平台運行的。 如果不知道怎么辦?沒關系,從今天開始統計起來,做個埋點日志服務,前端寫個腳本上報下useragent就可以了。
- navigator.userAgent
- "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.77 Safari/537.36"
課程大綱
- 評判標准
- RAIL評估模型
- 性能指標
- 體驗指標
- 指標數據采集
- 優化實戰
- 鏈路優化
- 編程優化
- 鏈路優化
- 鏈路階段分析
- 階段指標數據
- 各階段優化手段
- 案例分析和常用工具
- 編程優化
- 首屏渲染
- 懶加載功能組件
- 滾動加載分頁組件
- web worker計算
- Task切分
- 代碼分割與打包
- 前端開發架構優化
- 前端開發架構優化
- ES6 module+template
- web component
- 輕react或vue
- 微前端架構
課程官方博客:前端學堂
視頻教程:雲課堂視頻課程
評判標准
無規矩不成方圓,所以這里先說說評判標准。評判標准主要指的是用戶打開網頁、瀏覽網頁的體驗和感受。我們需要一種客觀的評估模型來統一量化用戶體驗的各個環節,這樣才能找到需要優化的方向,找到開發極致用戶體驗網頁的捷徑。
RAIL評估模型
RAIL 是一種以用戶為中心的性能模型。每個網絡應用均具有與其生命周期有關的四個不同方面,且這些方面以不同的方式影響着性能。以用戶為中心;最終目標不僅是讓您的網站在任何特定設備上都能運行很快,而是使用戶滿意。
- Response,立即響應用戶;在 100 毫秒以內確認用戶輸入,超過100ms建議加上動效或者loading,通過視覺沖擊減少用戶等待的焦慮。
- Animation,設置動畫或滾動時,在 10 毫秒以內生成幀。
- Idle,最大程度增加主線程的空閑時間。主線程空閑才能隨時都可以及時響應。
- Load,持續吸引用戶;在 1000 毫秒以內呈現交互內容。
讓用戶成為您的性能工作的中心。用戶花在網站上的大多數時間不是等待加載,而是在使用時等待響應。了解用戶如何評價性能延遲:
延遲與用戶反應 | |
---|---|
0 – 16 毫秒 | 流暢;人們特別擅長跟蹤運動,如果動畫不流暢,他們就會對運動心生反感。 用戶可以感知每秒渲染 60 幀的平滑動畫轉場。也就是每幀 16 毫秒(包括瀏覽器將新幀繪制到屏幕上所需的時間),留給應用大約 10 毫秒的時間來生成一幀。 |
0 – 100 毫秒 | 快,在此時間窗口內響應用戶操作,他們會覺得可以立即獲得結果。時間再長,操作與反應之間的連接就會中斷。 |
100 – 300 毫秒 | 可感覺慢,需要loading,用戶會遇到輕微可覺察的延遲。 |
300 – 1000 毫秒 | 慢,需要做loading和占位。在此窗口內,延遲感覺像是任務自然和持續發展的一部分。對於網絡上的大多數用戶,加載頁面或更改視圖代表着一個任務。 |
1000+ 毫秒 | 很慢,超過 1 秒,用戶的注意力將離開他們正在執行的任務。 |
10,000+ 毫秒 | 放棄,用戶感到失望,可能會放棄任務;之后他們或許不會再回來。 |
響應:在 100 毫秒以內響應
在用戶注意到滯后之前您有 100 毫秒的時間可以響應用戶輸入。這適用於大多數輸入,不管他們是在點擊按鈕、切換表單控件還是啟動動畫。但不適用於觸摸拖動或滾動。 如果您未響應,操作與反應之間的連接就會中斷。用戶會注意到。 盡管很明顯應立即響應用戶的操作,但這並不總是正確的做法。使用此 100 毫秒窗口執行其他開銷大的工作,但需要謹慎,以免妨礙用戶。如果可能,請在后台執行工作。 對於需要超過 500 毫秒才能完成的操作,請始終提供反饋機制,比如loading,進度條等。
動畫:在 10 毫秒內生成一幀
動畫不只是奇特的 UI 效果。例如,滾動和觸摸拖動就是動畫類型。 如果動畫幀率發生變化,您的用戶確實會注意到。您的目標就是每秒生成 60 幀,每一幀必須完成以下所有步驟:
從純粹的數學角度而言,每幀的預算約為 16 毫秒(1000 毫秒 / 60 幀 = 16.66 毫秒/幀)。 但因為瀏覽器需要花費時間將新幀繪制到屏幕上,只有 10 毫秒來執行代碼。 在像動畫一樣的高壓點中,關鍵是不論能不能做,什么都不要做,做最少的工作。 如果可能,請利用 100 毫秒響應預先計算開銷大的工作,這樣您就可以盡可能增加實現 60fps 的可能性。 如需了解詳細信息,請參閱渲染性能。
空閑:最大程度增加空閑時間
利用空閑時間完成推遲的工作。例如,盡可能減少預加載數據,以便您的應用快速加載,並利用空閑時間加載剩余數據。 推遲的工作應分成每個耗時約 50 毫秒的多個塊。如果用戶開始交互,優先級最高的事項是響應用戶。
要實現小於 100 毫秒的響應,應用必須在每 50 毫秒內將控制權返回給主線程,這樣應用就可以執行其像素管道、對用戶輸入作出反應,等等。以 50 毫秒塊工作既可以完成任務,又能確保及時的響應。
加載:在 1000 毫秒以內呈現內容
在 1 秒鍾內加載您的網站。否則,用戶的注意力會分散,他們處理任務的感覺會中斷。側重於優化關鍵渲染路徑以取消阻止渲染。 實際操作中,我們無需在 1 秒內加載所有內容以產生完整加載的感覺,而是啟用漸進式渲染和在后台執行一些工作,默認只加載和渲染首屏內容,將非首屏、非必需的加載推遲到空閑時間段處理。
關鍵 RAIL 指標匯總
要根據 RAIL 指標評估您的網站,請使用 Chrome DevTools Timeline 工具記錄用戶操作。然后根據這些關鍵 RAIL 指標檢查 Timeline 中的記錄時間。
RAIL 步驟 | 關鍵指標 | 用戶操作 |
---|---|---|
響應 | 輸入延遲時間(從點按到繪制)小於 100 毫秒。 | 用戶點按按鈕(例如打開導航)。 |
動畫 | 每個幀的工作(從 JS 到繪制)完成時間小於 16 毫秒。 | 用戶滾動頁面,拖動手指(例如,打開菜單)或看到動畫。 拖動時,應用的響應與手指位置有關(例如,拉動刷新、滑動輪播)。 此指標僅適用於拖動的持續階段,不適用於開始階段。 |
空閑 | 主線程 JS 工作分成不大於 50 毫秒的塊。 | 用戶沒有與頁面交互,但主線程應足夠用於處理下一個用戶輸入。 |
加載 | 頁面可以在 1000 毫秒內就緒。 | 用戶加載頁面並看到關鍵路徑內容。 |
這是Google工程師提出來的RAIL優化模型,在實際前端業務監控中,我們可以拆分成更多的數據指標進行統計分析。
性能和體驗數據指標
數據驅動業務開發,我們的目標是高性能和極致用戶體驗,那么我們首先需要制定符合我們目標的性能數據指標和體驗數據指標。 在制定數據指標之前,我們分析下頁面加載過程,我們分為這四個部分:
用戶體驗 | 描述 |
---|---|
它在發生嗎?happening | 網頁瀏覽順利開始了嗎?服務端有響應嗎? |
它是否有用?useful | 用戶是否能看到足夠的內容? |
它是否可用?usable | 用戶是否可以和頁面交互,還是頁面仍在忙於加載? |
它是否令人愉快的?idle | 交互是否流程和自然,沒有卡段或閃爍? |
性能指標:加載呈現又快又穩。加載到展現的性能指標和穩定性指標。
體驗指標:操作反應靈敏。點擊,滑動等交互響應及時,操作流暢,動畫運行流暢。
- 秒開率:頁面首屏加載時間小於1s的比例,也就是頁面加載到onload事件觸發時所消耗的時間。
- FP(first paint) 和 FCP(first content paint) 分別是指頁面首次繪制和首次內容繪制。FP(首次繪制)包括了任何用戶自定義的背景繪制,它是首先將像素繪制到屏幕的時刻。FCP(首次內容繪制)是瀏覽器將第一個 DOM 渲染到屏幕的時間。該指標報告了瀏覽器首次呈現任何文本、圖像、畫布或者 SVG 的時間。這兩個指標其實指示了我們通常所說的白屏時間。
- FMP(first meaningful paint)首次有意義繪制, 是頁面可用性的度量標准。因為很難有一個通用標准來指示所有的頁面當前時刻的渲染達是否到了有用的程度,所以當前並沒有制定標准。對於開發者,我們可以根據自己的頁面來確定那一部分是最重要的,然后度量這部分渲染出的時間作為FMP。
- TTFB(time to first byte, 首字節時間),是指從瀏覽器發起第一個請求到數據返回第一個字節所消耗的時間,這個時間包含了網絡時間,后端處理時間等等,可以作為一個鏈路數據綜合參考指標。
穩定性指標
- 資源錯誤:靜態資源加載錯誤,常見的就是404,資源地址不正確或者遠程服務有問題。
- JS報錯:頁面運行時拋出來的異常信息。比如變量未定義,函數報錯等等。
- Crash:頁面白屏不展示內容,很可能是頁面某個模塊報錯導致整個頁面不展示。
- 內存堆棧:監控頁面內存和堆棧使用情況,常見如頁面內存泄露等原因會直接導致APP閃退。
- 接口報錯:接口掛了,請求超時。或者接口返回了錯誤信息。或者接口返回數據錯誤,比如空數據,不符合預期。
- 交互延遲:用戶點擊后頁面沒有響應或者響應時間超過100ms,用戶感覺這次點擊操作是延遲的(可稱為無效點擊)。通過EventTiming API我們可以統計用戶交互操作后的瀏覽器響應時間。
- 卡頓:統計瀏覽器中執行時間超過 50 ms 的任務,都是 long task(Long tasks API ),可能會造成頁面卡頓。
- 滾動流暢性:滾動過程是否流暢,監測用戶開始操作到頁面開始滾動的時間差,按照前面的標准,小於100ms才會體驗流暢。
- 動畫流暢性:監測動畫開始到動畫結束,計算幀率FPS。按照前面的標准,每幀計算時間小於10ms才會體驗流暢。
- TTI(time to interactive, 可交互時間):指頁面已渲染出內容,同時可以響應用戶的輸入的時間。
- FID(First Input Delay),首次輸入延遲,從用戶看到頁面到第一次輸入的延遲,一般都是因為主線程阻塞,會導致響應慢。這個指標反映用戶對當前頁面的第一感覺,如果用戶很久沒有交互,說明首屏內容比較吸引人,或者用戶很快就切走了,說明對用戶沒有吸引力。
性能指標數據采集
介紹上面我們總結的性能和體驗指標如何准確有效的采集。
優化實戰
我們已經全面分析總結了評估頁面性能和用戶體驗的各個指標參數。那么怎么來優化呢?open signal官方提供了2018年2月份統計的全世界4G網絡覆蓋率和通信速率的統計分布圖如下,在目前移動互聯網的浪潮下,我們要利用好用戶終端設備的每個字節的流量。
當然頁面性能和體驗優化並不是一蹴而就的,需要不斷的研究、跟蹤,發現問題,解決問題。但是我們可以在一開始編寫業務代碼的時候就做的更好,做到極致。所以,關於優化實戰我們主要分為兩部分:加載渲染鏈路優化 和 編程代碼優化。
加載渲染鏈路優化
從訪問url到頁面呈現,整個加載和渲染鏈路可以做優化的思路。
加載鏈路:瀏覽器導航開始->檢查緩存->DNS->HTTP->解析
渲染鏈路:瀏覽器內核或者webview(對於ios區分wkwebview和早期版本的uiwebview)渲染流程
具體詳情參看下面這篇文章:
編程代碼優化
我們說的“快”,並不僅僅指瀏覽器器加載頁面快,就是常說的秒開率,一般指DomContentLoad時間。但是“快”其實包含更多的含義,除了前面說的瀏覽器加載快,還包含瀏覽器解析快(Javascript腳本發布時通常都會做代碼壓縮混淆,不僅是減少體積,也為了安全性),JS腳本編譯快(我們知道javascript在瀏覽器的javascript虛擬機【managed runtime environment for JavaScript,JavaScript托管運行時環境】中運行的,所以也需要編輯JS腳本成字節碼,才能運行),最后一個就是javascript執行快。
鏈路優化中,我們已經解決了JavaScript下載加速的問題,那么剩下的優化工作主要集中在優化瀏覽器解析、編譯並執行JS腳本。影響瀏覽器解析和執行JS腳本的因素主要是JS腳本的體積大小和代碼的復雜程度。所以編程代碼優化實踐主要是減少代碼的體積和按需降低代碼復雜度,實現瀏覽器解析快,JS腳本編譯快。
- 代碼體積大,加載就會耗時,而且占用cdn存儲資源和http請求資源,瀏覽器解析時暫用內存多,分析代碼耗時。
- 代碼復雜度高,代碼解析就比較耗時。如果依賴一些復雜的類庫,還要考慮庫的解析和執行時間。瀏覽器解析代碼會占用更多內存,使用堆棧更深,執行耗時。
優化策略:
- 首屏渲染與PRPL
- 懶加載組件
- 滾動加載分頁組件
- web worker
- task拆分
- 代碼分割與打包
- 項目架構優化
具體詳情參看下面這篇文章:前端極致性能體驗編碼框架優化
參考
- Can You Afford It?: Real-world Web Performance Budgets
- Progressive Performance
- Reducing JavaScript payloads with Tree-shaking
- Ouch, your JavaScript hurts!
- Fast & Resilient — Why carving out the “fast” path isn’t enough
- Web performance optimization with Webpack
- JavaScript Start-up Optimization
- The Impact Of Page Weight On Load Time
- Beyond The Bubble — Real-world Performance
- How To Think About Speed Tools
- Thinking PRPL
- navigation-timing
- the-cost-of-javascript
- learning-and-using-the-user-timing-api