之前提到首屏優化,想到的就是Vue項目首頁打開很慢需要優化。一般都是肉眼看看,對當前的加載速度并沒有一個準確的衡量標準,也沒有很清晰的解決思路。
前兩天我想給自己的網站申請谷歌廣告,聽說審核對網站的性能要求很高。于是網上搜索后發現了一個網站優化利器--Lighthouse
一:Lighthouse是什么?
Lighthouse 是一個由?Google 開發的開源自動化工具,用于改進網頁質量。它提供全面的網頁性能、可訪問性、最佳實踐和 SEO 分析,幫助開發者構建更好的網站體驗。
Lighthouse這個工具前端開發者又熟悉又陌生,說她熟悉因為她就在Chrome的F12面板中,跟Network在一塊。說她陌生是因為,可能大多程序員沒注意到她,也不知道她是干什么用的。
Lighthouse使用起來很簡單,F12里找到她,輸入需要檢測的網站即可。我第一次使用時的得分如下
二:Lighthouse的相關指標
1、主要指標
如上截圖中主要4個指標,相關概念如下
性能 (Performance) | 頁面加載速度和用戶體驗 | 包含FCP, LCP, TTI, TBT, CLS |
可訪問性 (Accessibility) | 殘障用戶友好度 | 屏幕閱讀器支持,色彩對比度,ARIA 屬性 |
最佳實踐 (Best Practices) | 現代Web開發標準 | HTTPS, 安全的API使用,圖片優化 |
SEO (Search Engine Optimization) | 搜索引擎優化 | 元標簽,結構化數據,移動友好性 |
2、性能(Performance)下的指標
- FCP (First Contentful Paint)??首個內容繪制時間
?測量頁面首個元素呈現的時間,讓用戶知道網站開始載入了。
-
LCP (Largest Contentful Paint)?最大內容繪制時間
?測量頁面主要內容加載完成的時間,讓用戶知道網站載入完畢,可以交互了。
- CLS (Cumulative Layout Shift)?累積布局偏移
?測量頁面內容意外移動的程度,比如一個按鈕在點擊時因其他元素加載突然下移了。
3、指標作用
通過這些指標得分,我們可以量化的知道自己網站的性能效果。有一個參考值,便于針對性的優化。
三:優化建議
Lighthouse的每個指標都有對應的優化建議,如下圖。如圖右上角可以切換各個指標
四:成功實踐
我根據Lighthouse的建議,針對性的做了相關的措施。最終成績如下,我網站效果為CodingLife,忙活了4天結果還算滿意~
先說下我服務器的配置,2核2G 3M帶寬。為了節省費用,配置堪稱寒酸!
1、分割打包 按需加載
首先要在路由配置中,使用按需加載與分包設置
// router.js文件中
routes: [{path: '/',name: 'BlogDetail',component: () => import(/* webpackChunkName: "blogDetail", webpackPrefetch: false */ '@/components/MainPage/BlogDetail');}
]
其次一定要配合webpack配置,否則很可能無法按需加載。即首頁渲染時,加載其他頁面的js包
// vue.config.js文件
module.exports = {chainWebpack: config => {// 禁用所有 prefetchconfig.plugins.delete('prefetch');}
};
2、壓縮資源包體積
將JS資源文件打包為.gz格式,可以高效減少資源包體積。shezhi前端webpack打包時,就做GZip壓縮
// vue.config.js文件
module.exports = {configureWebpack:config=>{// GZip壓縮const CompressionPlugin = require('compression-webpack-plugin');config.plugins.push(new CompressionPlugin({algorithm:'gzip',test:/\.(js|css|woff|woff2|svg)$/, // 要壓縮的文件threshold:10240, // 壓縮超過10k的數據deleteOriginalAssets:false, // 不刪除壓縮前的文件,如果瀏覽器不支持Gzip,則會加載源文件minRatio:0.8 // 壓縮比大于0.8的文件將不會被壓縮}));}
};
Nginx服務器,配合設置
server {gunzip on; # 如果客戶端不支持 gzip,自動解壓返回原始文件gzip off; # 關閉動態壓縮(因為已經有預壓縮文件)
}
3、減小圖片體積
圖片使用webp格式,可以大幅減小圖片體積。使用webp主要工作在ngnix上,具體操作如下
安裝cwebp,處理圖片
# 下載最新版源碼(當前最新版本1.3.0)
wget https://storage.googleapis.com/downloads.webmproject.org/releases/webp/libwebp-1.3.0.tar.gz# 解壓并進入目錄
tar -xvzf libwebp-1.3.0.tar.gz
cd libwebp-1.3.0# 配置編譯選項(確保啟用PNG和JPEG支持)
./configure --enable-libpng --enable-libjpeg# 編譯并安裝
make
sudo make install# 刷新庫緩存
sudo ldconfig# 驗證安裝
cwebp -version
配置nginx有限返回webp格式圖片
http {# 簡化的WebP檢測map $http_accept $webp_suffix {default "";"~*webp" ".webp"; # 添加.webp后綴}# HTTPS 服務器 - 主配置server {listen 443 ssl http2;server_name codinglife.online www.codinglife.online;location /uploads/ {alias /opt/CodingLife/uploads/;autoindex off;# 核心緩存策略(根據文件類型區分)location ~* \.(jpe?g|png|gif|webp|svg|avif)$ { try_files $uri$webp_suffix $uri =404;add_header Vary Accept; # 關鍵:標記內容協商}}}
}
4、減少圖片請求數量
我的博客首頁是個列表,列表的每條都包含一個縮略圖,剛開始設置每頁8條數據。8個圖片,對于3M的帶寬來說,壓力太大。
于是我將分頁請求中每頁條數精細化,根據設備分辨率動態設置。比如移動端每頁3條,筆記本電腦每頁4條,外接顯示器8條。
calculatePageSize() {if (this.windowWidth < 1366) {this.perPageNum = 3 // 移動端和小屏設備} else if (this.windowWidth >= 1366 && this.windowWidth < 1600) {this.perPageNum = 4 // 14寸筆記本} else if (this.windowWidth >= 1600 && this.windowWidth < 1920) {this.perPageNum = 5 // 15.6寸筆記本} else {this.perPageNum = 8 // 大屏幕}}
5、減少無用Dom
因為Lighthouse還模擬移動設備測試首屏性能,并且模擬條件極為苛刻。具體如下
-
Desktop
:默認使用?150ms TCP延遲的"有線"網絡?(類似穩定WiFi/光纖)。 -
Mobile
:默認使用?300ms TCP延遲 + 1.6Mbps下載/0.75Mbps上傳的"慢速4G"網絡。
我的網站使用媒體查詢,自適應移動端和pc端。因為移動端屏幕大小有限,我選擇隱藏了很多不必要的模塊。但原有的css設置隱藏是奢侈的,依舊消耗性能,我本次將無用的dom需要徹底刪掉。
<section v-if="isDeskTop"></section>data: function () {return {isDeskTop: window.innerWidth > 768 // 是否是桌面端}
},
6、剔除無用請求
以前適配移動端時大大咧咧,只想著實現效果就行。很多無用模塊都是css配置display:none,js接口正常請求,現在看來是真的浪費。本次我又精細化的過了一遍,移動端時刪除不必要的接口請求。
// 移動端時刪除不必要的接口請求
if(this.isDeskTop){ //渲染留言個數this.GetLeaveMessageNum();this.GetCommentNum();
}
7、提高傳輸效率
chrome最多同時發6個請求,如果需要同時發起7個請求,第7個就要等待前6個結束。可SPA同時發起7個請求可太常見了。
于是我將HTTP/1升級到HTTP/2,做到單 TCP 連接上并行傳輸多個請求/響應。原理如下,告別了network里同時并行一堆請求的歷史
原理
network效果?
nginx的配置超級簡單,只需要一行:
server {listen 443 ssl http2;
}
五:最終效果
哥們的網站CodingLife,最終效果不管移動端還是PC端都是秒開。摸索了4天,最終看到Lighthouse打分99時,我跟個傻子一樣哈哈大小,那是真的開心!
打開F12的network可以看到如下差別,不提速是不可能的啦
- 請求的JS文件條數明顯少了(按需加載,只加載首屏js)
- JS資源文件最大的也就700k(Gzip壓縮)
- 圖片大都100k以內(webp格式圖片)
- 請求的圖片條數明顯減少(動態設置列表條數)
- 發起的接口請求明顯減少(刪除移動端無用請求)
- 請求縮略圖只有一條(啟用http/2)