實踐指南-前端性能提升 270%

来源:https://www.cnblogs.com/jingdongkeji/archive/2023/08/10/17619666.html
-Advertisement-
Play Games

當我們疲於開發一個接一個的需求時,很容易忘記去關註網站的性能,到了某一個節點,猛地發現,隨著越來越多代碼的堆積,網站變得越來越慢。本文就是從這樣的一個背景出發,著手優化網站的前端性能,並總結出一套開發習慣,讓我們在日常開發時,也保持高性能,而不是又一次回過頭來優化性能。 ...


一、背景

當我們疲於開發一個接一個的需求時,很容易忘記去關註網站的性能,到了某一個節點,猛地發現,隨著越來越多代碼的堆積,網站變得越來越慢。

本文就是從這樣的一個背景出發,著手優化網站的前端性能,並總結出一套開發習慣,讓我們在日常開發時,也保持高性能,而不是又一次回過頭來優化性能。

指標名稱 優化前 優化後 提升
Lighthouse Performance 評分 29 81 279%
FCP(First Contentful Paint 首次內容繪製) 0.7s 0.7s
LCP(Largest Contentful Paint 最大內容繪製) 6.2s 2.5s 248%
TTI(Time to Interactive 可交互時間) 10.1s 2.1s 480%
Speed Index(速度指數) 5.6s 1.8 311%
TBT(Total Blocking Time 總阻塞時間) 820ms 120ms 683%

優化前後對比:

優化前後對比

二、優化前

接下來就是介紹下優化前我們要做哪些事件:

  1. 瞭解性能指標及測量工具

  2. 分析需要優化的地方

1. 瞭解測量工具及性能指標

一開始我們只是感受到網站的頁面打開時白屏時間較長,感覺性能是比較差的,那麼具體有哪些性能指標需要去關註呢?

這裡我使用的是 Chrome devtools 內置的Lighthouse,Lighthouse 是一種開源的自動化工具,用於提高 Web 應用程式的質量。

Lighthouse 會在一系列的測試下運行網頁,比如不同尺寸的設備和不同的網路速度。它還會檢查頁面對輔助功能指南的一致性,例如顏色對比度和 ARIA 最佳實踐。

打開 Chrome devtools Lighthouse 即可使用。

在比較短的時間內,Lighthouse 可以給出這樣一份報告。

這份報告從 5 個方面來分析頁面: 性能、輔助功能、最佳實踐、搜索引擎優化和 PWA。像性能方面,會給出一些常見的耗時統計。

優化前

1.1 Performance

Performance 評分統計,包括了以下指標:

1.1.1 FCP

FCP 測量在用戶導航到頁面後瀏覽器呈現第一段 DOM 內容所花費的時間。頁面上的圖像、非白色<canvas>元素和 SVG 被視為 DOM 內容;不包括 iframe 內的任何內容。

1.1.2 LCP

LCP 測量視口中最大的內容元素何時呈現到屏幕上。這近似於頁面的主要內容對用戶可見的時間。

需要註意的是 LCP 的計算是一個動態的過程,如下圖最後的圖片才是這個頁面中的最大內容繪製的元素。

lcp

1.1.3 TTI

TTI 測量頁面完全交互所需的時間。

TTI 是如何計算的呢,如下圖首先延時間軸正向搜索時長至少為 5 秒的安靜視窗(安靜視窗是指沒有長任務且不超過兩個正在處理的網路 get 請求),然後沿時間軸反向搜索安靜視窗之前的最後一個長任務,如果沒有找到長任務,則在 FCP 步驟停止執行,TTI 就是安靜視窗之前最後一個長任務的結束時間,如果沒有找到長任務的話,則與 FCP 值相同。

TTI

1.1.4 Speed Index

Speed Index 衡量頁面載入期間內容以視覺方式顯示的速度。Lighthouse 首先捕獲瀏覽器中頁面載入的視頻,並計算幀之間的視覺進度。

1.1.5 TBT

TBT 測量頁面被阻止響應用戶輸入(例如滑鼠點擊、屏幕點擊或鍵盤按下)的總時間。

通過添加 First Contentful Paint 和 Time to Interactive 之間所有長任務的阻塞部分來計算總和。任何執行時間超過 50 毫秒的任務都是長任務。

50 毫秒後的時間量是阻塞部分。例如,如果 Lighthouse 檢測到一個 70 毫秒長的任務,則阻塞部分將為 20 毫秒。

如下圖淡紅色區域的時間總和就是這個頁面的 TBT 分數。

TBT

1.2 最佳實踐

用於檢測 Web 應用程式整體代碼健康狀況,包括是否包含文檔類型、圖片寬高比是否正確等等。

1.3 SEO

用於檢測搜索引擎對網頁內容的理解程度。

2. 分析需要優化的地方

瞭解了關鍵的性能指標後,就可以測量看看當前網站的性能了,

上面看到綜合評分是非常低的,Lighthouse 給出了應該從哪些地方開始優化的建議。

2.1 Performance

性能優化建議主要包括以下幾點:

  • 減少未使用的 JS;

  • 合理使用圖片的格式,webp 或者 avif 更快;

  • 延遲載入不在視圖的圖片;

  • JS 壓縮;

  • 圖片的尺寸大小應該適當;

  • 減少未使用的 CSS。

性能優化建議

Lighthouse 診斷出的網站存在的問題:

  • 需要載入的資源太多太大,有 147 個請求,合計 11mb;

  • 有 40 個靜態資源的緩存只有 1 小時

  • 滾動事件沒有添加標記{passive: true}),導致需要等待偵聽器完成執行後再滾動頁面;

  • 圖像元素沒有設置明確的寬度和高度;

  • JS 文件太多,主線程工作量太大、JS 執行時間太長;

存在的問題

2.2 最佳實踐

最佳實踐方面有以下問題:

  • 圖片的解析度太低,清晰度不夠;

  • 沒有設置 CSP 策略。

最佳實踐的問題

2.3 SEO

SEO 有以下問題:

  • 沒有 meta description;

  • 圖片沒有 alt 屬性;

  • robots.txt 是無效的。

SEO的問題

三、優化 Performance

根據上面 Lighthouse 報告,捋一捋項目中影響性能最大的因素,包括以下幾點:

  • 體積太大,達 11mb;

  • 圖片太大,圖片格式也有影響。

1. 體積優化

1.1 代碼壓縮

檢查是否還有壓縮空間,或者有無工具庫未壓縮的。

1.2 代碼分包

通過 webpack-bundle-analyzer 插件分析包體積,將一些大的 npm 包和 runtimeChunk 獨立分包,減小包體積。

1.3 組件按需載入

React.lazy + Suspense 封裝懶載入組件,路由級組件引入懶載入組件。
同時使用骨架屏作為懶載入的兜底組件,可以讓用戶感知載入更快。
在滑鼠移入導航欄時預載入路由組件,可以加快頁面展示。

1.4 工具庫按需載入

通過 import('xx').then(xx) 按需載入工具庫。

1.5 靜態資源上傳 CDN

項目內有一些 json 文件存儲的靜態數據,這部分文件上傳至 CDN,改為 fetch 的方式按需引入。

1.6 刪除不需要的資源

檢查項目中引入的 mf、npm 資源,將沒有使用到的刪除。

1.7 避免重覆的 npm 包引入

發現業務組件庫通過 npm 引入的原子組件庫,而項目本身又是通過 mf 引入的原子組件庫,相對於引入了 2 遍原子組件庫。

這時就需要改造業務組件庫,也改成用 mf 的方法引入。

1.8 避免 esm 依賴嵌套

因為 webpack 的按需載入是通過 import、export 來標記的,因此想要一個好的按需載入的效果,就需要避免依賴嵌套的問題。

1.9 圖標按需載入

原子組件庫 mf 暴露的方式會導致只用了 1 個 icon,就會載入組件庫下所有 icon 對應的 chunk,導致資源浪費。

新建一個 icon 的 npm 包用於 icon 的按需引入。

1.10 小結

通過以上優化手段,體積從 11.7mb 降低至 1.1mb,降低 10.6 倍。

優化前:

優化前

優化後:

優化後

2. 圖片優化

1.1 圖片懶載入

對非首屏的圖片採用圖片懶載入策略。

1.2 圖片尺寸

使用圖片時,設置圖片的合理尺寸。

1.3 圖片格式設置

優先使用 webp 格式圖片。

四、優化最佳實踐

1. 設置 CSP 策略

2. 設置合理的圖片的解析度

優化項目內的圖片解析度。

五、優化 SEO

1. meta description、keywords 優化

詳細的 meta description、keywords 可以加快 SEO。

<meta name="keywords" content="xx" /> <meta name="description" content="xx" />



2. 圖片加上 alt 屬性

<img src="smiley.gif" alt="Smiley face" />



六、優化前後對比

再來回顧下前後對比:

優化前,明顯的感知白屏時間長:

優化前

優化後,在清緩存的情況下也能實現秒開:

優化後

整體性能提升 270%:

優化前後對比

七、性能監控

為了在後續的迭代過程中,保持高性能,引入內部前端監控平臺 -燭龍,可視化的監控前端性能。

第一步,載入 cdn 插件:

<script
  defer
  src="https://h5static.m.jd.com/act/jd-jssdk/latest/jd-jssdk.min.js"
></script>



第二步,在入口文件中,初始化 cdn 插件:

useEffect(() => {
  // 初始化測速組件,在這裡可以打開一些控制的開關,如是否上報介面
  if (IS_PROD) {
    // @ts-ignore
    jmfe.profilerInit({
      flag: xxx, // 這是應用ID,需要先在燭龍申請應用
      autoReport: true,
      autoAddStaticReport: true,
      autoAddApiReport: true,
      autoAddImageReport: false, // 支持所有圖片上報,如果圖片多,切記關閉,否則存在性能問題
      performanceReportTime: 8000,
      profilingRate: 1,
    })
  }
}, [])



第三步,查看監控數據:

在燭龍平臺,小工具性能評分達 96分:

查看監控數據

第四步,新增告警,實時監控

燭龍平臺支持多維度的告警的服務,增加性能指標相關的告警,在性能異動時,及時發現問題,優化性能。

小結

本文詳細介紹了一個前端項目優化的詳細過程,從優化前的問題分析,到具體的優化措施,最終實現了前端性能提升了近 3 倍。同時也將性能指標落到監控平臺,實現可視化的監控前端性能指標。

希望能對你有所幫助,感謝閱讀~

參考資料

作者:京東零售 唐姣

來源:京東雲開發者社區


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 本文分享自華為雲社區《openGauss資料庫在CentOS上的安裝實踐》,作者:Gauss小松鼠 。 1.安裝前準備 安裝資料庫前先要有已安裝centOS 7.6的伺服器+資料庫安裝包。 首先找小伙伴申請了華為雲ECS伺服器安裝好了OS,這裡使用的是x86_64+centos。 華為雲伺服器現在可 ...
  • 根據 2023 年的 Stack Overflow 調研 (https://survey.stackoverflow.co/2023/) ,Postgres 已經取代 MySQL 成為最受敬仰和渴望 (the most admired, desired) 的資料庫。 隨著 Postgres 的發展勢 ...
  • 一、升級webview版本 (1). 下載需要更新的Webview apk。如果不能翻牆可以用下載好的版本(相容32/64位):Webview-115.0.5790.138 (2). 在路徑\aosp\external\chromium-webview\prebuilt\下替換arm或arm64架構 ...
  • # 前言 提到爬蟲可能大多都會想到python,其實爬蟲的實現並不限制任何語言。 下麵我們就使用js來實現,後端為express,前端為vue3。 # 實現功能 話不多說,先看結果: ![image](https://img2023.cnblogs.com/blog/1769804/202308/1 ...
  • 這裡給大家分享我在網上總結出來的一些知識,希望對大家有所幫助 最近,我剛剛完成了一個閱讀器的txt文件閱讀功能,但在處理大文件時,遇到了文本內容過多導致瀏覽器崩潰的問題。 一般情況下,沒有任何樣式渲染時不會出現什麼問題,15MB的文件大約會有3秒的空白時間。 <div id="content"></ ...
  • ## css3 瀑布流佈局遇見截斷下一列展示後半截現象 - 註:css3實現瀑布流佈局簡直不要太香~~~~~ ## 場景-在uniapp項目中 ### 當瀑布流佈局column-grap:10px 相鄰兩列之間的間隙為10px,column-count:2,2列展示時,就出現了截斷問題,如下圖: ! ...
  • 7月27號下午2點 New 操作符做了什麼: 1. 創建一個新的空對象。 2. 將這個新對象的原型指向構造函數的原型。 3. 將構造函數的this指向這個新對象。 4. 根據構造函數返回類型作判斷,如果是值類型,返回newObj。如果是引用類型,就返回這個引用類型的對象 Vue2 數組push、sh ...
  • # CSS 選擇器權重 聲明:本文參考來源於[MDN CSS 優先順序](https://developer.mozilla.org/zh-CN/docs/Web/CSS/Specificity)(80%)和B站尚矽谷的[課程](https://m.bilibili.com/video/BV1p84y ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...