Try   HackMD

Webpack 優化打包資源

工具

npm i -D webpack-bundle-analyzer babel-plugin-component image-webpack-loader babel-plugin-lodash lodash-webpack-plugin compression-webpack-plugin
  • webpack-bundle-analyzer 圖形化分析工具
  • babel-plugin-componentbabel.config.js 可以使用 component plugin,藉此達到只引入需要的組件來減小體積
  • image-webpack-loader 壓縮圖片
  • babel-plugin-lodashvue.config.js 可以使用 lodash-webpack-plugin,優化 lodash 打包資源
  • lodash-webpack-plugin 按需引入 lodash
  • compression-webpack-plugin gzip 壓縮資源檔

圖形化分析

vue.config.js

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; module.exports = { // ... configureWebpack: { plugins: [ // 分析打包資源 new BundleAnalyzerPlugin(), ], }, }

element-ui

babel.config.js

element-ui 引入檔元件化,便可以只引入需要的組件來減小體積

module.exports = { // ... plugins: [ // ... [ 'component', { libraryName: 'element-ui', styleLibraryName: 'theme-chalk', }, ], ], };

src/main.js

//... import { Breadcrumb, BreadcrumbItem, Loading, // 其餘會使用到的 element-ui 元件 ... } from 'element-ui'; // ... Vue.use(Breadcrumb); Vue.use(BreadcrumbItem); // 其餘會使用到的 element-ui 元件 ... Vue.prototype.$loading = Loading.service; // ...

壓縮圖片

module.exports = { // ... chainWebpack: config => { // 壓縮圖片 config.module .rule('images') .test(/\.(png|jpg|jpeg|gif|svg|svgz)$/i) .use('image-webpack-loader') .loader('image-webpack-loader') .options({ // jpeg mozjpeg: { progressive: true, quality: 30 }, // png optipng: { enabled: false }, // png pngquant: { quality: [0.65, 0.9], speed: 4 }, // svg gifsicle: { interlaced: false }, // jpg & png into webp webp: { quality: 75 }, }) .end(); }, }

Gzip 壓縮

vue.config.js

const CompressionPlugin = require('compression-webpack-plugin'); module.exports = { // ... configureWebpack: { plugins: [ new CompressionPlugin({ test: /\.(js|css|svg|otf)$/, filename: '[path][base].gz', threshold: 10240, }), ], }, }

lodash

vue.config.js

const LodashWebpackPlugin = require('lodash-webpack-plugin'); module.exports = { // ... configureWebpack: { plugins: [ // ... // lodash 按需打包 new LodashWebpackPlugin({ 'collections': true, }), ], }, }

babel.config.js

module.exports = { // ... plugins: [ [ 'lodash' ], ], };

jquery

vue.config.js

module.exports = { // ... chainWebpack: config => { // 指定引入 jquery 的檔案路徑 config.resolve.alias .set('jquery', 'jquery/dist/jquery.slim.min.js'); }, // ... }

router

src/router/index.js

某些較大的檔案使用 lazyload 方式引入
不宜過度使用,避免請求過多而變慢導致反效果

// ... import LoginPage from '../views/ds_auth/LoginPage.vue'; // 其餘較小的檔案 ... Vue.use(VueRouter); const routes = [ { path: '/', name: 'Index', component: () => import(/* webpackChunkName: "index" */ '../views/global/Index.vue'), }, { path: '/loginPage', name: 'LoginPage', component: LoginPage, }, // ... ]; // ...

優化成果

優化前 1.18 MB

優化後 668.24 KB


參考資料