網(wǎng)站性能對(duì)于用戶體驗(yàn)、轉(zhuǎn)化率和流失率、SEO 排名等至關(guān)重要,http://Trip.com 主要用戶來(lái)自海外,對(duì)網(wǎng)站訪問性能有更高的要求。能夠快速響應(yīng)的網(wǎng)站通常" />

国产成人精品无码青草_亚洲国产美女精品久久久久∴_欧美人与鲁交大毛片免费_国产果冻豆传媒麻婆精东

15158846557 在線咨詢 在線咨詢
15158846557 在線咨詢
所在位置: 首頁(yè) > 營(yíng)銷資訊 > 網(wǎng)站運(yùn)營(yíng) > 提升50分,Trip.com 機(jī)票基于 PageSpeed 的前端性能優(yōu)化實(shí)踐

提升50分,Trip.com 機(jī)票基于 PageSpeed 的前端性能優(yōu)化實(shí)踐

時(shí)間:2023-08-16 15:00:01 | 來(lái)源:網(wǎng)站運(yùn)營(yíng)

時(shí)間:2023-08-16 15:00:01 來(lái)源:網(wǎng)站運(yùn)營(yíng)

提升50分,Trip.com 機(jī)票基于 PageSpeed 的前端性能優(yōu)化實(shí)踐:

前言




網(wǎng)站性能對(duì)于用戶體驗(yàn)、轉(zhuǎn)化率和流失率、SEO 排名等至關(guān)重要,http://Trip.com 主要用戶來(lái)自海外,對(duì)網(wǎng)站訪問性能有更高的要求。能夠快速響應(yīng)的網(wǎng)站通常有機(jī)會(huì)獲取更多流量,并為用戶帶來(lái)更好的體驗(yàn)。




近期我們對(duì) http://Trip.com 機(jī)票站點(diǎn)做了一版性能優(yōu)化,通過對(duì)主要 landing 頁(yè)面進(jìn)行系統(tǒng)優(yōu)化,將頁(yè)面的 PageSpeed 評(píng)分從原本 30 左右提升到 80 分以上。




這里分享在優(yōu)化過程中的一些經(jīng)驗(yàn),將從性能指標(biāo)、性能測(cè)量與優(yōu)化實(shí)踐方案三個(gè)方面展開,期望可以給大家提供一些思路和參考。




一、性能指標(biāo)




1.1 性能指標(biāo)的發(fā)展與演進(jìn)




針對(duì)線上項(xiàng)目做性能優(yōu)化,首先需要有一個(gè)確定的可量化的評(píng)判標(biāo)準(zhǔn),用來(lái)判斷優(yōu)化工作是否有效。




1.1.1 傳統(tǒng)的性能指標(biāo)以及它們存在的問題




傳統(tǒng)的性能指標(biāo)最典型的是 DOM Ready 時(shí)間和頁(yè)面加載時(shí)間(load time):前者指的是初始 HTML 文檔完全加載和解析完成的時(shí)間,一般是通過 DOMContentLoaded 事件獲得;后者指的是整個(gè)頁(yè)面所需的資源(包括腳本、樣式、圖片等)加載完成的時(shí)間,通過全局的 load 事件獲取。




普遍存在的問題是:在早先前后端耦合的時(shí)代,通過在服務(wù)端使用模板引擎渲染出 HTML,能比較好地反映網(wǎng)站性能。后來(lái)前端領(lǐng)域的迅猛發(fā)展,尤其是隨著客戶端渲染方案的盛行,以及各種動(dòng)態(tài)技術(shù)的大量運(yùn)用,這兩個(gè)指標(biāo)差不多已經(jīng)失去其原有的意義,無(wú)法準(zhǔn)確反映性能。




1.1.2 指標(biāo)和用戶實(shí)際感受之間的差異




再往后,采用瀏覽器提供的 Navigation Timing API ,通過 performance.timing 獲取從頁(yè)面開始加載到結(jié)束全過程中不同階段的時(shí)間點(diǎn)。用這種方法,開發(fā)者可從多個(gè)維度去定義一些指標(biāo),通過簡(jiǎn)單的差值計(jì)算得到數(shù)據(jù),并以此去監(jiān)控站點(diǎn)性能。




比如在攜程現(xiàn)有的UBT(User Behavior Tracking)中基于 Timing API 主要定義了以下 7 個(gè)關(guān)鍵指標(biāo) DNS、Connect、Request、Response、Blank、Domready 和 Onload。







1.1.3 以用戶為中心的性能指標(biāo)




上述這些指標(biāo)更側(cè)重于技術(shù)角度,跟用戶在實(shí)際使用過程中的真實(shí)感受會(huì)有偏差。以此為標(biāo)準(zhǔn)去做性能優(yōu)化的話,很可能面臨的一種場(chǎng)景是,已經(jīng)把某些特定指標(biāo)如加載時(shí)間的數(shù)值大幅減少,但用戶體驗(yàn)仍然不佳?;诖?,Chrome 團(tuán)隊(duì)和 W3C 性能工作組推出了一組 以用戶為中心的性能指標(biāo),從用戶角度更好地去評(píng)判頁(yè)面性能。




這些指標(biāo)主要包含:







1.2 指標(biāo)介紹




接下來(lái)簡(jiǎn)單介紹下主要性能指標(biāo)的具體定義:




1.2.1 FCP




FCP 指標(biāo)測(cè)量的是頁(yè)面從開始加載到頁(yè)面內(nèi)容的任何部分在屏幕上完成渲染的時(shí)間?!皟?nèi)容”可以是文本、圖像(包括背景圖像)、<svg> 元素或非白色的 <canvas> 元素。




這個(gè)指標(biāo)回答了一個(gè)用戶問題,應(yīng)用正在運(yùn)行嗎




還有一個(gè)從名稱上很接近的指標(biāo),F(xiàn)P (首次繪制),它們之間的區(qū)別如下:







1.2.2 LCP




這個(gè)指標(biāo)對(duì)應(yīng)的關(guān)鍵用戶問題是,內(nèi)容是否有用,即頁(yè)面是否已經(jīng)呈現(xiàn)出對(duì)用戶有用的內(nèi)容。




早先有過一些類似的指標(biāo)比如 FMP (首次有效繪制),但有效繪制的定義是什么通常很難解釋,而且算法容易出錯(cuò)。




相反,最大內(nèi)容繪制的定義簡(jiǎn)單明了,這里的“內(nèi)容”和 FCP 中的定義基本一致,指的是在可視區(qū)域內(nèi)的最大圖片或文本塊完成渲染的時(shí)間。




元素大小指的是內(nèi)容占據(jù)的面積大小,即 size = width * height ,不包含邊距邊框。




大多數(shù)情況下,頁(yè)面上最吸引用戶的內(nèi)容往往就是最大元素,可以視為頁(yè)面中最重要的內(nèi)容。




1.2.3 TTI




可交互時(shí)間,對(duì)應(yīng)的用戶關(guān)注點(diǎn)是可以使用嗎




早期,關(guān)于可交互時(shí)間一直并沒有一個(gè)清晰明確的定義。刀耕火種的時(shí)代,開發(fā)者通過自定義時(shí)間節(jié)點(diǎn),并在代碼中埋點(diǎn)來(lái)獲取相關(guān)數(shù)據(jù)。




比如通過在 setTimeout 中放一個(gè)任務(wù)獲取執(zhí)行時(shí)間點(diǎn),再計(jì)算到頁(yè)面開始加載的差值。




setTimeout(function() { tti = new Date() - navigationStartTime}, 0)


或者,在使用 React 等特定框架時(shí),通過向主要組件的生命周期函數(shù) componentDidMount 埋點(diǎn),并以此計(jì)算 TTI 時(shí)間。




而在 Lighthouse 中,可交互時(shí)間指標(biāo)有了更通用、標(biāo)準(zhǔn)化的定義。TTI 應(yīng)從 FCP 時(shí)間點(diǎn)開始沿時(shí)間軸查找,如果出現(xiàn) 5 秒的靜默窗口(沒有長(zhǎng)任務(wù)并且不超過 2 個(gè)正在處理的 GET 請(qǐng)求),那么最后一個(gè)長(zhǎng)任務(wù)執(zhí)行結(jié)束的時(shí)間點(diǎn)即為可交互時(shí)間。




長(zhǎng)任務(wù)指的是執(zhí)行時(shí)間超過 50 ms 的任務(wù)。




定義的根據(jù)是,主線程上若不存在導(dǎo)致阻塞狀態(tài)的長(zhǎng)任務(wù),則視為此時(shí)已可以響應(yīng)用戶交互。







1.2.4 TBT




TBT 和 TTI 是一對(duì)配套指標(biāo),用于衡量在頁(yè)面可交互之前的阻塞程度。TBT 是指在 FCP 和 TTI 之間所有長(zhǎng)任務(wù)超過 50ms 的部分的時(shí)間總和(注意不是長(zhǎng)任務(wù)的時(shí)間總和)。







1.2.5 CLS




累積布局偏移指標(biāo)用于衡量頁(yè)面視覺穩(wěn)定性。單次布局偏移分?jǐn)?shù)是影響分?jǐn)?shù)(不穩(wěn)定區(qū)域占可視區(qū)域的百分比)與距離分?jǐn)?shù)(不穩(wěn)定元素最大位移距離占比)的乘積。CLS 指標(biāo)本身一直在不斷進(jìn)化 ,便于更加準(zhǔn)確地去衡量布局偏移對(duì)用戶的影響。




1.2.6 其他







二、性能測(cè)量




了解需要關(guān)注的性能指標(biāo)之后,面臨的問題是應(yīng)該怎么樣去有效測(cè)量呢?




性能測(cè)量分兩種類型,實(shí)驗(yàn)室測(cè)量與現(xiàn)場(chǎng)測(cè)量(真實(shí)用戶監(jiān)控)。部分指標(biāo)只能通過實(shí)驗(yàn)室測(cè)量,或是只能現(xiàn)場(chǎng)測(cè)量。




2.1 實(shí)驗(yàn)室測(cè)量




實(shí)驗(yàn)室測(cè)量指的是在一個(gè)受控環(huán)境下,使用預(yù)定義的硬件設(shè)備和網(wǎng)絡(luò)配置等規(guī)則去運(yùn)行網(wǎng)站頁(yè)面,進(jìn)行性能數(shù)據(jù)采集,提取性能指標(biāo)。目前最流行的工具是 Google 提供的 Lighthouse ,最初作為一個(gè)獨(dú)立瀏覽器擴(kuò)展程序推出,需開發(fā)者自行安裝(支持 Firefox),目前已經(jīng)集成到 Chrome DevTools 。Lighthouse 不僅僅是一個(gè)性能測(cè)量工具,除此之外還提供 PWA 、SEO 、可訪問性、最佳實(shí)踐等審計(jì)報(bào)告。




在做性能優(yōu)化的時(shí)候,如何有效評(píng)估優(yōu)化方案的效果是一個(gè)問題,由于還未發(fā)布到線上環(huán)境無(wú)法采集真實(shí)用戶性能數(shù)據(jù),這時(shí)使用工具進(jìn)行實(shí)驗(yàn)室測(cè)量就顯得尤為重要。




同時(shí),Lighthouse 提供開源 CI 工具 Lighthouse CI ,開發(fā)者能自行部署服務(wù),并集成到現(xiàn)有的 CI 體系中。




2.2 現(xiàn)場(chǎng)測(cè)量




現(xiàn)場(chǎng)測(cè)量,也稱真實(shí)用戶監(jiān)控(RUM),即實(shí)時(shí)采集真實(shí)用戶性能數(shù)據(jù)。




實(shí)驗(yàn)室測(cè)量的是在一系列特定條件下的性能數(shù)據(jù),不能完全反映現(xiàn)實(shí)世界中用戶的真實(shí)情況?,F(xiàn)場(chǎng)測(cè)量的優(yōu)勢(shì)在于樣板量足夠大,包羅各種不同設(shè)備不同網(wǎng)絡(luò)環(huán)境下的用戶性能數(shù)據(jù),從統(tǒng)計(jì)上更能反映真實(shí)性能情況。缺點(diǎn)是,現(xiàn)場(chǎng)測(cè)量需基于瀏覽器提供的性能 Web API ,受限于當(dāng)前設(shè)備采集到的數(shù)據(jù)不及實(shí)驗(yàn)室測(cè)量豐富。




2.3 定量評(píng)估的問題與方案




定量評(píng)估每一項(xiàng)優(yōu)化方案的效果并不容易,原因包括環(huán)境差異問題,分?jǐn)?shù)計(jì)算問題等。




解決方案是:







三、性能優(yōu)化方案




確定優(yōu)化方向,并且有了可定量評(píng)估的方案之后,接下來(lái)要做的就是如何實(shí)施具體的優(yōu)化方案。




性能優(yōu)化是一個(gè)老生常談,同時(shí)與時(shí)俱進(jìn)的主題。早期大名鼎鼎的 雅虎 35 條性能軍規(guī) 到現(xiàn)在大部分仍然適用,另一方面隨著技術(shù)的發(fā)展,基于上述以用戶為中心的性能指標(biāo),能更有針對(duì)性地實(shí)施方案。同時(shí)借助 Lighthouse 工具,能更有效地評(píng)估具體方案效果。




我們的 Web 應(yīng)用基于 React 技術(shù)棧,以下部分內(nèi)容基于 React 來(lái)進(jìn)行闡述。




3.1 減小包體積




Web 應(yīng)用與傳統(tǒng)客戶端應(yīng)用很不同的一點(diǎn)在于,應(yīng)用所需資源文件都是存放在遠(yuǎn)端服務(wù)器上的,每次訪問都有相當(dāng)大的性能開銷是用于資源獲取。




如何讓資源高效加載成了一個(gè)非常重要的問題,其中最重要的一環(huán)是網(wǎng)絡(luò)傳輸,專用 CDN 服務(wù)器包含就近訪問,資源緩存和傳輸體積壓縮等功能,能節(jié)省大量網(wǎng)絡(luò)傳輸時(shí)間,這是基礎(chǔ)設(shè)施的角度。




從應(yīng)用開發(fā)者的角度,首先可以對(duì)應(yīng)用包體積進(jìn)行瘦身。




包體積的問題主要表現(xiàn)為:







3.1.1 冗余代碼的優(yōu)化




冗余代碼的產(chǎn)生有多種,比如是已經(jīng)廢棄不用但仍然被導(dǎo)入的功能模塊,或者是在做 AB 實(shí)驗(yàn)完成后未完全移除的版本代碼等。




借助相關(guān)工具,比如 Webpack 插件 webpack-bundle-analyzer 能用一種可視化的方式呈現(xiàn)每個(gè)包的具體模塊信息,體積大小、依賴關(guān)系一目了然。而 Chrome DevTools Coverage 工具能分析出運(yùn)行過程中文件(腳本和樣式)的使用情況,可作為參考更好地針對(duì)性地瘦身優(yōu)化。




3.1.2 重復(fù)代碼的優(yōu)化




重復(fù)代碼很大一部分是實(shí)現(xiàn)相似功能的過程中,直接復(fù)制粘貼一方代碼進(jìn)行修改導(dǎo)致,借助 jsinspect 可以檢測(cè)到相同和相似代碼,然后進(jìn)行合理抽象。還有一種情況是,依賴 NPM 包提供多種方式的代碼,比如 dist 目錄下的打包代碼,lib 目錄下的 CommonJS 代碼,和 es 目錄下的 ES Modules 代碼。若是不小心在不同地方引入不同方式的包,就等同于是引入重復(fù)功能模塊。更甚一步,在跨團(tuán)隊(duì)合作中依賴包只提供打包版本,也會(huì)出現(xiàn) babel polyfill 代碼多次重復(fù),并且無(wú)從分析。解決方案是制定統(tǒng)一的標(biāo)準(zhǔn),推薦 NPM 包都提供僅 babel 編譯不打包版本。




3.1.3 類庫(kù)開銷的優(yōu)化




在類庫(kù)的使用上同樣需要注意,比如僅使用一兩個(gè)方法就引入整個(gè) lodash 庫(kù),推薦做法是按需引入,不用改變寫法加入 babel-plugin-lodash 這類插件就能在代碼構(gòu)建時(shí)轉(zhuǎn)換。另外一種情況是引入 moment 這類體積較大的庫(kù)用作時(shí)間處理與格式化,可以視實(shí)際情況采用體積更小的替代品。對(duì)于更簡(jiǎn)單的需求,則完全可以基于原生 API 自行實(shí)現(xiàn)封裝一些方法。




3.1.4 圖片文件的優(yōu)化




未經(jīng)優(yōu)化的圖片可高達(dá)幾百 KB ,應(yīng)在保證圖片清晰度的情況下合理壓縮體積。




另一方面,為現(xiàn)代瀏覽器提供有更高效壓縮算法的圖片格式,相比傳統(tǒng)的 PNG 和 JPG 格式,WebP 在同等質(zhì)量下有更小的體積,注意做好降級(jí)方案。




3.1.5 更激進(jìn)的做法




關(guān)于編譯構(gòu)建,傳統(tǒng)做法為了瀏覽器兼容性引入很多非必要的 polyfill ,解決方案是提供一個(gè)動(dòng)態(tài) polyfill 腳本,根據(jù)當(dāng)前客戶端提供不同內(nèi)容的 polyfill 。另一方面,現(xiàn)代瀏覽器已經(jīng)支持越來(lái)越多的 ES6+ 語(yǔ)法特性,針對(duì)這部分用戶可提供 ES6+ 版本的代碼,并使用 ES Modules 格式,從而大幅減小包體積。




3.2 優(yōu)化資源加載




做好包體積優(yōu)化能節(jié)省網(wǎng)絡(luò)傳輸時(shí)間,以及一部分代碼執(zhí)行時(shí)間,但更重要的是讓資源有效加載,可從資源加載順序和優(yōu)先級(jí)方面著手。




3.2.1 Resource Hints




為了使頁(yè)面可以快速加載,我們基于 PRPL 模式 進(jìn)行優(yōu)化。PRPL 是四個(gè)詞的首字母縮寫,分別代表:







首先,我們需要優(yōu)化關(guān)鍵路徑資源,頁(yè)面中要呈現(xiàn)的內(nèi)容很多,但不是所有內(nèi)容都需要第一時(shí)間呈現(xiàn),應(yīng)優(yōu)先呈現(xiàn)最重要的內(nèi)容。瀏覽器并不知道哪些資源是最重要的,基于 Resource Hints 可以告訴瀏覽器資源優(yōu)先級(jí)。常用的有以下幾類:







在使用過程需要注意:







3.2.2 Service Worker




使用 Service worker 緩存預(yù)載資源,對(duì)后續(xù)訪問會(huì)有極大的性能提升,能節(jié)省大量網(wǎng)路傳輸開銷。




在項(xiàng)目中推薦采用 Google 提供的 Workbox 庫(kù),可以通過配置的方式對(duì)不同類型資源應(yīng)用不同緩存策略。




Service Worker 帶來(lái)的優(yōu)化效果不能從 PageSpeed Insights 網(wǎng)站上的分?jǐn)?shù)直接體現(xiàn),因?yàn)?PageSpeed 總是單次分?jǐn)?shù)并且不使用緩存。




3.2.3 優(yōu)化加載第三方腳本




應(yīng)用依賴的第三方腳本通常會(huì)減慢頁(yè)面加載速度,一般采用以下方式:按需加載和延遲加載。




按需加載




需用戶交互才用到的功能模塊應(yīng)按需加載。舉個(gè)例子,用戶登錄時(shí)要調(diào)用一個(gè)第三方驗(yàn)證模塊,就沒必要在頁(yè)面一開始就引入該腳本,在用戶執(zhí)行登錄操作時(shí)引入更合理。




延遲加載




像是 Google analysis 和合作商營(yíng)銷等第三方日志埋點(diǎn)腳本,由于業(yè)務(wù)需要無(wú)法移除,加載后占用大量性能資源。




由于這類腳本和應(yīng)用沒有依賴關(guān)系,可使用 defer script 延遲腳本的解析執(zhí)行。更進(jìn)一步,延遲到在可交互時(shí)間之后加載就基本不會(huì)有任何影響。







3.3 組件懶加載




可視區(qū)域之外的內(nèi)容和需要用戶交互時(shí)才呈現(xiàn)的組件,都可采用懶加載,保證頁(yè)面首要內(nèi)容快速呈現(xiàn)。




要做懶加載,首先需要合理定義拆分點(diǎn)進(jìn)行代碼分割,然后基于動(dòng)態(tài)導(dǎo)入和 React.lazy 即可實(shí)現(xiàn)。




對(duì)于大部分點(diǎn)擊觸發(fā)的組件來(lái)說,這樣已經(jīng)足夠,但針對(duì)頁(yè)面底部可視區(qū)域之外需常規(guī)滾動(dòng)查看的內(nèi)容,還要做一些額外的工作。可以自行封裝實(shí)現(xiàn)一個(gè)組件,在內(nèi)部進(jìn)行判斷內(nèi)容是否可視,并監(jiān)聽 scroll 事件重新渲染。




實(shí)際中,我們結(jié)合 react-lazyload 和 @loadable/component 實(shí)現(xiàn)所需功能,如下:




import React from 'react';import loadable from '@loadable/component';import LazyLoad from 'react-lazyload';const LazyComponent = loadable(() => import(/* webpackChunkName: "home_lazy" */ './LazyComponent'));export function HomePage() { return ( <> <MainComponent /> <LazyLoad> <LazyComponent /> </LazyLoad> </> );)}


懶加載可能導(dǎo)致懶加載組件自身體驗(yàn)下降,可對(duì)用戶比較頻繁使用的組件進(jìn)行預(yù)加載。




過度拆分可能會(huì)產(chǎn)生很多體積很小的包,可適當(dāng)?shù)剡M(jìn)行合并。借助 webpack magic comment ,配置相同 chunk name 即可合并打包。




import loadable from '@loadable/component';export const SortLayer = loadable(() => import(/* webpackChunkName: "depart_select_layer" */ './SortLayer'));export const StopLayer = loadable(() => import(/* webpackChunkName: "depart_select_layer" */ './StopLayer'));export const TimeLayer = loadable(() => import(/* webpackChunkName: "depart_select_layer" */ './TimeLayer'));


3.4 優(yōu)化渲染方式




3.4.1 服務(wù)端渲染




CSR (客戶端渲染)的最大問題在于受用戶環(huán)境影響太大,一方面是網(wǎng)絡(luò)層面腳本文件的加載,一方面是瀏覽器的執(zhí)行效率,不同環(huán)境下差異很大。




SSR (服務(wù)端渲染)則能解決這個(gè)問題,直出 HTML 能快速呈現(xiàn)頁(yè)面主要內(nèi)容,能很好地改善 FCP 和 LCP 指標(biāo)。




SSR 的優(yōu)勢(shì)相對(duì) CSR 主要有兩點(diǎn):







實(shí)際上,大部分時(shí)候都是結(jié)合二者,針對(duì)首屏采用服務(wù)端渲染,讓用戶更快看到內(nèi)容,其他仍使用客戶端渲染的模式,減輕服務(wù)器壓力,畢竟將大量用戶的渲染任務(wù)轉(zhuǎn)移到服務(wù)端會(huì)是一筆不小的開銷。這時(shí),結(jié)合緩存機(jī)制可以大幅節(jié)省渲染時(shí)間。




3.4.2 預(yù)渲染




基于構(gòu)建時(shí)的預(yù)渲染,是使用 webpack 和 babel 等工具提前生成對(duì)應(yīng)的 HTML 以及引用的腳步和樣式文件。還有一種方式是基于運(yùn)行時(shí)的,使用 headless 瀏覽器。但預(yù)渲染并不適用于有大量動(dòng)態(tài)內(nèi)容的頁(yè)面。




實(shí)際應(yīng)用場(chǎng)景是針對(duì)信息展示的內(nèi)容頁(yè)面。




3.5 優(yōu)化長(zhǎng)任務(wù)




Long Task (長(zhǎng)任務(wù))的定義是執(zhí)行時(shí)間超過 50 ms 的任務(wù)。我們知道,JavaScript 是單進(jìn)程單線程的模型,主線程上一旦有耗時(shí)長(zhǎng)的任務(wù)存在時(shí),就會(huì)造成阻塞,無(wú)法響應(yīng)用戶輸入。




Long Task 跟 Lighthouse 中的兩個(gè)重要性能指標(biāo) TTI 和 TBT 息息相關(guān),而這兩個(gè)指標(biāo)占比為 40% ,可以說優(yōu)化好 Long Task 能大幅提升頁(yè)面性能。




Long Task 可借助對(duì)應(yīng)的 Long Task Web API 進(jìn)行監(jiān)控,開發(fā)過程中則使用 Chrome DevTools Performance 面板進(jìn)行查看和調(diào)試。需要注意的是,實(shí)際用戶尤其是移動(dòng)端的用戶環(huán)境通常不夠樂觀,調(diào)試過程應(yīng)適當(dāng)調(diào)低硬件配置和網(wǎng)絡(luò)速度,模擬大部分用戶的實(shí)際使用情況,發(fā)現(xiàn)并優(yōu)化更多的 Long Task 。




任務(wù)類型有多種,除了最常見的腳本執(zhí)行之外,還包括腳本解析編譯、HTML 解析、CSS 解析、布局、渲染等。腳本執(zhí)行是長(zhǎng)任務(wù)的主要表現(xiàn)形式,因此著重說明在 JavaScript 執(zhí)行上的一些優(yōu)化方式:







3.5.1 requestIdleCallback API




針對(duì)一些不重要的任務(wù)比如埋點(diǎn)日志可以直接丟到 requestIdleCallback 中,瀏覽器會(huì)在空閑時(shí)間執(zhí)行。在不支持的環(huán)境可使用 shim ,基于 setTimeout 實(shí)現(xiàn)近似的功能。




庫(kù) idlize 中封裝了一些非常實(shí)用的幫助函數(shù),使用這些方法可把任務(wù)延遲到需要的時(shí)候再執(zhí)行。




3.5.2 Web Worker




如果項(xiàng)目中確實(shí)存在比較復(fù)雜的計(jì)算,可啟動(dòng) Web Worker 單獨(dú)另開一個(gè)線程來(lái)計(jì)算,并使用 message 通信。




3.5.3 記憶函數(shù)




如果一個(gè)函數(shù)被大量調(diào)用,合理運(yùn)用記憶函數(shù)一個(gè)很好的選擇,有大量的庫(kù)可供我們選擇,也可以根據(jù)使用場(chǎng)景自行實(shí)現(xiàn)。




3.5.4 Debounce 和 Throttle




針對(duì) input change 和 scroll 等可能頻繁觸發(fā)的事件,結(jié)合 Debounce 或 Throttle 避免無(wú)節(jié)制地調(diào)用。




3.6 React 性能優(yōu)化




在 React 框架使用上有一些性能優(yōu)化的實(shí)踐,常用的有:







最后說明一點(diǎn),僅在必要的時(shí)候進(jìn)行性能優(yōu)化,大部分情況下無(wú)需考慮,保持簡(jiǎn)潔和可維護(hù)性更重要,而且濫用方法反而損害性能。




3.7 減少布局偏移




如何調(diào)試監(jiān)控




使用對(duì)應(yīng)的 Layout Instability API 可收集用戶的布局偏移數(shù)據(jù)。




在開發(fā)調(diào)試中,Layout Shift 同樣可以使用 Chrome DevTools Performance 進(jìn)行分析,能查看每一次布局偏移的分?jǐn)?shù),進(jìn)行針對(duì)性優(yōu)化。




常用的優(yōu)化方案







預(yù)留空間可減少其他頁(yè)面元素的偏移,比如出現(xiàn)在最頂部的廣告位,在數(shù)據(jù)還未獲取到的時(shí)候預(yù)先設(shè)置好一個(gè)容器,避免后續(xù)大幅偏移。




針對(duì)整頁(yè)動(dòng)態(tài)的內(nèi)容,使用骨架屏是一種很好的模式,業(yè)界已有不少成熟方案可自動(dòng)生成。




設(shè)置圖片寬高,可保證瀏覽器在加載圖片過程中始終能分配正確的空間大小。




四、總結(jié)反思




借助上文中提到的性能測(cè)量方式,我們逐步實(shí)施優(yōu)化方案并發(fā)布上線,經(jīng)過近兩個(gè)月斷斷續(xù)續(xù)的時(shí)間,最終讓性能分?jǐn)?shù)穩(wěn)定在 80 分以上。







性能優(yōu)化也適用于二八定律,優(yōu)化方式很多,簡(jiǎn)單堆砌疊加使用很可能適得其反。不同場(chǎng)景下的優(yōu)化方案千差萬(wàn)別,關(guān)鍵在于找準(zhǔn)最核心的問題。




以上僅提供一些思路作為參考,部分方案對(duì)特定指標(biāo)效果很好,部分方案不會(huì)反映到指標(biāo)分?jǐn)?shù),但有助提升用戶體驗(yàn)。再者,指標(biāo)衡量的是單個(gè)頁(yè)面速度,而作為開發(fā)者還應(yīng)考慮到后續(xù)頁(yè)面,從應(yīng)用維度去平衡,真正從用戶角度考慮。




【作者簡(jiǎn)介】

Patrick,攜程資深前端開發(fā)工程師,專注于前端工程化和性能優(yōu)化。

關(guān)鍵詞:性能,實(shí)踐,提升

74
73
25
news

版權(quán)所有? 億企邦 1997-2025 保留一切法律許可權(quán)利。

為了最佳展示效果,本站不支持IE9及以下版本的瀏覽器,建議您使用谷歌Chrome瀏覽器。 點(diǎn)擊下載Chrome瀏覽器
關(guān)閉