性能優(yōu)化調(diào)研系列文章
為什么要進行前端性能優(yōu)化?
用戶體驗-> 用戶留存 -> 用戶轉(zhuǎn)化 -> 收益轉(zhuǎn)化
Google在開發(fā)者文檔《為什么性能優(yōu)化如此重要》 從四個角度闡述了性能的重要性
Performance is about retaining users(用戶留存)
加載時長和頁面放棄關(guān)系
正向例子:
- Pinterest reduced perceived wait times by 40% and this increased search engine traffic and sign-ups by 15%.
- COOK 的轉(zhuǎn)化率提升 7%、丟出率下降 7%,且每次會話瀏覽頁數(shù)增加 10%,得益于其頁面平均加載時間減少 850 毫秒
反面例子:
Performance is about improving conversions (轉(zhuǎn)化率)
對于Mobify來說,首頁加載速度每降低100毫秒,基于會話的轉(zhuǎn)化率就提高了1.11%,平均每年的收入增加了近380,000美元。此外,結(jié)帳頁面加載速度降低100毫秒,基于會話的轉(zhuǎn)化率提高了1.55%,這反過來又使年均收入增長了近$ 530,000
AutoAnything 發(fā)現(xiàn)當他們減少一半的頁面加載時間,會提升12%-13%的成交額。
Performance is about user experience(用戶體驗)
- 性能是好的用戶體驗的基礎(chǔ)。
- 現(xiàn)代web應(yīng)用,前端承載了越來越多的邏輯和職責,導致應(yīng)用越來越大(相反,真實用戶的網(wǎng)絡(luò)和設(shè)備性能卻千差萬別)
其中引用的一篇《流式傳輸會延遲智能手機用戶的心理負擔:愛立信移動報告》非常有意思。
調(diào)研報告顯示: 視頻加載的延遲會使用戶的心率平均上升37%,等同于看恐怖電影或者參加數(shù)學考試一樣給人帶來的壓力(恐怖電影 沒啥感覺,數(shù)據(jù)考試可能大家都有比較深的感觸~)
Performance is about people(以人為中心)
- 減少你站點加載的資源大小,不要沒到月底,流量套餐就用完了,或者被限速?。。。ㄍ瑯右矔楣緶p少CDN支付的費用哦~)
- 醫(yī)院,診所和危機中心等公共資源具有在線資源,這些資源為用戶提供了危機期間所需的重要和特定的信息。盡管設(shè)計對于在緊張時刻有效地展示重要信息至關(guān)重要,但快速提供這些信息的重要性不可低估
以上基本上對Google在開發(fā)者文檔《為什么性能優(yōu)化如此重要》的總結(jié)。
性能優(yōu)化指標
上面基本上說明了性能優(yōu)化的重要性,但是怎么確定我們的應(yīng)用性能好與壞呢? 用戶體驗是最直接以及最終的要得到的效果,但是體驗(感覺)又是一個抽象,主觀意識,非量化的方式。
在傳統(tǒng)的web頁面中(jsp、或者smarty)服務(wù)端模板渲染的應(yīng)用中(通常也不會包含很多的前端異步渲染請求、渲染邏輯)關(guān)注的可能是onload DOMContentLoaded時機。
然后在今天2020年的節(jié)點上 顯然這些已經(jīng)無法真正測量頁面的性能了。我們需要合理的定義性能指標(Performance Metrics)
Google 根據(jù)一些原則定義了一些通用的指標

關(guān)于指標定義:
- google的性能指標也在不斷的調(diào)整
- google的一些指標不一定對所有的業(yè)務(wù)場景都適用
- 我們可能需要定義一些自定義的性能指標
這些指標如何測量呢?
兩種方式
- 實驗室數(shù)據(jù): 在一個穩(wěn)定可控的環(huán)境中使用工具模擬頁面加載過程,采集相關(guān)指標。
- 線上真實用戶數(shù)據(jù): 采集線上用戶真實的加載和交互過程中的指標。
這兩種方案,在沒有設(shè)定背景的情況下,并沒有優(yōu)劣之分。在團隊發(fā)展的不同階段,項目的不同階段,具體問題的發(fā)生的背景下,去選擇合適的方案。長期來看線上數(shù)據(jù)采集是一個剛需,因為我們最終要交付的對象是真實的用戶,而用戶的真實使用環(huán)境(網(wǎng)絡(luò)、性能等)我們無法揣測。
-
2020-7月份 安卓聯(lián)網(wǎng)方式 分布(數(shù)據(jù)來源:百度流量研究院) 百度統(tǒng)計數(shù)據(jù) 網(wǎng)絡(luò)連接方式分布
-
2020-7月份 IOS聯(lián)網(wǎng)方式 分布(數(shù)據(jù)來源:百度流量研究院) image.png
實驗室采集工具:
線上采集(構(gòu)建線上性能監(jiān)控體系)
使用lighthouse進行性能測試
通過lightouse大致測量你的頁面的性能表現(xiàn),觀察各個性能指標的得分。
// 使用命令行
lighthouse https://www.oklink.com/ --view --emulated-factor-form='mobile' --output-path='oklink.com.html'
lighthouse 移動端默認使用的網(wǎng)絡(luò)預設(shè)是, 在chrome的 devtool中有個網(wǎng)絡(luò)限流,選項是:Fast 3G就是這個配置
Latency: 150ms
Throughput: 1.6Mbps down / 750 Kbps up.
Packet loss: none.
這樣的話,模擬移動端的最大下載速度就是 200k。
FCP
Fisrt Contentfull Paint 指標測量了從開始加載到第一次繪制任何的text(包含引用加載中字頭文件的text)、image(包括背景圖)非白色的canvas、svg元素的時間。
含義
衡量的維度:Is it happening? Did the navigation start successfully? Has the server responded?
FCP 和 FP 的區(qū)別
- First Paint 發(fā)生在導航階段完成之后的第一次渲染. 不包含默認背景色(比如默認背景色的body)但是包含非默認背景色(設(shè)置背景色的body)
- Fisrt Contentfull Paint 發(fā)生在導航階段完成之后,第一次繪制任何的text、image(包括背景圖)非白色的canvas、svg元素、包含引用加載中字頭文件的text。
- FP 在 FCP 之前或者同時觸發(fā)。
- 觸發(fā)FP的第一次繪制 不一定觸發(fā)FCP,觸發(fā)FCP的條件一定能觸發(fā)FP。
參考demo:https://github.com/webaifei/performance-demos/blob/master/src/templates/fp.html#L16&L23
怎么計算
- 使用工具: lighthouse 、pageSpeed等
- 使用web-vitals
- 使用Paint Timing API
多快算好
目前lighthouse V6 移動測評的時候, 給出評分規(guī)則,小于2.3s,會給出90+的分數(shù)。
LCP
Largest contentfull paint 指標上報可視窗口內(nèi),最大的圖片或者文本繪制時間。
含義
衡量的維度: Is it useful? Has enough content rendered that users can engage with it?
計算邏輯
哪些元素被被考慮作為最大元素
- img
- svg中的image
- 一個元素 使用background-image (但是不是使用 CSS gradient)
- 塊級元素(包含了 文本內(nèi)容或者是行內(nèi)文本元素)
- 使用了poster屬性的video元素
元素的大小如何計算?
- 只計算用戶可視區(qū)域范圍的可見元素:如果元素設(shè)置了
visibility opacity display不可見 是不會計算在內(nèi)的。 - 如果一個元素一部分超出了可視區(qū)域,或者被父容器使用overflow等屬性隱藏掉,則這部分不可見的部分不會計算在內(nèi)。
- 對于image圖片元素,有兩個大小:圖片真實的大小和在可視區(qū)域內(nèi)的展示的大小,上報時候取兩者的最小值進行計算。
- 對于text文本元素,只考慮能包含文本的最小矩形區(qū)域。
- 對于所有的元素,任何通過css設(shè)置的margin、padding、border都不會計算在內(nèi)。
參考demo: https://github.com/webaifei/performance-demos/blob/master/src/templates/lcp.html
什么時候會上報LCP?
因為web 頁面加載是分階段的,在渲染的過程中,largest element 可能會變化。 所以Largest Contentful Paint API 會在largest element發(fā)生變化的變化的時候 不斷的觸發(fā)上報。
具體哪些情況下 最大元素可能發(fā)生變化
- 新添加DOM元素(元素屬于最大內(nèi)容的備選項)
- 刪除一個DOM元素(元素屬于最大內(nèi)容的備選項)
- 修改DOM元素的屬性:opacity display visibility, src(元素屬于最大內(nèi)容的備選項)
注意: 改變元素的大小和位置 不會再次觸發(fā)LCP 上報,對于圖片資源在加載完成之后 修改大小和位置不會再次觸發(fā)LCP上報。
什么時候停止上報?
- 用戶在頁面上發(fā)生交互(因為用戶操作經(jīng)常會修改元素的可見性)
怎么計算
- 使用工具: lighthouse 、pageSpeed等
- 使用web-vitals
- 使用Paint Timing API
多快算好
目前lighthouse 移動評分 低于2.5s,被認為是一個較好的表現(xiàn),給出了90+的分數(shù)。
TTI
Time to interactive 指標測量從頁面開始加載到頁面依賴的主要的子資源加載完畢并且能夠快速可靠的響應(yīng)用戶的輸入
含義
衡量的維度:Is it usable? Can users interact with the page, or is it busy?
計算邏輯
TTI 定義上比較抽象,那么是怎么測量:主要的子資源加載完畢并且能夠快速可靠的響應(yīng)用戶的輸入
- 從FCP時間點開始
- 向前(時間線上其實是指之后的時間)立即搜索一個長達5秒鐘的靜默窗口
- 從找到的靜默窗口之前,向后(時間線上其實是指之前的時間)搜索最近的一次long task ,如果沒有找到就停在FCP發(fā)生的時間點。
- TTI 就是靜默窗口之前的最近一次long task的結(jié)束時間,如果沒有找到long task 那就是FCP的時間點。
5秒鐘的靜默窗口被定義為:
1. 期間沒有l(wèi)ong task運行
2. 沒有超過兩個的進行中的網(wǎng)絡(luò)請求
<figcaption style="margin-top: 5px; text-align: center; color: #888; font-size: 14px;">TTI</figcaption>
如何計算
- 使用lighthouse 等
- 使用 google提供的tti-polyfill
參考demo:https://github.com/webaifei/performance-demos/blob/master/src/templates/tti.html
多快算好
google建議為了提供良好的用戶體驗,在移動設(shè)備上,TTI 要盡量少于5s
目前lighthouse 移動評分 5s的TTI 得分為77分。
優(yōu)化手段
待補充。
TBT
Total block time 指標統(tǒng)計了從FCP開始到TTI結(jié)束之間的所有long task超過50ms部分的時間總和。
含義
衡量的維度:Is it usable? Can users interact with the page, or is it busy?
怎么計算
假設(shè)下面是FCP -> TTI 之間的所有運行的tasks那么總的TBT=200+40+105
多快算好
google 建議TBT 時間<300ms 目前lighthouse 移動評分 低于300ms,會給出90+的分數(shù)。
知道了這些指標的含義和計算規(guī)則,我們就可以開始優(yōu)化那些得分較低的指標了。但是在這之前,先來了解下《瀏覽器的加載、渲染過程》,會對我們的性能優(yōu)化工作有非常大的幫助。
