日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 前端技术 > HTML >内容正文

HTML

前端性能优化实践 | 百度APP个人主页优化

發(fā)布時間:2024/10/12 HTML 99 豆豆
生活随笔 收集整理的這篇文章主要介紹了 前端性能优化实践 | 百度APP个人主页优化 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

性能是每個前端工程師都應(yīng)該關(guān)注的話題,通用的優(yōu)化手段已有許多文章和實踐,就不再贅述,本篇以百度 App 個人主頁為例,聊聊針對業(yè)務(wù)特點進(jìn)行的一些性能優(yōu)化實踐。適用于:傳統(tǒng)意義的優(yōu)化手段能用的都用了:打包拆包,縮減體積和 HTTP 請求數(shù)、CDN 和按需加載等,但性能方面仍不太理想。

01優(yōu)化三部曲

下面介紹下我們的優(yōu)化三部曲,這也是所有優(yōu)化項目的基本步驟:

  • 現(xiàn)狀摸底
  • 發(fā)現(xiàn)問題
  • 解決問題
  • 第一步:定義指標(biāo),建設(shè)報表

    優(yōu)秀方案的制定首先需要準(zhǔn)確的數(shù)據(jù)做支撐。

    一般來說,前端性能指標(biāo)包括 DOM ready、First Contentful Paint、白屏、首屏、用戶可操作時間、onload 時間等,在實際中需要結(jié)合業(yè)務(wù)本身的特點進(jìn)行定義,一般通用的指標(biāo)定義并不能體現(xiàn)用戶在當(dāng)前業(yè)務(wù)下的真實體驗。

    個人主頁是在百度 App 客戶端內(nèi)的 web 頁面,有 hybrid 版(使用 file 協(xié)議直接加載本地 HTML 和 JS、CSS)和 web 版(打開一個 web URL)兩種不同的打開方式。

    首先,我們了解一下個人主頁頁面的結(jié)構(gòu):

    頭部區(qū)域展示當(dāng)前作者的個人信息,tab 區(qū)域則是作者創(chuàng)作產(chǎn)生的內(nèi)容。頁面中所有數(shù)據(jù)均為異步獲取。

    打開個人主頁需要經(jīng)歷的過程可簡化成以下幾個:

    其中耗時可劃分為端(Native)耗時、網(wǎng)絡(luò)和 server 耗時、前端渲染耗時三大部分:

    根據(jù)以上過程,我們制定了定義指標(biāo)的原則:

    • 主頁頁面展現(xiàn)的用戶數(shù)據(jù),是頁面內(nèi) JS 請求數(shù)據(jù)后的異步渲染。因此首屏定義為:頭部區(qū)域 和 tab 列表第一屏數(shù)據(jù)渲染完成(用戶真正可見,也即用戶可操作時間)
    • 主頁是由 san 搭建的 SPA 頁面,HTML 上同步的 DOM并沒有真實內(nèi)容出現(xiàn),在首屏用戶數(shù)據(jù)返回之前,頁面均顯示為 loading 態(tài)。因此白屏的定義為:頁面 DOM掛載上內(nèi)容(用戶首次看到頁面不再空白的時間)
    • 由于在端內(nèi),iOS 和 安卓 onload 事件觸發(fā)的時機(jī)不同,iOS上資源加載會阻塞頁面渲染,因此主頁中針對 iOS 進(jìn)行了調(diào)整,使用 rAF 使 iOS 在 JS 開始執(zhí)行時即觸發(fā)onload,而安卓在首屏需要的圖片、jsonp 等資源全部 load 完成后觸發(fā),因此該項指標(biāo)主要用作輔助作用。

    在報表建設(shè)的過程中,結(jié)合主頁的業(yè)務(wù)形態(tài)(在 Android、iOS 雙端均有 hybrid 版和 web 版兩種)以及指標(biāo)定義的含義,對整個過程的階段盡可能細(xì)化,方式如下:

    • 將主頁的三種版本進(jìn)行分組打點:hybrid 版,hybrid 混合 web 版,web版。即可避免數(shù)據(jù)干擾,又可通過控制上線時間,來進(jìn)行實驗對比
    • 添加系統(tǒng)、端內(nèi)外、起始點作為篩選條件,排除不同的使用條件帶來的數(shù)據(jù)差異,有助于縮小范圍,定位分析
    • 根據(jù)主頁的執(zhí)行流程,將耗時流程細(xì)分,進(jìn)一步定位問題,整個階段細(xì)分為:端耗時(從點擊到解析頁面 head 頂部)、同步 HTML 內(nèi)各 JS引用階段耗時、數(shù)據(jù)請求耗時、頁面內(nèi)端能力及各組件生命周期到首屏耗時(耗時部分在實際優(yōu)化中逐步細(xì)化分析)

    最終得到每個階段的詳細(xì)劃分:

    補(bǔ)充說明

    • 端到端打點即以用戶進(jìn)行操作的時刻為起始點來記錄數(shù)據(jù),涵蓋了從用戶發(fā)起點擊操作開始到頁面完全展現(xiàn)之間的客戶端耗時、網(wǎng)絡(luò)耗時、server耗時、前端各個階段耗時的完整流程打點。 其中,起始時間戳由上一個頁面在用戶操作時進(jìn)行記錄,并透傳給個人主頁;前端在每次發(fā)起網(wǎng)絡(luò)請求時記錄當(dāng)前時間戳,接口的返回值中傳回后端處理接口的耗時,二者的差值即 HTTP 連接的耗時。本次采用前端計算上報、平臺展示的方案,打點前端控制靈活且迭代快。
    • 端耗時部分前期僅能計算從上一個頁面點擊到解析頁面頂部的整體時間。

    第二步:數(shù)據(jù)分析,提出優(yōu)化方向

    經(jīng)過第一步,拿到穩(wěn)定的數(shù)據(jù)及頁面各階段耗時,分析并提出解決方案。

    圖中性能數(shù)據(jù)可以看出主要耗時階段:端耗時、引入主 profile.js 到 js 內(nèi)部開始耗時、首屏接口耗時、頁面數(shù)據(jù)處理和渲染耗時,針對主要耗時階段,優(yōu)化分為以下幾個方面:

    • 針對端耗時,前端配合端查找優(yōu)化點
    • 針對首屏接口耗時,前端聯(lián)合 server 進(jìn)行接口優(yōu)化
    • 針對 JS 內(nèi)部耗時,前端進(jìn)行自身代碼優(yōu)化

    第三步:著手優(yōu)化,逐步完善

    主頁入口較多,需要兼容不同入口情況以及歷史遺留,個人主頁業(yè)務(wù)基本情況如下:
    1.頁面為 SPA 模式,但業(yè)務(wù)復(fù)雜,代碼總體積較大
    2.hybrid 版 首屏需要的資源由兩個接口返回,且兩個接口存在依賴,在前端串行執(zhí)行
    3.web 版頂部用戶數(shù)據(jù)使用同步數(shù)據(jù),依賴的 tab 接口與 hybrid 相同
    4.hybrid 版 的特點:

    • hybrid 版 與 web 版 使用不同方式編譯的同一套代碼,但 web 版上第一個接口是同步的,數(shù)據(jù)隨著 HTML 模板一起返回,而hybrid 中所有接口均是異步
    • 使用的場景更多
    • 采用 file 協(xié)議加載 HTML 模板,用 jsonp 的方式請求后端數(shù)據(jù)接口

    按照前端代碼、工程化、server 端、客戶端 native 框架四個方向分別針對性制定優(yōu)化方案,以下主要介紹前端可控的代碼和工程化兩個方面。

    02前端代碼優(yōu)化

    提前觸發(fā)iOS onload

    方法:使用 rAF 嵌套 setTimeout 提前觸發(fā) onload 事件,解決 iOS 資源加載阻塞頁面顯示的情況
    收益:用戶可見的首屏?xí)r間不受 load 阻塞

    減少首屏依賴

    首屏?xí)r間可反映出用戶對頁面速度的感受,首屏所依賴的行為越多,就意味著用戶需要等待的時間越長。因此,在性能優(yōu)化中需要盡可能地減少在首屏前執(zhí)行的操作、后置一些非必要的操作,可以在某種程度上提升用戶體驗。

    經(jīng)過一段時間的數(shù)據(jù)收集分析和代碼 review,我們發(fā)現(xiàn)一些可以改進(jìn)的地方:

  • 在首屏前的一段邏輯里,JS 初始化一些數(shù)據(jù)時一次性調(diào)用了多個 native 提供的方法(端能力),導(dǎo)致端能力執(zhí)行耗時 80 分位值遠(yuǎn)超理論值;
  • SPA 頁面的最外層組件 App 在首個接口的數(shù)據(jù)返回后才進(jìn)行掛載。對 web 版頁面來說,首個接口是同步的,因此 App在接口后掛載影響不大;但對使用場景更多的 hybrid 版來說,頁面的首屏至少需要兩個接口,而所有接口請求均為異步,首個接口返回之前足以處理很多頁面必要的邏輯,App的掛載時機(jī)就顯得非常不合適。
  • 頁面上埋了很多打點,除 pv外其他多是頁面上一些小組件的展現(xiàn)打點,在首屏之前頻繁發(fā)送打點請求擠占了首屏中圖片的加載時間。
  • 結(jié)合以上發(fā)現(xiàn),對代碼進(jìn)行了如下調(diào)整:

    • 調(diào)整與 native 端能力調(diào)用的執(zhí)行順序,首屏必要的留下,其他的后置,降低端能力執(zhí)行耗時
    • 優(yōu)化必要的代碼信息 (例如:個人主頁從頭用到尾的 runtime) 初始化邏輯
    • 最外層 App組件掛載不依賴接口數(shù)據(jù),頁面提前進(jìn)行初始化,接口數(shù)據(jù)并行請求,異步渲染
    • 調(diào)整代碼執(zhí)行邏輯,關(guān)鍵邏輯移至 store,提前執(zhí)行
    • 頁面內(nèi)部分打點等邏輯后置,減少頁面掛載執(zhí)行時間

    一波操作下來,獲得了 80 分位 100ms + 的收益。

    首屏接口合并

    上文有提到 hybrid 首屏需要在前端串行執(zhí)行兩個異步網(wǎng)絡(luò)接口。從統(tǒng)計到的性能數(shù)據(jù)上看,在調(diào)用接口到拿到接口數(shù)據(jù)的過程中,耗時最長的是建立網(wǎng)絡(luò)連接這個階段,兩個接口合并成一個接口,首屏?xí)r間上至少可以節(jié)省一次建立網(wǎng)絡(luò)連接的時間(個人主頁做到了 110ms+)。當(dāng)然,接口合并也需要考慮 server 端的平響,考慮可能會犧牲的一丟丟白屏?xí)r間。

    首屏接口前置

    作為一個標(biāo)準(zhǔn)的 SPA 頁面,個人主頁頁面上幾乎所有的邏輯都是在公共 js 加載完成之后才開始執(zhí)行,但 js 加載需要時間,尤其是首次加載、本地還沒有緩存時。

    hybrid 版本沒有同步接口,只能在 js 加載完成之后才發(fā)出首屏的第一個請求,因此 hybrid 的版本在這里還存在可優(yōu)化空間。

    已知現(xiàn)在主流瀏覽器可并行處理的請求通常默認(rèn)在 4~6 個,在加載 js 時去拿首屏需要的數(shù)據(jù)(jsonp),串行變并行,節(jié)省下來一份二者重疊的時間。

    首屏接口前置就做了這么一些事:
    hybrid 打包時內(nèi)聯(lián)了一個體積盡可能小的極簡代碼包,去取首屏第一個接口的數(shù)據(jù),完成后存入全局變量并以事件的形式派發(fā)出來。由于 iOS 部分場景中首次請求建立網(wǎng)絡(luò)連接的耗時較長,順便使用 native 端能力代替 jsonp,首屏接口前置中 iOS 收益在 260ms+,安卓 60ms 左右。

    工程化
    工程化上進(jìn)行的優(yōu)化主要是在打包上下功夫,打包影響加載 JS、CSS 等資源的 http 耗時,在相同的條件下,包體積越小、請求次數(shù)越少,資源加載速度就越快。

    打包和拆包

    JS 和 CSS 資源打包合并,但需要考慮打包文件過大,單個請求耗時太長,需要結(jié)合業(yè)務(wù)場景合理拆分代碼包。

    主流瀏覽器可并行處理的請求通常默認(rèn)在 4~6 個,可合理拆分資源包,利用并行請求縮減整體的響應(yīng)時間。

    通過合理劃分包來最大程度上利用瀏覽器緩存。鎖版本、保持每個小 bundle 未發(fā)生改變時哈希值穩(wěn)定,較大的 JS、CSS 和圖片等會被直接寫進(jìn)硬盤緩存。例如,個人主頁根據(jù)代碼的修改頻率把 js 包拆成體積差不多大小的三個,其中 vendors 是各種 npm 依賴,版本穩(wěn)定,通常不會發(fā)生改變。每次上線后用戶瀏覽器只需要從 CDN 上請求另外兩個代碼包,vendors 則使用上次還未過期的本地緩存。

    現(xiàn)代模式 (modern mode)

    通常,開發(fā)時我們使用 ES6 (ES2015+) 來編寫代碼,ES6 的新特性可以讓開發(fā)工作更便捷迅速但打包時需要用 Babel 進(jìn)行轉(zhuǎn)換來讓我們的代碼能運行在不支持 ES6 的瀏覽器上。轉(zhuǎn)換后的代碼會加入 polyfill,最直觀的感受就是代碼包體積增大。modern mode 在支持原生 ES6 的瀏覽器中,js 會通過 加載 ES 模塊 的 script type="module"加載,而在不支持的瀏覽器中使用 script nomodule來加載 babel 編譯后的版本,并且支持 ES 模塊的瀏覽器會忽略這種寫法。在支持 ES6 的瀏覽器上使用 ES6 的版本,代碼 bundle 體積更小、解析和執(zhí)行的速度更快,何樂而不為呢?
    從個人主頁收集到的數(shù)據(jù)顯示,目前已有 75% 的場景支持 modern mode,帶來的性能收益也是非常可觀:
    分類
    白屏(ms)
    首屏(ms)

    優(yōu)化效果總結(jié)
    優(yōu)化后 JS 初始化耗時減少,首屏數(shù)據(jù) jsonp 請求使用內(nèi)聯(lián)的極簡代碼包在頁面準(zhǔn)備完畢前就發(fā)出,在 jsonp 得到返回值前并行加載頁面需要的其他 CSS 和 JS 資源;App 掛載和頁面 runtime 初始化的時間提前,首屏數(shù)據(jù)回來后可以立馬處理并渲染數(shù)據(jù),而不被其他的一些操作占用寶貴的時間;打點等請求后置,首屏完畢前讓 JS 專注于數(shù)據(jù)和渲染,同時騰出帶寬加載圖片等用戶可見的資源。優(yōu)化后的流程可用下圖表示:

    03總結(jié)

    工欲善其事,必先利其器。在著手進(jìn)行優(yōu)化前,有大量的時間花在了選取數(shù)據(jù)參考點、收集數(shù)據(jù)上,通過反復(fù)的 code review、實驗、業(yè)務(wù)邏輯推敲來確保每個關(guān)鍵指標(biāo)反映的都是真實可信的數(shù)據(jù)。本文僅僅提供一種從數(shù)據(jù)著手的優(yōu)化點分析方法,列舉的優(yōu)化方法與實際業(yè)務(wù)密不可分,并不具有太強(qiáng)的普適性,希望能給大家在解決瓶頸的道路上帶來一點不一樣的思路。

    作者 @潘銘

    文章看完,還不過癮?
    更多精彩內(nèi)容歡迎關(guān)注百度開發(fā)者中心公眾號

    總結(jié)

    以上是生活随笔為你收集整理的前端性能优化实践 | 百度APP个人主页优化的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。