当前位置: 首页 > 编程笔记 >

webpack打包优化的几个方法总结

夹谷和裕
2023-03-14
本文向大家介绍webpack打包优化的几个方法总结,包括了webpack打包优化的几个方法总结的使用技巧和注意事项,需要的朋友参考一下

为什么要优化打包?

  • 项目越做越大,依赖包越来越多,打包文件太大
  • 单页面应用首页白屏时间长,用户体验差

我们的目的

  • 减小打包后的文件大小
  • 首页按需引入文件
  • 优化 webpack 打包时间

优化方式

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 对于一些插件,如果只是在个别组件中用的到,也可以不要在 main.js 里面引入,而是在组件中按需引入

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

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

2、优化 loader 配置

  • 优化正则匹配
  • 通过 cacheDirectory 选项开启缓存
  • 通过 include、exclude 来减少被处理的文件。
module: {
 rules: [
  {
   test: /\.js$/,
   loader: 'babel-loader?cacheDirectory',
   include: [resolve('src')]
  }
 ]
}

3、优化文件路径——省下搜索文件的时间

  • extension 配置之后可以不用在 require 或是 import 的时候加文件扩展名,会依次尝试添加扩展名进行匹配。
  • mainFiles 配置后不用加入文件名,会依次尝试添加的文件名进行匹配
  • alias 通过配置别名可以加快 webpack 查找模块的速度。
 resolve: {
  extensions: ['.js', '.vue', '.json'],
  alias: {
   'vue$': 'vue/dist/vue.esm.js',
   '@': resolve('src'),
  }
 },

4、生产环境关闭 sourceMap

  • sourceMap 本质上是一种映射关系,打包出来的 js 文件中的代码可以映射到代码文件的具体位置,这种映射关系会帮助我们直接找到在源代码中的错误。
  • 打包速度减慢,生产文件变大,所以开发环境使用 sourceMap,生产环境则关闭。

5、代码压缩

  • UglifyJS: vue-cli 默认使用的压缩代码方式,它使用的是单线程压缩代码,打包时间较慢
  • ParallelUglifyPlugin: 开启多个子进程,把对多个文件压缩的工作分别给多个子进程去完成

两种方法使用如下:

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

 new ParallelUglifyPlugin({
  //缓存压缩后的结果,下次遇到一样的输入时直接从缓存中获取压缩后的结果并返回,
  //cacheDir 用于配置缓存存放的目录路径。
  cacheDir: '.cache/',
  sourceMap: true,
  uglifyJS: {
   output: {
    comments: false
   },
   compress: {
    warnings: false
   }
  }
 })
]

6、提取公共代码

  • 相同资源重复被加载,浪费用户流量,增加服务器成本。
  • 每个页面需要加载的资源太大,导致网页首屏加载缓慢,影响用户体验。

webpack3 使用 CommonsChunkPlugin 的实现:

plugins: [
 new webpack.optimize.CommonsChunkPlugin({
  name: 'vendor',
  minChunks: function(module, count) {
   console.log(module.resource, `引用次数${count}`)
   //"有正在处理文件" + "这个文件是 .js 后缀" + "这个文件是在 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 的实现:

module.exports = {
 optimization: {
  splitChunks: {
   cacheGroups: {
    vendor: {
     priority: 1, //添加权重
     test: /node_modules/, //把这个目录下符合下面几个条件的库抽离出来
     chunks: 'initial', //刚开始就要抽离
     minChunks: 2 //重复2次使用的时候需要抽离出来
    },
    common: {
     //公共的模块
     chunks: 'initial',
     minChunks: 2
    }
   }
  }
 }
}

7、CDN 优化

  1. 随着项目越做越大,依赖的第三方 npm 包越来越多,构建之后的文件也会越来越大。
  2. 再加上又是单页应用,这就会导致在网速较慢或者服务器带宽有限的情况出现长时间的白屏。

1、将 vue、vue-router、vuex、element-ui 和 axios 这五个库,全部改为通过 CDN 链接获取,在 index.html 里插入 相应链接。

<head>
 <link rel="stylesheet" href="https://cdn.bootcss.com/element-ui/2.0.7/theme-chalk/index.css" 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 多进程解析和处理文件

  • 由于运行在 Node.js 之上的 Webpack 是单线程模型的,所以 Webpack 需要处理的事情需要一件一件的做,不能多件事一起做。
  • HappyPack 就能让 Webpack 把任务分解给多个子进程去并发的执行,子进程处理完后再把结果发送给主进程。
  • HappyPack 对 file-loader、url-loader 支持的不友好,所以不建议对该 loader 使用。

使用方法如下:

1、HappyPack 插件安装: npm i -D happypack
2、webpack.base.conf.js 文件对 module.rules 进行配置

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、在生产环境 webpack.prod.conf.js 文件进行配置

const HappyPack = require('happypack')
// 构造出共享进程池,在进程池中包含5个子进程
const HappyPackThreadPool = HappyPack.ThreadPool({ size: 5 })
plugins: [
 new HappyPack({
  // 用唯一的标识符id,来代表当前的HappyPack是用来处理一类特定的文件
  id: 'babel',
  // 如何处理.js文件,用法和Loader配置中一样
  loaders: ['babel-loader?cacheDirectory'],
  threadPool: HappyPackThreadPool
 }),
 new HappyPack({
  id: 'vue', // 用唯一的标识符id,来代表当前的HappyPack是用来处理一类特定的文件
  loaders: [
   {
    loader: 'vue-loader',
    options: vueLoaderConfig
   }
  ],
  threadPool: HappyPackThreadPool
 })
]

总结

  • 比较实用的方法: 按需加载,优化loader配置,关闭生产环境的sourceMap,CDN优化。
  • vue-cli已做的优化: 代码压缩,提取公共代码,再优化空间不大。
  • 根据项目实际需要和自身开发水平选择优化方法,必须避免因为优化产生bug。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持小牛知识库。

 类似资料:
  • 主要内容:1.哪些问题会引起接口性能问题,2.问题解决1.哪些问题会引起接口性能问题 数据库慢查询 深度分页问题 未加索引 索引失效 join过多 子查询过多 in中的值太多 单纯的数据量过大 业务逻辑复杂 循环调用 顺序调用 线程池设计不合理 锁设计不合理 机器问题(fullGC,机器重启,线程打满) 2.问题解决 2.1 慢查询(基于mysql) 深度分页 当分页所以深度不大的时候当然没问题,随着分页的深入 这个时候,mysql会查出来10000

  • 本文向大家介绍vue webpack打包优化操作技巧,包括了vue webpack打包优化操作技巧的使用技巧和注意事项,需要的朋友参考一下 临近春节,公司很多同事都提前回家过年,剩余人员根据禅道去修改bug,当bug修正完毕以后,我们需要重新打包给运维,上测试服给测试同事提测,但是由于项目本体比较庞大,所以打包时间太过漫长(二十五分钟以上:sob:),所以有了打包优化的想法(其实想法早就有了,但是

  • 本文向大家介绍浅谈React + Webpack 构建打包优化,包括了浅谈React + Webpack 构建打包优化的使用技巧和注意事项,需要的朋友参考一下 本文介绍了React + Webpack 构建打包优化,分享给大家,具体如下: 使用 babel-react-optimize 对 React 代码进行优化 检查没有使用的库,去除 import 引用 按需打包所用的类库,比如 lodash

  • 本文向大家介绍Android中ListView的几种常见的优化方法总结,包括了Android中ListView的几种常见的优化方法总结的使用技巧和注意事项,需要的朋友参考一下 Android中的ListView应该算是布局中几种最常用的组件之一了,使用也十分方便,下面将介绍ListView几种比较常见的优化方法: 首先我们给出一个没有任何优化的Listview的Adapter类,我们这里都继承自B

  • 本文向大家介绍Webpack实现按需打包Lodash的几种方法详解,包括了Webpack实现按需打包Lodash的几种方法详解的使用技巧和注意事项,需要的朋友参考一下 前言 在数据操作时,Lodash 就是我的弹药库,不管遇到多复杂的数据结构都能用一些函数轻松拆解。 ES6 中也新增了诸多新的对象函数,一些简单的项目中 ES6 就足够使用了,但还是会有例外的情况引用了少数的 Lodash 函数。一

  • 本文向大家介绍webpack打包多页面的方法,包括了webpack打包多页面的方法的使用技巧和注意事项,需要的朋友参考一下 前言 一开始接触webpack是因为使用Vue的关系,因为Vue的脚手架就是使用webpack构建的。刚开始的时候觉得webpack就是为了打包单页面而生的,后来想想,这么好的打包方案,只在单页面上使用是否太浪费资源了呢?如果能在传统多页面上使用webpack,开始效率是否会