BI 數據可視化平臺建設(3)—首頁性能提升實踐

作者: vivo 互聯網大數據團隊- Wang Lei

本文是vivo互聯網大數據團隊《BI 數據可視化平臺建設》系列文章第3篇。

隨著越來越多代碼的堆積,平臺的運行加載性能也在逐步下降,在不同程度上極大地影響了用戶體驗,從而導致用戶流失。本文就是從這樣的一個背景出發,通過對BI數據可視化平臺的一系列的性能優化實踐,給大家系統性闡述首頁性能優化的核心策略,并探討在日常開發中如何實現長效性能保障。

往期系列文章:

  1. BI 數據可視化平臺建設(1)—交叉表組件演變實戰

  2. BI 數據可視化平臺建設(2)—篩選器組件升級實踐

文章太長?1分鐘看圖抓住核心觀點👇

圖片

一、背景

隨著業務的拓展和用戶數量的激增,平臺經歷了多個周期的快速迭代,整體功能場景也越發復雜的。在快速迭代的過程中,我們很容易忽略平臺的性能,到了某一個節點,猛地發現,隨著越來越多代碼的堆積,平臺的運行加載性能也在逐步下降,在不同程度上極大地影響了用戶體驗,從而導致用戶流失。本文就是從這樣的一個背景出發,通過對BI數據可視化平臺的一系列的性能優化實踐,給大家分享一下如何提升首頁性能的思路,并且讓我們在日常開發中,如何持續保持高性能,而不是又一次回過頭來優化性能。本文主要給大家介紹一平臺在進行首頁性能提升的一些實踐經驗。

二、了解性能指標

2.1 用戶體驗核心指標

衡量一個 Web 頁面的體驗和質量有非常多的指標,根據頁面加載流程可以將指標分成三大類:

  • 文檔加載相關(TTFB、DCL等)

  • 內容呈現相關(LCP、FCP、FMP 等)

  • 交互響應相關(INP、FPS 等)

針對這么多的性能指標,Google 提出了網站用戶體驗的三大核心指標 (LCP INP CLS),分別用來衡量用戶感知的加載速度、量化網頁首次互交互的感受、衡量網頁視覺的穩定性:

圖片

圖片來源:https://web.dev/

2.2 平臺度量指標

但是在實際規劃平臺性能度量體系時,我們可以根據自身的業務和需求進行自定義,針對數據可視化平臺來說,我們更看重用戶感知的加載速度,如何讓用戶快速看到數據可視化內容是我們首頁性能優化的關鍵,因此我們性能指標主要以文檔加載和內容呈現為主,這里我們以 TTFB、FCP、LCP 作為我們首頁性能的度量指標,它們涵蓋了網絡請求到頁面主要內容加載的過程:

網絡請求過程(網絡響應衡量指標 TTFB):

圖片

TTFB 主要指的是以下請求階段耗時的總和:

  • 重定向時間

  • Service Worker 啟動時間(如果有)

  • DNS 查找

  • 連接和 TLS 協商

  • 請求,直到響應的第一個字節到達

頁面主要內容加載過程(內容呈現衡量指標 FCP、LCP):

圖片

圖片來源:https://web.dev/

  • TTFB(Time to First Byte ):

它主要測量的是在網絡請求階段中,從請求資源到響應的第一個字節到達所經過的時間,這有助于識別 Web 服務器因速度過慢而無法響應請求。由于 TTFB 發生在指標 FCP(First Contentful Paint ) 和 LCP(Largest Contentful Paint)之前,因此希望服務器能夠快速地響應導航請求。一般來說,大多數網站都應盡量將 TTFB 控制在 0.8秒 以內,且超過75%以上PV 達到該范圍。

圖片

圖片來源:https://web.dev/

  • FCP(First Contentful Paint):

它用于標記網頁加載過程中用戶可以在屏幕上看到的第一個元素所用的時間。元素主要是指文本、圖片(包括背景圖片)、SVG 或 Canvas。可以用于衡量用戶感知的加載速度。為了提供良好的用戶體驗,網站的 FCP 最好不要超過 1.8 秒,且確保超過75%以上PV 達到該范圍。

圖片

圖片來源:https://web.dev/

  • LCP(Largest Contentful Paint):

它用于標記網頁加載過程中加載了網頁主要內容的時間點。可以用于衡量用戶感知的加載速度,也是Google 提出的度量用戶體驗的三大核心指標之一。為了提供良好的用戶體驗,網站的 LCP 最好控制在 2.5 秒 以內,且確保超過75%以上PV 達到該范圍。

圖片

圖片來源:https://web.dev/

三、首頁性能現狀

**背景:**性能問題主要是由于前期開發人力有限、功能快速迭代等原因,導致代碼質量和可維護性較差,積累下的技術債務。

(1)平臺性能指標分析:LCP (首屏平均耗時) 高達3.3s,遠高于Google LCP衡量的標準(2.5s)。

圖片

(2)通過Lighthouse工具進行性能分析,性能得分較低,各項性能指標都處于不及格的水平。

圖片

四、分析性能問題

4.1 通過Network面板分析

圖片

從Network面板上,可以分析得出加載過程中存在以下幾類問題:

  • 入口文件體積太大,加載耗時長,阻塞其他資源加載

  • 低優先級資源阻塞了高優先級資源加載

  • 微前端子應用等非首屏依賴資源沒有進行異步加載

  • 網絡傳輸協議還處于HTTP1.1,傳輸效率低

  • 接口請求傳輸的數據體過大,存在大量冗余數據

4.2 通過Performance面板分析

圖片

從 Performance 面板上,可以分析得出加載過程中存在以下幾類問題:

  • FPS 長時間出現紅色條形,表示幀速率下降得太低,可能出現動畫延遲卡頓等問題

  • CPU 資源占用率過高,可能出現性能問題

  • 主線程存在多個 Long Task(長任務),阻塞了頁面加載渲染

4.3 通過Lighthouse工具分析

圖片

通過 Lighthouse 工具,可以分析得出加載過程中存在以下的問題:

  • 大量 Long Task 阻塞了主線程工作

  • 存在阻塞渲染的低優先級資源

  • DOM節點數過多,增加了內存占用,樣式計算用時延長,并產生高昂的布局重排成本

  • 圖片資源不是最優壓縮效果的格式

  • 存在大量未使用的CSS和JS文件代碼

五、優化實踐

5.1 優化方向 (時間和空間)

通過上述的問題分析,我們可以分析出資源加載渲染耗時 以及瀏覽器性能資源占有 都有可能導致頁面卡頓緩慢,影響用戶體驗,因此可以從耗時和資源占用兩方面來進行性能優化,也可以理解成時間和空間的優化。

5.2 時間優化 (網絡耗時、加載耗時、渲染耗時等)

(1)網絡傳輸耗時優化

網絡傳輸耗時優化主要可以從 緩存策略、傳輸協議、資源預加載預解析、CDN 等幾個方向進行。本次優化主要是通過網絡傳輸升級、資源預加載、請求性能優化等方面來講解一下。

  • 網絡傳輸協議升級,由 HTTP/1.1 升級至 HTTP/2.0 版本,通過 HTTP/2.0 多路復用的特性解決了請求并發數限制的問題,同時二進制傳輸和頭部壓縮等特性也提高了網絡傳輸的效率。

  • 刪除資源預加載(Preload),減少首頁非關鍵資源的預加載處理。通過加載瀑布流可以看到,這里提前加載了多個非首屏關鍵資源的字體文件,且文件體積高達 1.8MB,阻塞了首屏關鍵資源的加載解析。所以我們需要根據資源的優先級,合理的使用 Preload(預加載)和 Prefetch(預解析)。

  • 請求性能優化,降低請求響應耗時。通過Network面板可以看到,首頁依賴的主要接口返回的數據體在沒壓縮前高達 3.1 MB,這里我們對請求內容進行了分析,通過異步請求、減少非關鍵的冗余數據等處理將傳輸數據體積降低到了 500KB 內。除了減少數據傳輸量,我們還可以通過請求合并,利用緩存等減少通信次數來進行請求性能優化。

(2)資源加載耗時優化

資源加載耗時優化可以從 代碼壓縮、代碼分包、組件、工具庫、ICON等按需加載等幾個方向進行。主要是通過優化體積來減少資源加載耗時,從而提升首屏性能。

  • 首先通過 webpack-bundle-analyzer 插件對包體積進行分析,可以看到 chunk-vendors.js 文件體積較大,同時還存在依賴嵌套等問題,導致資源加載緩慢。本次優化我們通過代碼分包、資源按需加載,圖片格式優化等措施,減少了資源體積, chunk-vendors.js 文件也從 2.3MB 降低到 480KB。下面我們通過幾個具體示例進行講解:

    對 Echarts 、Ant-Design-Vue-1.x ICON等UI工具庫進行按需加載。

    // 優化前 在入口文件進行全量的同步加載
    import * as echarts from ‘echarts/core’;
    import { XXXChart } from ‘echarts/charts’;
    import { XXXComponent } from ‘echarts/components’;
    import { CanvasRenderer } from ‘echarts/renderers’;

    echarts.use([XXXChart, XXXComponent, CanvasRenderer]);

    // 優化后 根據使用場景進行按需加載
    async function initEcharts(chartType){
    const echarts = await import(‘echarts/core’);
    const { XXXChart} = await import(‘echarts/charts’);
    const { XXXComponent } = await import(‘echarts/components’);
    const { CanvasRenderer } = await import(‘echarts/renderers’);
    echarts.use([XXXChart, XXXComponent, CanvasRenderer]);
    }

由于歷史需求迭代原因,我們對 Ant-Design-Vue-1.x 進行了二次定制開發,這也導致了ICON全量引入,我們這里使用的方案是重定向到本地文件來進行控制 ,使用 alias 將 @ant-design/icons/lib/dist 指向項目中的 antdIcon.js,然后在 antdIcon.js 文件中按需導出即可,通過按需加載,ICON引入體積從 500K+ 降低到 30K+

// vue.config.js alias配置
resolve: {alias: {'@ant-design/icons/lib/dist$': path.resolve(\_\_dirname, './src/plugins/antdIcons.js'),}
}// src/plugins/antdIcons.js
export { default as CheckCircleOutline } from '@ant-design/icons/lib/outline/CheckCircleOutline';
export { default as CheckCircleFill } from '@ant-design/icons/lib/fill/CheckCircleFill';
  • 檢查刪除冗余依賴,避免重復npm包引入;隨著平臺長期的發展迭代,或多或少都會存在冗余的 mf、npm 資源,同時我們在對微前端子應用的包體積進行分析時,發現子應用通過 npm 引入的Echarts,而主應用本身也引入相同的庫,相對于引入了2 遍 Echarts,這個時候我們改造了子應用的依賴引入方式,通過傳參的方式將Echarts實例傳遞給子應用,避免重復引入和加載相同資源。

    //主應用 通過props傳遞依賴
    import { start, loadMicroApp, prefetchApps } from ‘qiankun’;

    export default {
    name: ‘MicroWidgetReact’,
    methods: {
    async loadMicroApp(){
    const echarts=awaitthis.echarts = await this.echarts=awaitthis.initEcharts();
    this.microApp = loadMicroApp({
    name: `xxx`,
    props: {
    …props,
    $echarts: $echarts,
    },
    });
    },
    },
    };

    //子應用配置 externals 并且外鏈依賴加上 ignore 屬性(這是自定義的屬性,非標準屬性)

圖片

5.3 空間優化 (CPU 占用、內存占用、本地緩存等)

我們在做性能優化的時候,很多情況下都會依賴時間換空間、或者空間換時間等方式,這里需要根據項目的實際情況做出取舍,選擇相對合適的一種方案去進行優化。資源占用常見的優化方式包括:

  • 代碼優化:精簡和優化 JavaScript 和 CSS 代碼,避免使用過多的循環和遞歸操作,減少對 CPU 的占用。

  • 避免內存泄漏:定期檢查并優化內存使用,避免出現內存泄漏問題,可以使用瀏覽器的開發者工具進行內存分析。

  • 圖片懶加載:延遲加載圖片,只有當圖片進入可視區域時再加載,減少內存占用。

  • 數據本地存儲:使用瀏覽器提供的本地存儲功能(如LocalStorage或IndexedDB),將一些數據緩存到本地,減少對網絡請求的依賴,提高性能。

  • 使用 Web Workers:將一些耗時的任務放到 Web Workers 中執行,減輕主線程的負擔,從而減少 CPU 占用。

  • 使用服務端渲染:使用服務端渲染技術,減少客戶端的計算壓力,提高頁面加載速度。

  • 使用資源壓縮:對 JavaScript、CSS、圖片等資源進行壓縮,減小文件大小,降低網絡傳輸和內存占用。

本次我們主要使用了 Web Workers 和 數據解綁 (Object.freeze) 等方式進行空間優化,減少了CPU和內存的占用。通過 Web Workers 將需要復雜計算任務放到 Worker 線程,避免阻塞其他首頁渲染任務,釋放主線程資源,實現單線程到多線程。但是這里要注意,過多的使用 Web Workers 有時候反而會導致資源的過度占用,因為 Web Workers 本身也會占用一定的內存資源,而 Workers 之間的通信和數據同步也可能會帶來復雜性和性能開銷,特別是在大規模的并發任務處理時,所以我們需要根據場景合理使用。

六、優化前后對比

整體性能提升 292%:

圖片

優化后的加載效果對比:

圖片

七、性能監控

為了保證平臺在后續的迭代過程中,持續保持高性能,我們引入Chrome 開源的 web-vitals 庫,結合自研的運行時性能監控埋點(卡頓、崩潰),以及平臺的數據可視化能力,實現對前端整體性能的監控。并利用了平臺的數據監控預警能力,通過對不同指標的配置告警服務,增加性能指標相關的告警,在性能指標發生異動時,及時發現問題,優化性能,保障了用戶使用體驗。

圖片

八、總結

上面講了那么多優化方法,都是針對當前項目進行的針對性優化 ,所以我們進行優化時,需要根據具體情況和需求,結合不同的優化策略來達到最佳的性能優化效果。前端性能優化是一個重要的主題,它涉及到許多方面,包括頁面加載速度、交互響應時間、資源利用效率等。但不管什么樣的優化方式,他們的核心思路都是一致的,因為在用戶能看到頁面,并且與之交互之前,都是有固定的步驟的,所以優化的核心思路就是:**盡可能去掉一些關鍵步驟、盡可能提前一些重要步驟、盡可能優化某個具體步驟。**比如 SSR 相比于 CSR,用戶能更快的看到頁面,就是去掉了「下載入口index.html,下載并執行 CSS、JS,請求接口」這幾個關鍵步驟,比如上面說的對高優先級資源進行預加載就是提前一些重要步驟,再比如說通過web workers 避免 JS 執行時產生 Long Task就是優化某個具體步驟。以上就是本次性能優化實踐的所有內容,希望能對你有所幫助。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/89665.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/89665.shtml
英文地址,請注明出處:http://en.pswp.cn/web/89665.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

基于Python的畢業設計選題管理系統設計與實現

基于Python的畢業設計選題管理系統設計與實現摘要本論文詳細闡述了一個基于Python的畢業設計選題管理系統的設計與實現過程。該系統采用了Python的Tkinter庫構建圖形用戶界面,使用SQLite數據庫存儲數據,實現了高校畢業設計選題過程中的教師出題、學生選題…

如何在HTML5頁面中嵌入視頻

在HTML5中嵌入視頻主要使用<video>標簽&#xff0c;這是一種簡單且標準的方式。以下是詳細步驟和示例&#xff1a; 基礎實現 <!DOCTYPE html> <html> <head><title>視頻嵌入示例</title> </head> <body><!-- 基礎視頻播放器…

java操作Excel兩種方式EasyExcel 和POI

一、POI1.引入依賴<!-- 03 xls--> <dependency><groupId>org.apache.poi</groupId><artifactId>poi</artifactId><version>3.9</version> </dependency><!-- 07 xlsx --> <dependency><groupId>org.a…

Openlayers 面試題及答案180道(141-160)

《前后端面試題》專欄集合了前后端各個知識模塊的面試題,包括html,javascript,css,vue,react,java,Openlayers,leaflet,cesium,mapboxGL,threejs,nodejs,mangoDB,MySQL,Linux… 。 前后端面試題-專欄總目錄 文章目錄 一、本文面試題目錄 141. 如何在生產環境中優…

LangChain面試內容整理-知識點24:實戰案例:智能助手 Agent 構建

本案例講述如何用LangChain構建一個結合多個工具的智能助手 Agent。智能助手需要理解用戶復雜請求,通過調用不同工具(如搜索、計算、查數據庫等)執行多步推理,再給出答案。LangChain的Agent框架非常適合這種場景。 構建步驟: 確定需求和選擇Agent類型:假設我們要一個能上…

【MATLAB例程】Taylor算法用于TOA(到達時間)的三維標簽位置解算,可自適應基站數量。附下載鏈接

本文給出自適應錨點&#xff08;基站&#xff09;的Taylor算法解算TOA&#xff08;到達時間&#xff09;的MATLAB代碼。參考論文&#xff1a;《基于Taylor-Chan算法的改進UWB室內三維定位方法》中的Taylor算法來解算TOA的復現程序&#xff08;MATLAB&#xff09;。 文章目錄運行…

Eclipse代碼折疊增強插件的安裝與使用

本文還有配套的精品資源&#xff0c;點擊獲取 簡介&#xff1a;Eclipse作為Java開發者的IDE&#xff0c;提供包括代碼折疊在內的多種功能&#xff0c;便于管理與閱讀代碼。本文介紹的“com.cb.eclipse.folding_1.0.6.jar”插件能夠進一步增強Eclipse的代碼折疊能力。安裝后&…

Python day18

浙大疏錦行 python day 18. 內容&#xff1a; 昨天學習了聚類算法的一些基本內容&#xff0c;今天繼續學習相關知識分析簇的特征和相關含義&#xff08;使用可視化來進行分析&#xff0c;也可以使用ai&#xff09; 代碼&#xff1a; shap.initjs() # 初始化 SHAP 解釋器 ex…

WPS文檔中心及文檔中臺遠程命令執行漏洞

【嚴重】WPS文檔中心及文檔中臺遠程命令執行漏洞 漏洞描述 WPS文檔中心是面向個人和企業的云端文檔存儲與管理平臺&#xff0c;WPS文檔中臺是為企業提供的集成化文檔協同與流程管理解決方案&#xff0c;強調API對接與業務系統整合。 在2024年5月之前通過docker私有化部署的版…

WPF 加載和顯示 GIF 圖片的完整指南

WPF 加載和顯示 GIF 圖片的完整指南 在 WPF 中加載和顯示 GIF 圖片需要一些特殊處理&#xff0c;因為 WPF 的 Image 控件默認不支持動畫 GIF。 解決方案一&#xff1a;使用 WpfAnimatedGif 庫&#xff08;推薦&#xff09; 這是最簡單且功能最完整的方法。 實現步驟&#xff1a…

Node.js GET/POST請求詳解

Node.js GET/POST請求詳解 引言 Node.js作為一種基于Chrome V8引擎的JavaScript運行環境&#xff0c;以其高性能、非阻塞I/O模型和輕量級等特點&#xff0c;在服務器端開發中得到了廣泛應用。本文將詳細介紹Node.js中GET和POST請求的處理方法&#xff0c;幫助開發者更好地理解和…

C++string類(2)

3.string類對象的訪問及遍歷操作函數名稱功能說明operator[] &#xff08;重 點&#xff09;返回pos位置的字符&#xff0c;const string類對象調用beginendbegin獲取第一個字符的迭代器 end獲取最后一個字符下一個位置的迭代器rbeginrendrbegin獲取最后一個字符的迭代器 ren…

SQLShift:一款異構數據庫存儲過程遷移工具

SQLShift 是一款專注于解決企業級數據庫遷移難題的智能 SQL 方言轉換平臺&#xff0c;尤其擅長異構數據庫存儲過程的自動化遷移。 SQLShift 工具深度融合了 AI 與 SQL 語法專家模型&#xff0c;可以大幅提升遷移效率并降低人工適配風險。 功能特性 多源多目標&#xff1a;目前…

學習設計模式《十八》——備忘錄模式

一、基礎概念 備忘錄模式的本質是【保存和恢復內部狀態】。 備忘錄模式的思考序號備忘錄模式的思考說明1保存是手段&#xff0c;恢復才是目的標準的備忘錄模式保存數據的手段是通過內存緩存&#xff1b;廣義的備忘錄模式實現的時候&#xff0c;可以采用離線存儲的方式&#xff…

HOT100——排序篇Leetcode215. 數組中的第K個最大元素

文章目錄題目&#xff1a;Leetcode215. 數組中的第K個最大元素原題鏈接思路1代碼1思路2代碼2題目&#xff1a;Leetcode215. 數組中的第K個最大元素 原題鏈接 數組中的第K個最大元素 思路1 排序 排序后返回倒數第k個數 代碼1 思路2 使用priority_queue&#xff0c;大根堆&#x…

三維重建一: 相機幾何

參考這位大佬&#xff1a;https://zhuanlan.zhihu.com/p/458000359 一. 基本的投影模型 正如上面所說&#xff0c;相機是一個將三維物體投影為二維圖像的設備。 對于小孔相機&#xff0c;或者薄透鏡相機來說&#xff0c;基礎投影的數學模型可以表達為 我們把這個過程表達在笛…

mysql 字符集不一致導致索引失效問題

mysql 字符集不一致導致索引失效問題 問題&#xff1a; 兩張表&#xff0c;同一個字段&#xff0c;由于字符集不一致&#xff0c;導致雖然都有索引&#xff0c;在關聯查詢時&#xff0c;索引失效身份表 identity_info &#xff0c;查詢索引信息 show index from identity_info …

Linux內核設計與實現 - 第6章 內核數據結構

目錄1. 鏈表 (Linked Lists)2. 隊列 (Queues)3. 映射 (Maps)4. 二叉樹 (Binary Trees)5. 位圖 (Bitmaps)6. 其他數據結構性能考量1. 鏈表 (Linked Lists) 單向鏈表 vs 雙向鏈表 struct list_head 標準實現內核鏈表API&#xff1a;LIST_HEAD(), list_add(), list_del() 環形鏈表…

十五、K8s可觀測能力:日志收集

十五、K8s可觀測能力&#xff1a;日志收集 文章目錄十五、K8s可觀測能力&#xff1a;日志收集1、云原生日志框架-ECK介紹1.1 什么是ECK&#xff1f;1.2 ECK核心資源&#xff1a;1.3 生產級日志收集架構2、日志收集-ECK2.1 集群規劃2.2 ECK 安裝2.3 一鍵部署高可用 ES 集群2.4 一…

微服務變更?自動化測試利器Parasoft SOAtest修復快、準、穩!

微服務架構憑借靈活和可擴展的優勢越來越普及&#xff0c;但隨之而來的變更也成了開發團隊的“心頭大患”。服務之間依賴復雜&#xff0c;接口改來改去&#xff0c;不僅讓開發更費勁&#xff0c;還容易導致測試用例失效、測試效率下降&#xff0c;甚至埋下系統不穩的隱患。 自…