溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶服務(wù)條款》

webpack打包優(yōu)化的幾個(gè)方法總結(jié)

發(fā)布時(shí)間:2020-08-27 19:22:37 來源:腳本之家 閱讀:204 作者:michael 欄目:web開發(fā)

為什么要優(yōu)化打包?

  • 項(xiàng)目越做越大,依賴包越來越多,打包文件太大
  • 單頁面應(yīng)用首頁白屏?xí)r間長,用戶體驗(yàn)差

我們的目的

  • 減小打包后的文件大小
  • 首頁按需引入文件
  • 優(yōu)化 webpack 打包時(shí)間

優(yōu)化方式

1、 按需加載

1.1 路由組件按需加載

const router = [
 {
  path: '/index',
  component: resolve => require.ensure([], () => resolve(require('@/components/index')))
 },
 {
  path: '/about',
  component: resolve => require.ensure([], () => resolve(require('@/components/about')))
 }
]

1.2 第三方組件和插件。按需加載需引入第三方組件

// 引入全部組件
import ElementUI from 'element-ui'
import 'element-ui/lib/theme-chalk/index.css'
Vue.use(ElementUI)

// 按需引入組件
import { Button } from 'element-ui'
Vue.component(Button.name, Button)

1.3 對(duì)于一些插件,如果只是在個(gè)別組件中用的到,也可以不要在 main.js 里面引入,而是在組件中按需引入

// 在main.js引入
import Vue from vue
import Vuelidate from 'vuelidate'
Vue.use(Vuelidate)

// 按組件按需引入
import { Vuelidate } from 'vuelidate'

2、優(yōu)化 loader 配置

  • 優(yōu)化正則匹配
  • 通過 cacheDirectory 選項(xiàng)開啟緩存
  • 通過 include、exclude 來減少被處理的文件。
module: {
 rules: [
  {
   test: /\.js$/,
   loader: 'babel-loader?cacheDirectory',
   include: [resolve('src')]
  }
 ]
}

3、優(yōu)化文件路徑——省下搜索文件的時(shí)間

  • extension 配置之后可以不用在 require 或是 import 的時(shí)候加文件擴(kuò)展名,會(huì)依次嘗試添加擴(kuò)展名進(jìn)行匹配。
  • mainFiles 配置后不用加入文件名,會(huì)依次嘗試添加的文件名進(jìn)行匹配
  • alias 通過配置別名可以加快 webpack 查找模塊的速度。
 resolve: {
  extensions: ['.js', '.vue', '.json'],
  alias: {
   'vue$': 'vue/dist/vue.esm.js',
   '@': resolve('src'),
  }
 },

4、生產(chǎn)環(huán)境關(guān)閉 sourceMap

  • sourceMap 本質(zhì)上是一種映射關(guān)系,打包出來的 js 文件中的代碼可以映射到代碼文件的具體位置,這種映射關(guān)系會(huì)幫助我們直接找到在源代碼中的錯(cuò)誤。
  • 打包速度減慢,生產(chǎn)文件變大,所以開發(fā)環(huán)境使用 sourceMap,生產(chǎn)環(huán)境則關(guān)閉。

5、代碼壓縮

  • UglifyJS: vue-cli 默認(rèn)使用的壓縮代碼方式,它使用的是單線程壓縮代碼,打包時(shí)間較慢
  • ParallelUglifyPlugin: 開啟多個(gè)子進(jìn)程,把對(duì)多個(gè)文件壓縮的工作分別給多個(gè)子進(jìn)程去完成

兩種方法使用如下:

plugins: [
 new UglifyJsPlugin({
  uglifyOptions: {
   compress: {
    warnings: false
   }
  },
  sourceMap: true,
  parallel: true
 }),

 new ParallelUglifyPlugin({
  //緩存壓縮后的結(jié)果,下次遇到一樣的輸入時(shí)直接從緩存中獲取壓縮后的結(jié)果并返回,
  //cacheDir 用于配置緩存存放的目錄路徑。
  cacheDir: '.cache/',
  sourceMap: true,
  uglifyJS: {
   output: {
    comments: false
   },
   compress: {
    warnings: false
   }
  }
 })
]

6、提取公共代碼

  • 相同資源重復(fù)被加載,浪費(fèi)用戶流量,增加服務(wù)器成本。
  • 每個(gè)頁面需要加載的資源太大,導(dǎo)致網(wǎng)頁首屏加載緩慢,影響用戶體驗(yàn)。

webpack3 使用 CommonsChunkPlugin 的實(shí)現(xiàn):

plugins: [
 new webpack.optimize.CommonsChunkPlugin({
  name: 'vendor',
  minChunks: function(module, count) {
   console.log(module.resource, `引用次數(shù)${count}`)
   //"有正在處理文件" + "這個(gè)文件是 .js 后綴" + "這個(gè)文件是在 node_modules 中"
   return module.resource && /\.js$/.test(module.resource) && module.resource.indexOf(path.join(__dirname, './node_modules')) === 0
  }
 }),
 new webpack.optimize.CommonsChunkPlugin({
  name: 'common',
  chunks: 'initial',
  minChunks: 2
 })
]

webpack4 使用 splitChunks 的實(shí)現(xiàn):

module.exports = {
 optimization: {
  splitChunks: {
   cacheGroups: {
    vendor: {
     priority: 1, //添加權(quán)重
     test: /node_modules/, //把這個(gè)目錄下符合下面幾個(gè)條件的庫抽離出來
     chunks: 'initial', //剛開始就要抽離
     minChunks: 2 //重復(fù)2次使用的時(shí)候需要抽離出來
    },
    common: {
     //公共的模塊
     chunks: 'initial',
     minChunks: 2
    }
   }
  }
 }
}

7、CDN 優(yōu)化

  1. 隨著項(xiàng)目越做越大,依賴的第三方 npm 包越來越多,構(gòu)建之后的文件也會(huì)越來越大。
  2. 再加上又是單頁應(yīng)用,這就會(huì)導(dǎo)致在網(wǎng)速較慢或者服務(wù)器帶寬有限的情況出現(xiàn)長時(shí)間的白屏。

1、將 vue、vue-router、vuex、element-ui 和 axios 這五個(gè)庫,全部改為通過 CDN 鏈接獲取,在 index.html 里插入 相應(yīng)鏈接。

<head>
 <link rel="stylesheet"  rel="external nofollow" />
</head>
<body>
 <div id="app"></div>
 <script src="https://cdn.bootcss.com/vue/2.6.10/vue.min.js"></script>
 <script src="https://cdn.bootcss.com/axios/0.19.0-beta.1/axios.min.js"></script>
 <script src="https://cdn.bootcss.com/vuex/3.1.0/vuex.min.js"></script>
 <script src="https://cdn.bootcss.com/vue-router/3.0.2/vue-router.min.js"></script>
 <script src="https://cdn.bootcss.com/element-ui/2.6.1/index.js"></script>
 <!-- built files will be auto injected -->
</body>

2、在 webpack.config.js 配置文件

module.exports = {
 ···
  externals: {
   'vue': 'Vue',
   'vuex': 'Vuex',
   'vue-router': 'VueRouter',
   'element-ui': 'ELEMENT',
   'Axios':'axios'
  }
 },

3、卸載依賴的 npm 包,npm uninstall axios element-ui vue vue-router vuex

4、修改 main.js 文件里之前的引包方式

// import Vue from 'vue'
// import ElementUI from 'element-ui'
// import 'element-ui/lib/theme-chalk/index.css'
// import VueRouter from 'vue-router'

import App from './App.vue'
import routes from './router'
import utils from './utils/Utils'

Vue.use(ELEMENT)
Vue.use(VueRouter)

const router = new VueRouter({
 mode: 'hash', //路由的模式
 routes
})

new Vue({
 router,
 el: '#app',
 render: h => h(App)
})

8、使用 HappyPack 多進(jìn)程解析和處理文件

  • 由于運(yùn)行在 Node.js 之上的 Webpack 是單線程模型的,所以 Webpack 需要處理的事情需要一件一件的做,不能多件事一起做。
  • HappyPack 就能讓 Webpack 把任務(wù)分解給多個(gè)子進(jìn)程去并發(fā)的執(zhí)行,子進(jìn)程處理完后再把結(jié)果發(fā)送給主進(jìn)程。
  • HappyPack 對(duì) file-loader、url-loader 支持的不友好,所以不建議對(duì)該 loader 使用。

使用方法如下:

1、HappyPack 插件安裝: npm i -D happypack
2、webpack.base.conf.js 文件對(duì) module.rules 進(jìn)行配置

module: {
 rules: [
  {
   test: /\.js$/,
   use: ['happypack/loader?id=babel'],
   include: [resolve('src'), resolve('test')],
   exclude: path.resolve(__dirname, 'node_modules')
  },
  {
   test: /\.vue$/,
   use: ['happypack/loader?id=vue']
  }
 ]
}

3、在生產(chǎn)環(huán)境 webpack.prod.conf.js 文件進(jìn)行配置

const HappyPack = require('happypack')
// 構(gòu)造出共享進(jìn)程池,在進(jìn)程池中包含5個(gè)子進(jìn)程
const HappyPackThreadPool = HappyPack.ThreadPool({ size: 5 })
plugins: [
 new HappyPack({
  // 用唯一的標(biāo)識(shí)符id,來代表當(dāng)前的HappyPack是用來處理一類特定的文件
  id: 'babel',
  // 如何處理.js文件,用法和Loader配置中一樣
  loaders: ['babel-loader?cacheDirectory'],
  threadPool: HappyPackThreadPool
 }),
 new HappyPack({
  id: 'vue', // 用唯一的標(biāo)識(shí)符id,來代表當(dāng)前的HappyPack是用來處理一類特定的文件
  loaders: [
   {
    loader: 'vue-loader',
    options: vueLoaderConfig
   }
  ],
  threadPool: HappyPackThreadPool
 })
]

總結(jié)

  • 比較實(shí)用的方法: 按需加載,優(yōu)化loader配置,關(guān)閉生產(chǎn)環(huán)境的sourceMap,CDN優(yōu)化。
  • vue-cli已做的優(yōu)化: 代碼壓縮,提取公共代碼,再優(yōu)化空間不大。
  • 根據(jù)項(xiàng)目實(shí)際需要和自身開發(fā)水平選擇優(yōu)化方法,必須避免因?yàn)閮?yōu)化產(chǎn)生bug。

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持億速云。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請(qǐng)聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI