2023年通天塔搭建頁前端效能最佳化階段分享
來源:京東技術
導讀
本文分享京東集團2023年通天塔專案在搭建頁前端效能最佳化的經驗和成果。讀者將瞭解如何透過減少頁面載入時間、提高互動響應速度和執行效率,來顯著提升使用者體驗。文章還將涵蓋對工具和實踐方法的評估,以及如何量化效能改進的效果。
本文分享京東集團2023年通天塔專案在搭建頁前端效能最佳化的經驗和成果。讀者將瞭解如何透過減少頁面載入時間、提高互動響應速度和執行效率,來顯著提升使用者體驗。文章還將涵蓋對工具和實踐方法的評估,以及如何量化效能改進的效果。
通天塔搭建頁專案是用來搭建各類活動頁面,比較老且業務複雜的專案,可最佳化點還是非常多的。今年側重對運營頁首屏載入的效能最佳化,在保證系統穩定可控、需求持續迭代前提下,最終提升了58.8%速度。在此非常感謝通天塔產品組、後端組、前端組同學,對專案效能最佳化大力支援。
市面上有很多效能最佳化方案,數不勝數,但如果開始就只是模仿一些邊邊角的最佳化,雖然也會略有效果,但不一定能給系統解決核心卡頓問題,不能給系統帶來質的提升,甚至到後面最佳化效果越來越差,這些最佳化可能會衝突、可能變成負最佳化。而且如果不去優先分析核心的問題,可能就會一直忽視核心問題,導致系統長期處於低效低體驗的狀態,隨著業務複雜變得越來越卡。
常見分析工具
圖 2.
分析網頁在執行時(而不是載入)時的效能。具體分析頁面每個階段哪些方法在執行,哪些資源在載入,很容易看出哪裡在阻塞。
也可以用來設定不同的cpu和網路環境。由於開發者電腦一般效能比較好,模擬較差效能和網路也是有必要的。
圖 3.
1)先看摘要Summary標籤頁,分析到底是載入、執行指令碼、渲染、繪製哪一個最佔時間,再去決定主要最佳化方向。
圖 4.
https://web.dev/articles/avoid-large-complex-layouts-and-layout-thrashing?utm_source=devtools&hl=zh-cn#avoid-forced-synchronous-layouts
圖 5.
2)再展開主要Main部分。開發者工具會向您顯示主執行緒上的活動隨時間變化的火焰圖。x 軸表示一段時間內的記錄。每個條形都代表一個事件。橫條越寬,表示事件用時越長。y 軸表示呼叫堆疊。如果您看到事件相互堆疊,則表示上層事件導致了下層事件。
圖 6.
3)放大上方Overview,找到任務右上角的紅色三角形,定位到耗時較長的任務,再定位到具體的方法中。
圖 7、8.
對於長任務,官網還有進一步最佳化建議:
懶載入相關建議:
4、程式碼覆蓋率Coverage
可以分析不同資源使用率情況。對於低使用率且較大體積的檔案,考慮懶載入、移除無效程式碼。
圖 9.
5、燈塔皮膚Lighthouse
https://developer.chrome.com/docs/lighthouse/overview?hl=zh-cn
圖 10.
主要是給頁面綜合評分,還有FCP、LCP、TBT、CLS分析。如果評分還有不足的地方,那就還有較大最佳化的空間。
3.1 加速請求資源速度
個人體驗感覺,快取帶給頁面效能提升是最明顯的。
像base64的圖片可以當資料類儲存。
還有函式內部的快取;
<link rel="dns-prefetch" href="//cdn1.jd.com"><link rel="dns-prefetch" href="//cdn2.jd.com"><link rel="dns-prefetch" href="//cdn3.jd.com">
比如字型檔案
<link rel="preload" as="font" href="xxxx.woff" />
不止是靜態資源,有條件的話,儘量讓所有資源都走CDN,有效提升載入速度,減少白屏時間。
3.2 減少請求資源大小
import * as xxxx-ui from 'xxxx-ui'
const Button = xxxx-ui['Button']
最好都改成按需載入,確保打包時候不會把整個庫都打進去。
import { Button } from 'xxxx-ui'
只要支援基於 ES modules 的 tree shaking,就會有按需載入的效果。
不過有的引入比較隱蔽,不容易直接發現,只有進行打包分析後才能實際發現多種情況打包了多餘的包。
(b)引入子包寫法不正確
比如引入加密包不正確,引入導致打包體積很大。
import crypto from 'crypto'const str = 'xxxxxxxxx'const sign = crypto.createHash('md5').update(str).digest('hex')
實際只用了crypto的md5方法,但卻把整個crypto包和其依賴的包都打包進程式碼裡。
圖 11.
後續改成只引入crypto的md5方法就能起到一樣的效果。
import md5 from 'crypto-js/md5' const str = 'xxxxxxxxx'const sign = md5(str).toString()
類似的lodash也有這樣的情況,透過改變寫法,也可以改善打包大小,在Gzipped下從幾十KB減少到幾KB。
圖 12.
只需改寫下,單個引入lodash裡的方法
圖 13、14.
比如,antd3.0的元件引用也有類似問題,需要改寫引用程式碼按需載入元件;
圖 15.
// 引入編輯器樣式import 'braft-editor/dist/index.css'
import Header from './Component/Header'<Header />
const Header = React.lazy(() => import(/* webpackChunkName:"Header" */ './Component/Header'))<React.Suspense fallback=""> <Header /></React.Suspense>
注意1:還是不能濫用,主要針對低優先順序或者體積過大的模組、元件。
setTimeout(() => import(/* webpackChunkName: 'xxx'*/ './xxx.less' ), 500)
比如,使用 Day.js 替換 momentjs 最佳化打包大小,但是打包多一個配置,這是antd裡介紹的配置;
圖 17.
<script src="
比如這個生成excel檔案的外掛,打包在專案裡就會很重。放在cdn上,不隨專案打包版本更新,每次載入後還能有較長快取時間。
圖 18.
- 直接壓縮工具壓縮;
- 物件儲存(OSS)壓縮或者裁剪圖片;
- nginx伺服器中配置;
多數語言包是不需要被打包進來的,可以打包分析檢查一遍。
圖 19.
8)字型檔案壓縮
一個完整字型檔案都有幾MB,而一般專案裡只有少數文字需要用到特殊字型,可以利用類似Fontmin把需要的文字單獨拎出來。
如果字數較少也考慮圖片替代,和其他圖片合併。
9)打包移除多餘程式碼
(a)Tree Shaking 刪除多餘程式碼
webpack3可以配置,webpack4+的mode: procution下自帶。其他打包工具也有支援。
注意1:使用 ES2015 模組語法(即 import 和 export)。
注意2:確保沒有編譯器將 ES2015 模組語法轉換為 CommonJS。比如lodash就是基於commonjs,所以才有上文《減少請求資源大小》中把整個lodash包都打進去的情況。
注意3:在專案的 package.json 檔案中新增 "sideEffects" 屬性。
(b)移除生產環境的 console.log、debugger、註釋
new UglifyJsPlugin({ uglifyOptions: { compress: { drop_console: true, drop_debugger: true } }})
10)生產環境選擇適當source-map方案,控制打包體積
根據實際情況,需要考慮原始碼要不要隱藏,除錯要不要更友好。
3.3 減少請求資源數量
合併js請求:配置webpack裡splitChunks的cacheGroups,把必用的公共依賴打包到一起,類似:
圖 20.
(a)多個圖片合併成雪碧圖;
(b)圖示類圖片儘量使用向量圖示庫iconfont(儘量按需配置、按需打包);
(c)可css、svg繪製的,儘量用css、svg實現;
<img loading="lazy" src="image.jpg" alt="..." />
3.4 最佳化程式碼邏輯
(a)有些資料會非常大,儘量分頁優先請求或者載入渲染涵蓋可視區域範圍前幾個、前十幾個,讓首屏的展示速度更快一點,後續再用完整資料覆蓋或者增量渲染;
(b)非許可權類的請求可以放在更早的位置發出,非阻塞性的請求可以先請求再等較晚時候處理邏輯,業務優先順序低的請求可以放在頁面渲染完成以後發出;
(c)不同優先順序的元件,可以分不同階段載入、處理邏輯,讓關鍵模組優先渲染、頁面整體過渡效果更好;
(d)如果存在前置的頁面,可以在前置的頁面空閒時間提前載入後續頁面的資料,甚至是資源;
(e)複雜的渲染和資料處理,也可以考慮遷移到服務端來做;
(a)迴圈、遞迴巢狀層級太深太多的話很容易造成卡頓;
(b)迴圈使用時,確認是否可以提前中斷迴圈,而不是把每個迴圈都走完;
(b)有的方法比較耗費效能,類似深複製、字串拼接,注意使用次數;
(c)檢視下手寫的方法是否可以用lodash等成熟庫的方法替代,可能效能更好;
(d)不同模組裡相同或者相似的程式碼,提取成公共方法或者元件;
(e)監聽器、計時器最好控制數量,配套退出機制,及時清除;
3.5 最佳化業務邏輯
(1)對於大部分專案,其實已經做過或多或少的最佳化,但可能依然有卡頓。
(2)對於大部分文章,其實主要集中於純技術,也都很少去思考產品規劃是否合理、業務邏輯是否合理。
(a)針對大多數使用者使用習慣,優先提供簡化易懂易用的常用互動,同時把專業垂直複雜的冷門互動單獨拎出來;
(b)有的業務模組邏輯非常重的,可以獨立出來,或者拆分成多級、多個模組;
(c)對於功能繁雜的頁面,應該把不重要的業務模組遷出、收起、延後展示;
(d)透過埋點確認沒人使用的業務模組,應該考慮下線;
(e)低使用頻率的功能控制載入次數,類似版本更新功能,每次開啟頁面都會請求最新配置介面資料,可以設定間隔一段時間才能重新請求,或者跟隨版本號更新後才能重新請求一次;
通天塔搭建頁是用來搭建京東商城各類活動頁面,整個專案迭代時間很久遠且業務複雜。隨著體量上升,載入速度慢、操作卡頓現象越來越多,效能最佳化成了23年的當務之急。通天塔及互動前端組經過一年的全方位最佳化,提升了58.8%首屏載入速度,兼顧了體驗和功能,在此分享一下這一年的經驗和心得。
來自 “ ITPUB部落格 ” ,連結:https://blog.itpub.net/70024924/viewspace-3006004/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 前端面試題 — 前端頁面效能最佳化前端面試題
- web前端分享:效能最佳化之文件碎片處理Web前端
- 好程式設計師分享Web前端效能最佳化程式設計師Web前端
- 前端效能最佳化前端
- 前端頁面效能前端
- web前端的幾個階段Web前端
- 前端技術分享:頁面效能優化問題覆盤前端優化
- 前端效能最佳化——圖片最佳化前端
- Spark 效能調優--開發階段Spark
- 頁面壞UV效能最佳化
- 前端進階(1)Web前端效能優化前端Web優化
- 從頁面載入到資料請求,前端頁面效能優化實踐分享前端優化
- 如何分析並最佳化網頁效能?網頁
- 前端面試7:頁面效能前端面試
- 軟體效能測試的幾個階段
- RAG應用效能最佳化全景圖:從查詢到生成的6個關鍵階段
- 遊戲陪玩原始碼前端效能優化,開發階段可採取的措施遊戲原始碼前端優化
- 小白階段如何學習Web前端知識Web前端
- web前端效能最佳化——圖片載入的最佳化Web前端
- MYSQL效能最佳化分享(分庫分表)MySql
- 最新前端開發職業路線+前端框架 共四階段前端框架
- 前端效能最佳化實踐方向與方法前端
- 前端效能最佳化百問大雜燴前端
- 前端效能最佳化——啟用文字壓縮前端
- 談談前端效能最佳化-面試版前端面試
- 14個Flink SQL效能最佳化實踐分享SQL
- PHP開發規範之效能最佳化分享PHP
- [轉帖]Linux效能最佳化—記憶體效能篇分享專題Linux記憶體
- 前端效能最佳化---防抖與節流--02前端
- web前端開發培訓有哪些學習階段Web前端
- 前端各階段資源,學得完算我輸前端
- 好程式設計師web前端教程分享常見基礎面試題之效能最佳化程式設計師Web前端面試題
- MongoDB 提升效能的18原則(開發設計階段)MongoDB
- 對於購物中心HTML前端頁面的最佳化HTML前端
- 前端效能最佳化:使用 Web Workers 實現輪詢前端Web
- 【前端除錯】- 藉助Performance分析並最佳化效能前端除錯ORM
- 前端頁面效能指標與採集方式前端指標
- 底層搭建:踏入動作遊戲的製作階段遊戲