基于 Vue 的 H5 首屏加載優(yōu)化以及打包優(yōu)化實(shí)踐

偶爾有一天覺得公司的 H5 項(xiàng)目在 build 的時(shí)候特別慢卦睹,看了下時(shí)間大約在 60 - 80s,而且由于需要在微信中看真機(jī)效果方库,所以需要經(jīng)常 build结序,于是去網(wǎng)上找找資料如何縮短這個(gè)加載時(shí)間。以下是我在優(yōu)化加載過程中遇到的一些坑及優(yōu)化方案纵潦。

vue-build.png
網(wǎng)絡(luò)請求.png

從上圖中我們發(fā)現(xiàn)編譯耗時(shí)接近 80s徐鹤,而且仔細(xì)看還發(fā)現(xiàn) vendor.js 和 app.css 異常的大,這不僅導(dǎo)致我們在編譯階段很慢邀层,而且首屏響應(yīng)也會(huì)變慢返敬,怎么去解決呢?通過查了些資料我們開始著手優(yōu)化起來~

優(yōu)化方案

  • 服務(wù)端開啟 gzip 壓縮
  • webpack 配置優(yōu)化
  • 按需加載第三方組件

項(xiàng)目配置


該 H5 商城基于 vue-cli 腳手架構(gòu)建寥院,引入 vue-router 劲赠、vuex、axios 搭建 SPA 應(yīng)用秸谢,UI 工具庫選用的是 iView凛澎、mint-ui,以及不少第三方組件估蹄。

服務(wù)端 Nginx 開啟 gzip

這個(gè)很重要塑煎,盡管我們現(xiàn)在已經(jīng)做了,但是需要提醒的是服務(wù)端 Nginx 開啟 gzip 壓縮能大幅度提高頁面加載速度臭蚁,前端需要配置 compression-webpack-plugin 插件最铁。這里注意根據(jù) webpack 版本來選擇 compression-webpack-plugin 插件版本,webpack4 使用 2.x 垮兑,webpack4 以下版本選擇 1.x

  • config/index.js
module.exports = {
  build: {
        ...
        // Gzip off by default as many popular static hosts such as
        // Surge or Netlify already gzip all static assets for you.
        // Before setting to `true`, make sure to:
        // npm install --save-dev compression-webpack-plugin
        productionGzip: true,  // 這里開啟 gzip冷尉,默認(rèn)為false
        productionGzipExtensions: ['js', 'css']   // 只壓縮 js css 不壓縮圖片 
  }
}
  • build/webpack.prod.conf.js
if (config.build.productionGzip) {
    const CompressionWebpackPlugin = require('compression-webpack-plugin')
    //增加瀏覽器CPU(需要解壓縮), 減少網(wǎng)絡(luò)傳輸量和帶寬消耗 (需要衡量系枪,一般小文件不需要壓縮的)
    webpackConfig.plugins.push(
        new CompressionWebpackPlugin({
            asset: '[path].gz[query]',
            algorithm: 'gzip',
            test: new RegExp(
                '\\.(' +
                config.build.productionGzipExtensions.join('|') +
                ')$'
            ),
            threshold: 10240,               // 達(dá)到10kb的靜態(tài)文件進(jìn)行壓縮 按字節(jié)計(jì)算
            minRatio: 0.8                   // 只有壓縮率比這個(gè)值小的資源才會(huì)被處理
        })
    )
}
開啟雙端gzip后效果1.png

開啟雙端gzip后效果2.png

由圖中可以看出网严,這里配置完后首屏加載速度提升是很明顯的,vendor 由 176kb 壓縮成61kb嗤无,app.css 由 1.22M 壓縮成186kb震束,接下來我們可以看看如何通過配置 webpack 優(yōu)化打包速度。

1当犯、使用 webpack-parallel-uglify-plugin 插件來壓縮代碼

vue 默認(rèn)使用 UglifyJsPlugin 插件進(jìn)行代碼壓縮垢村,由于是單線程,壓縮效率較低嚎卫;我們可以使用 webpack-parallel-uglify-plugin 插件嘉栓,可以合理使用 CPU 資源宏榕,通過設(shè)置緩存能夠大大減少非首次構(gòu)建時(shí)間

const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin');
    ...
    // 注釋 webpack 提供的 UglifyJS 插件
    //new UglifyJsPlugin({
    //  uglifyOptions: {
    //    compress: {
    //      warnings: false
    //    }
    //  },
    //  sourceMap: config.build.productionSourceMap,
    //  parallel: true
    //}),
    // 增加 webpack-parallel-uglify-plugin 來替換
    new ParallelUglifyPlugin({
      cacheDir: '.cache/',
      uglifyJS:{
        output: {
          comments: false
        },
        compress: {
          drop_debugger: true, // 去除生產(chǎn)環(huán)境的 debugger 和 console.log
          drop_console: true
        }
      }
    })
webpack-parallel-uglify-plugin.png

此時(shí)編譯發(fā)現(xiàn)打包時(shí)間縮短了不少,不錯(cuò)侵佃,總算看到點(diǎn)希望麻昼,接下來我們來嘗試下縮小打包后的文件大小。

2馋辈、減少打包文件數(shù)量

隨著項(xiàng)目的迭代抚芦,引入的第三方庫也會(huì)越來越多,每次 build 都會(huì)對所有文件進(jìn)行打包迈螟,耗時(shí)也會(huì)越來越久叉抡,不利于平時(shí)開發(fā)。這個(gè)時(shí)候我們可以通過減少一些不經(jīng)常更新的包來單獨(dú)打包答毫,我們有兩種方式褥民,第一種是通過 CDN 引入包然后配合 externals 配置的方式也可以,抽離第三方包洗搂,只打包業(yè)務(wù)代碼消返。第二種方式就是引入 DLL 文件,dllplugin 是 webpack DllPlugin耘拇、webpack 的簡稱撵颊,思路也是講一些第三方包抽離出來單獨(dú)打包,后面就不需要重新打包了驼鞭。

使用方法:

  • 1、在 build 文件夾下新建 webpack.dll.conf.js尺碰,內(nèi)容如下:
const path = require('path')
const webpack = require('webpack')

module.exports = {
    entry: {
        //這地方寫你想抽離的包挣棕,可以參考你的package.json文件下的 dependencies
        vendor: [
            'vue/dist/vue.common.js',
            'vue-router',
            'vuex'
        ]
    },
    output: {
        //這地方寫你打包后生成文件的路徑
        path: path.join(__dirname, "../dist/dll/"),
        filename: '[name].dll.js',
        library: '[name]_library'
    },
    plugins: [
        //這個(gè)插件是重點(diǎn),用于打包上面entry里配置的包
        new webpack.DllPlugin({
            path: path.join(__dirname, '../dist/dll', '[name]-manifest.json'),
            name: '[name]_library'
        }),
        new webpack.optimize.UglifyJsPlugin()
    ]
}

這里我們先抽離出 vue亲桥,vue-router 和 vuex洛心,然后在 package.json 中 scripts
下加入該命令 "build:dll": "webpack --config build/webpack.dll.conf.js",執(zhí)行 yarn build:dll 命令將第三方依賴打包

yarn dll.png

可以看到在 dist 目錄下生成了一個(gè) dll 文件夾题篷,里面有 vendor-manifest.json 和 vendor.dll.js 這兩個(gè)文件词身,我們打開 build/webpack.base.conf.js 文件,編輯添加如下配置

const webpack = require('webpack');
module.exports = {
    ...
    plugins: [
        new webpack.DllReferencePlugin({
            manifest: require('../dist/vendor-manifest.json')
        })
    ]
    ...
}

接著我們只要在 index.html 中引入 vendor.dll.js 即可

<body>
    <div id="app"></div>
    <script src="./dist/dll/vendor.dll.js"></script>
</body>

接下來我們執(zhí)行 yarn build 發(fā)現(xiàn) vendor 文件由原來的 1.57M 變成了 931KB番枚,看起來效果不錯(cuò)

步驟一.png

這里我們只是預(yù)編譯了三個(gè)文件法严,當(dāng)我們把其他的第三方庫打包后看看效果如何

步驟二.png

vendor 文件現(xiàn)在只有 270 kb 了,縮小了不知道多少倍~ 到這里葫笼,dll 的配置基本完事了深啤,我們還可以把 index.html 中的手動(dòng)引入的腳步改成自動(dòng)導(dǎo)入。

// webpack.base.conf.js
new webpack.DllReferencePlugin({
    context: path.resolve(__dirname, '..'),
    manifest: require('../dist/vendor-manifest.json')
}),
// 在htmlwebpack后插入一個(gè) AddAssetHtmlPlugin 插件反浓,用于將 vendor 插入打包后的頁面
new AddAssetHtmlPlugin({
    filepath: require.resolve('../dist/dll/vendor.dll.js'),
    includeSourcemap: false
})

一開始踩了很多坑茎毁,配置 dll 一直配不對,還是要細(xì)心~

然后刪除 index.html 引入的腳本即可淑掌。接下來我們可以繼續(xù)優(yōu)化一下 css 呈昔,從我們的 main.js 文件可以看到全局引入了很多 css挥等,我們可以通過 CDN 方式引入。

多說一句堤尾,cdn 引入其實(shí)原理和 dll 一樣肝劲,但是我們知道每一個(gè) cdn 資源也是需要走請求的,如果很多 cdn 的話還是要權(quán)衡一下哀峻,同理涡相,dll 文件如果太大,會(huì)影響首屏加載剩蟀,不能光圖打包爽催蝗。

CDN 引入全局樣式和字體庫

我們把 main.js 中一些可以從 cdn 上找到的樣式和字體都通過 cdn 引入到 index.html 中,然后再打包

首頁.png
app.css.png

我們發(fā)現(xiàn) css 文件也響應(yīng)縮小了一些育特,最終效果如下圖所示:

end.png
end.png

總結(jié)

從首次打包花了 80s 到現(xiàn)在 47s丙号,優(yōu)化了接近一半的時(shí)間,在研究 webpack 時(shí)也遇到不少問題缰冤,基本都是自己 Google 犬缨,不斷的翻閱文檔和相關(guān) issues。有的插件在 webpack3.x 和 webpack4.x 不盡相同棉浸,沒有做向下兼容怀薛,需要不斷地踩坑,比如這次的 add-asset-html-webpack-plugin 在 webpack3.x 下只能使用 2.x 版本迷郑,以及昨晚的 compression-webpack-plugin 插件在 webpack3.x 下只能使用 1.x 版本枝恋,這些東西其實(shí)勞心勞力但是又沒有什么用處,真心不建議跟 webpack 較勁嗡害。

項(xiàng)目優(yōu)化其實(shí)只是一個(gè)下策焚碌,更重要的是我們平時(shí)寫代碼需要多思考,提升效率和性能霸妹。我們寫的時(shí)候需要注意引入第三方組件以及樣式十电,不是多處用到的組件盡量按需加載,外部樣式走 CDN叹螟,公用邏輯盡量提出來鹃骂,不要寫完就完事了。就我們目前的商城罢绽,移動(dòng)端組件庫就有倆偎漫,查看請求時(shí)發(fā)現(xiàn)有幾張圖片都是 1.5M(編輯同學(xué)上傳時(shí)沒有壓縮),首頁第一次加載請求有200多個(gè)有缆,主要是圖片請求象踊,這塊如何優(yōu)化呢温亲?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市杯矩,隨后出現(xiàn)的幾起案子栈虚,更是在濱河造成了極大的恐慌,老刑警劉巖史隆,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件魂务,死亡現(xiàn)場離奇詭異,居然都是意外死亡泌射,警方通過查閱死者的電腦和手機(jī)粘姜,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來熔酷,“玉大人孤紧,你說我怎么就攤上這事【苊兀” “怎么了号显?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長躺酒。 經(jīng)常有香客問我押蚤,道長,這世上最難降的妖魔是什么羹应? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任揽碘,我火速辦了婚禮,結(jié)果婚禮上园匹,老公的妹妹穿的比我還像新娘雳刺。我一直安慰自己,他們只是感情好偎肃,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布煞烫。 她就那樣靜靜地躺著浑此,像睡著了一般累颂。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上凛俱,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天紊馏,我揣著相機(jī)與錄音,去河邊找鬼蒲犬。 笑死朱监,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的原叮。 我是一名探鬼主播赫编,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼巡蘸,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了擂送?” 一聲冷哼從身側(cè)響起悦荒,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎嘹吨,沒想到半個(gè)月后搬味,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蟀拷,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年碰纬,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片问芬。...
    茶點(diǎn)故事閱讀 38,039評論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡悦析,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出愈诚,到底是詐尸還是另有隱情她按,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布炕柔,位于F島的核電站酌泰,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏匕累。R本人自食惡果不足惜陵刹,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望欢嘿。 院中可真熱鬧衰琐,春花似錦、人聲如沸炼蹦。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽掐隐。三九已至狗热,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間虑省,已是汗流浹背匿刮。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留探颈,地道東北人熟丸。 一個(gè)月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓,卻偏偏與公主長得像伪节,于是被迫代替她去往敵國和親光羞。 傳聞我的和親對象是個(gè)殘疾皇子绩鸣,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評論 2 345

推薦閱讀更多精彩內(nèi)容