最近在做一個基於mobile app的漫畫的專案,面向印尼市場。
網址是http://id.mangaya.mobi
上線後,基本測試沒有問題,開啟也挺順暢。但是google analytics卻反饋載入平均19s!
OMG~~於是開展了一系列的探索。。
首先說說技術棧,用的是create-react-app,redux,react-router,webpack4,babel7.
我們知道網頁的載入流程大致如下:
那麼優化網頁的載入速度,最本質的方式就是,1.減少請求數量 2.縮小請求體積大小。
減少請求數量
- 用base64減少不必要的網路請求,實際上create-react-app已經自動幫我們做了。
- 引入檔案使用React.Lazy
- 圖片延遲載入,使用react-lazyload,非常方便。
縮小請求體積大小
-
後臺返回的圖片使用webp格式,縮小體積。但是由於webp目前只被安卓支援,所以我們目前的方案是後端獲取請求的user-agent資訊,判斷如果是ios的話,就返回jpg格式的圖片,如果是安卓的話,就返回webp格式。這主要使用在banner圖。
-
webpack 處理
-
2.1 build的時候去掉map檔案,減少不必要的檔案以及防止被檢視原始碼
-
2.2 壓縮css和js,實際上create-react-app已經自動幫我們做了。uglifyjs-webpack-plugin使用的uglify-es已經不再被維護,取而代之的是一個名為terser的分支。
-
2.3 預設splitChunk是
chunks: 'all'
,但是這樣會導致生成一個很大的vendor檔案,可以改一下,將node檔案抽離出來。
splitChunks: {
// chunks: 'all',
chunks: "all",
maxInitialRequests: Infinity,
minSize: 0,
cacheGroups: {
vendor: {
test: /[\\/]node_modules[\\/]/,
name(module) {
// get the name. E.g. node_modules/packageName/not/this/part.js
// or node_modules/packageName
const packageName = module.context.match(
/[\\/]node_modules[\\/](.*?)([\\/]|$)/
)[1];
// npm package names are URL-safe, but some servers don't like @ symbols
return `npm.${packageName.replace("@", "")}`;
}
}
},
name: false
},
複製程式碼
這樣雖然總的專案大小變大了,但是由於vendor檔案被拆分成多個檔案,根據http1.1或者http2的協議,瀏覽器資源獲取是可以多個並行的,配合cdn,這樣請求資源,反而更快。
- 2.4 Babel polyfill的按需載入,直接在package.json配置就好了,由於需要支援的機子比較低端,所以設定為支援
>0.02%
的機型。可參考
"browserslist": [
">0.02%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
複製程式碼
- gzip壓縮
如果瀏覽器支援gzip壓縮,在傳送請求的時候,請求頭中會帶有
Accept-Encoding:gzip
。然後伺服器會將原始的response進行gzip壓縮,並將gzip壓縮後的response傳輸到瀏覽器,緊接著瀏覽器進行gzip解壓縮,並最終反饋到網頁上。
資源cdn加速
將靜態伺服器改成印尼的伺服器,明顯dns以及靜態資源的傳輸加快。最後就是cdn加速靜態資源了,我把npm包的js都放到cdn上了,之後還可以配置多路cdn等策略。
總結
經過一段時間的努力,成功將首次載入時間從19秒變成10秒以下!仍需要繼續。。。
同時我們還招募了志願者幫我們測試嘻嘻嘻 當然這只是首次的載入的時間問題,後續還有觀看漫畫的優化工作,以及改成https協議加入pwa的service worker等等,敬請期待哈哈。