Vue的效能調校記錄
架構
以下為我目前的系統架構
Web Server:AWS EC2 t2.micro(新加坡)
系統:ubuntu, 使用Nginx+php-fpm
Cloud Storage:AWS S3(新加坡)
Google Speed Insight
很多人在開發網站的時候
都會透過Google Speed Insight來幫網站做效能健診
並且透過分析報告來調整
但我在效能調校後的感想是
它提供的大部分的分析報告及修正建議是很有用的
但分數不能太過執著
先說建議的部份
會說大部分
是因為有些建議例如圖片縮圖
它會建議要用很小到很模糊的圖
但有些地方就是要顯示很大的圖所以沒辦法
再來有些是需要花錢來提昇的
因此要看當下的需求及預算來衡量
像是圖片來源的速度
我本身圖片是放在AWS S3上
如果願意多花一點錢把S3做加速
其實那個分數是會拉上很多
而且體感速度也是差很多
如果要再多花點錢用Cloudfront一定還會再更快更高分
所以有些調整是要看當下是否有辦法投入成本
再來
Google Speed Insight的爬蟲每次來爬的時候都是從美國出發
如果像我Server放在新加坡
速度上的物理限制很難突破
而且Google Speed Insight每次在分析的時候
都是在完全無Cache的情況
但在現實世界中其實都是第一次會比較慢
第二次開始就會快很多(當然前提是資源的cache設定要做好)
因此
我最後更在意的是體感速度的提昇
而不是完全的在追求Google Speed Insight的分數
Vuejs的部份
使用webpack splitchunk
vue+webpack在production的時候
如果沒特別處理
其實會發現很多超大的JS跟CSS
用Google Speed Insight它也會跟你說這些檔案太大了建議縮小
因此可使用webpack splitchunk將太大的js拆開
並設定每個cacheGroups的priority將比較不重要或少用的chunk排在後面
或是使用webpack magic comment設定webpackChunkName
另外
在針對production的js檔案大小及分佈
其實很難直接了解
所以我都使用webpack-bundle-analyzer來查看chunk的拆解情況
Preload/Prefetch
在資源(js/css/font/image)的DOM attribute中加入preload/prefetch
可以決定載入的方式
preload: 在頁面render之前就開始載入, 比較重要的js就可以做preload
prefetch: 比較不重要或不常用的資源, 可以用prefetch, 瀏覽器將會在有空閒的時候背景載入, 要使用的時候就不需要再花時載入一次
這兩個載入方式都可以透過@vue/preload-webpack-plugin這個套件來處理
或是使用webpack magic comment的webpackPreload或webpackPrefetch
preconnect
preconnect可以讓瀏覽器在對一些外部資源請求之前(像是後端的api, AWS S3, Google Analytics)
先對這些服務做DNS解析、或是交握等等這些動作
等到需要對這些Server請求的時候可以縮短一些時間
大概會長這樣
<link rel="preconnect" href="https://storage.googleapis.com" crossorigin>
一樣可以透過套件來完成(html-webpack-preconnect-plugin)
purgecss-webpack-plugin
這個套件會使用purgecss
可以拿來砍掉沒用到的css(Google Speed Insight會跟你說)
但要小心使用不要砍到真的要用的css
用Vue會有個問題就是因為production會將不是當下頁面的資源也載入
所以Google Speed Insight會跟你說你有些css沒用
但其實是在其他頁面有用到的
lazy load
使用lazy loading的好處
能讓畫面不可見範圍的資源像是圖片、影片等資源先不要載入
避免資源的浪費跟效能問題
npm上可以找到很多實做lazy load的js套件
我則是使用lazysizes
另外我有使用vuetify
vuetify本身也提供lazy load的相關功能
Web Server的部份
HTTP2
速度比HTTP1快
- 可以對請求進行header壓縮
- 多個請求只須建立單一TCP連線, 減少重複交握的時間
- Server Push將資源Push到瀏覽器Cache中
Cache靜態資源
Web Server針對webpack打包後的靜態資源
做cache設定
其實就是幫靜態資源的header加上Cache-Control告訴瀏覽器cache起來
max-age的時間就依照需求設定
如果webpack有設定打包時重新將檔案hash
max-age其實可以拉長到一年都沒差
因為有新的發佈檔案都會更改
以下為nginx的範例
location ~ (css|js|map|jpg|jpeg|png|ico|gif|woff|woff2|svg|ttf|eto|br|gz)$ {
add_header Cache-Control "max-age=86400";
}
JS/CSS minify
這個算是很基本的就不多講了
透過webpack都很好處理
Vue CLI建立的專案基本上也都預設有做到
瀏覽器相容性支援
這個就很取決系統的使用者瀏覽器使用比例
或是看專案合約上的瀏覽器支援
因為如果瀏覽器要支援比較舊的總是要透過polyfill
打包後也是很佔空間
如果專案不須特別支援ES5的話
polyfill就可以直接拿掉節省資源
或是直接使用Vue的Modern Mode打包
整個頁面初始化的時候加入loading
loading可以減少使用者對等待的焦慮感
一片白的頁面會讓人不知道網站是否正常運作
Google Speed Insight也會用空白的時間長度來做一部分的評斷
Cloud Storage的部份
Cache-Control設定
跟Web Server設定一樣
幫檔案加上Cache Control並設定TTL即可
Laravel在檔案上傳(put/putfileAs)選項就能直接對Cloud Storage做這些事情
<?php
Storage::disk('s3')->putfileAs('blog/foobar.jpg', $image, 'foobar.jpg', [
'CacheControl' => 'max-age=31536000',
]);
金錢手段能處理的部份
有些事情靠金錢也能解決
單看當下的需求、預算
- Web Server Instance開好一點
- Cloudfront
- S3加速
以Web Server Instance來說
因為我自己的Blog主要拿來做記錄用
所以也不會開多好夠用就好