- 打包速度:优化打包速度,主要是进步了咱们的开发功率,更快的打包构建过程,将让你保持一颗愉悦的心
- 打包体积:优化打包体积,主要是进步产品的运用体验,降低服务器资源成本,更快的页面加载,将让产品显得更加“丝滑”,同时也能够让打包更快
webpack 打包速度优化
webpack 进行打包速度优化有七种常用手段
1. 优化 loader 查找规模
关于 loader 来说,影响打包功率首战之地必属 Babel 了。因为 Babel 会将代码转为字符串生成 AST,然后对 AST 继续进行改变最后再生成新的代码,项目越大,转换代码越多,功率就越低。优化正则匹配、运用 include 和
exclude 指定需求处理的文件,疏忽不需求处理的文件
rules: [{
// 优化正则匹配
test: /.js$/,
// 指定需求处理的目录
include: path.resolve(__dirname, 'src')
// 理论上只有include就够了,可是某些状况需求排除文件的时分能够用这个,排除不需求处理文件
// exclude: []
}]
2. 多进程/多线程
受限于 node 是单线程运行的,所以 webpack 在打包的过程中也是单线程的,特别是在执行 loader 的时分,长期编译的任务
许多,这样就会导致等候的状况。咱们能够运用一些方法将 loader 的同步执行转换为并行,这样就能充分利用系统资源来进步
打包速度了
{
test: /.js?$/,
exclude: /node_modules/,
use: [
{
loader: "thread-loader",
options: {
workers: 3 // 进程 3 个
}
},
{
loader: "babel-loader",
options: {
presets: ["@babel/preset-env"],
plugins: ["@babel/plugin-transform-runtime"]
}
}
]
},
3. 分包
在运用 webpack 进行打包时分,关于依靠的第三方库,比方 vue,vuex 等这些不会修改的依靠,咱们能够让它和咱们自己编写
的代码分隔打包,这样做的好处是每次更改我本地代码的文件的时分,webpack 只需求打包我项目本身的文件代码,而不会再
去编译第三方库,那么第三方库在第一次打包的时分只打包一次,以后只需咱们不升级第三方包的时分,那么 webpack 就不会
对这些库去打包,这样能够快速进步打包的速度。因而为了解决这个问题,DllPlugin 和 DllReferencePlugin 插件就产生了。这种
方法能够极大的削减打包类库的次数,只有当类库更新版本才需求从头打包,而且也完成了将公共代码抽离成独自文件的优化方案
// webpack.dll.conf.js
const path = require('path')
const webpack = require('webpack')
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')
module.exports = {
mode: 'production',
devtool: false,
entry: {
vue: [
'vue',
'vue-router',
'iscroll',
'vuex'
],
},
output: {
path: path.join(__dirname, '../dist'),
filename: 'lib/[name]_[hash:4].dll.js',
library: '[name]_[hash:4]'
},
performance: {
hints: false,
maxAssetSize: 300000, //单文件超越300k,命令行告警
maxEntrypointSize: 300000, //初次加载文件总和超越300k,命令行告警
},
optimization: {
minimizer: [
new UglifyJsPlugin({
parallel: true // 敞开多线程并行
})
]
},
plugins: [
new webpack.DllPlugin({
context: __dirname,
path: path.join(__dirname, '../dist/lib', '[name]-manifest.json'),
name: '[name]_[hash:4]'
})
]
}
// webpack.prod.cong.js
plugins: [
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require('../dist/lib/vue-manifest.json')
}),
]
4. 敞开缓存
当设置 cache.type:“filesystem”时,webpack 会在内部以分层方法启用文件系统缓存和内存缓存,将处理结果结存放到内存中,
下次打包直接运用缓存结果而不需求从头打包
{
type: "filesystem",
// cacheDirectory 默许途径是 node_modules/.cache/webpack
// cacheDirectory: path.resolve(__dirname, '.temp_cache')
}
5. 打包剖析东西
显示测量打包过程中各个插件和 loader 每一步所耗费的时刻,然后让咱们能够有针对的剖析项目中耗时的模块对其进行处理。
npm install speed-measure-webpack-plugin -D
// webpack.prod.config.js
const SpeedMeatureWebpackPlugin = require("speed-measure-webpack-plugin");
const smp = new SpeedMeatureWebpackPlugin();
var webpackConfig = merge(baseWebpackConfig,{})
--> 修改为下面格局
var webpackConfig = {...}
module.exports = webpackConfig
--> 修改为下面格局
module.exports = smp.wrap(merge(baseWebpackConfig, webpackConfig));
6. ignorePlugin
这是 webpack 内置插件, 它的效果是疏忽第三方包指定目录,让这些指定目录不要被打包进去,防止在 import 或 require 调用时,生成以下正则表达式匹配的模块
- requestRegExp 匹配( test )资源恳求途径的正则表达式。
- contextRegExp( 可选 )匹配( test )资源上下文( 目录 )的正则表达式
new webpack.IgnorePlugin({
resourceRegExp: /^./test$/,
contextRegExp: /test$/,
})
7. 优化文件途径
- alias:省下查找文件的时刻,让 webpack 更快找到途径
- mainFiles:解析目录时要运用的文件名
- extensions:指定需求查看的扩展名,装备之后能够不用在 require 或是 import 的时分加文件扩展名,会顺次尝试增加扩展名进行匹配
resolve: {
extensions: ['.js', '.vue'],
mainFiles: ['index'],
alias: {
'@': resolve('src'),
}
}
webpack 打包体积优化
webpack打包体积优化有11种常用优化手段
1. 构建体积剖析
npm run build 构建,会默许翻开: http://127.0.0.1:8888/,能够看到各个包的体积,剖析项目各模块的巨细,能够按需优化。
npm install webpack-bundle-analyzer -D
const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;
plugins:[
new BundleAnalyzerPlugin()
]
- 项目图片资源优化紧缩处理
对打包后的图片进行紧缩和优化,降低图片分辨率,紧缩图片体积等
npm install image-webpack-loader -D
// webpack.base.conf.js
{
test: /.(gif|png|jpe?g|svg|webp)$/i,
type: "asset/resource",
parser: {
dataUrlCondition: {
maxSize: 8 * 1024
}
},
generator: {
filename: "images/[name].[hash:6][ext]"
},
use: [
{
loader: "image-webpack-loader",
options: {
mozjpeg: {
progressive: true,
quality: 65
},
optipng: {
enabled: false
},
pngquant: {
quality: [0.5, 0.65],
speed: 4
},
gifsicle: {
interlaced: false
},
webp: {
quality: 75
}
}
}
]
}
3. 删去无用的 css 款式
有时分一些项目中可能会存在一些 css 款式被迭代废弃,需求将其删去,能够运用 purgecss-webpack-plugin插件,该插件能够去
除未运用的 css。
npm install purgecss-webpack-plugin glod -D
// webpack.prod.conf.js
const PurgeCSSPlugin = require("purgecss-webpack-plugin");
const glob = require('glob')
const PATHS = {
src: path.join(__dirname, 'src')
}
// plugins
new PurgeCSSPlugin({
paths: glob.sync(`${PATHS.src}/**/*`, {nodir: true}),
safelist: ["body"]
}),
4. 代码紧缩
对 js 文件进行紧缩,然后减小 js 文件的体积,还能够紧缩 html、css 代码。
const TerserPlugin = require("terser-webpack-plugin");
optimization: {
minimize: true, //代码紧缩
usedExports:true, // treeshaking
minimizer:
[
new TerserPlugin({
terserOptions: {
ecma: undefined,
parse: {},
compress: {},
mangle: true, // Note `mangle.properties` is `false` by default.
module: false,
// Deprecated
output: null,
format: null,
toplevel: false,
nameCache: null,
ie8: false,
keep_classnames: undefined,
keep_fnames: false,
safari10: false
}
})
],
splitChunks:
{
cacheGroups: {
commons: {
name: "commons",
chunks: "initial",
minChunks: 2
}
}
}
}
5. 敞开 Scope Hoisting
Scope Hoisting又译作“效果域进步”。只需在装备文件中增加一个新的插件,就能够让 webpack 打包出来的代码文件更小、运行
的更快, Scope Hoisting会剖析出模块之间的依靠关系,尽可能的把打包出来的模块合并到一个函数中去,然后适当地重命名一
些变量以防止命名抵触。
new webpack.optimize.ModuleConcatenationPlugin();
6. 提取公共代码
将项目中的公共模块提取出来,能够削减代码的冗余度,进步代码的运行功率和页面的加载速度。
new webpack.optimize.CommonsChunkPlugin(options);
7. 代码别离
代码别离能够将工程代码别离到各个文件中,然后按需加载或并行加载这些文件,也用于获取更小的 bundle,以及操控资源加
载优先级,在装备文件中装备多进口,输出多个 chunk。
//多进口装备 终究输出两个chunk
module.exports = {
entry: {
index: 'index.js',
login: 'login.js'
},
output: {
//关于多进口装备需求指定[name]不然会呈现重名问题
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
8. Tree-shaking
treeshaking是一个术语,一般用于描述移除 JavaScript 上下文中的未引证代码( dead-code )。它依靠于 ES2015 模块语法的 静
态结构 特性,例如 import 和 export。
9. CDN 加快
CDN 的全称是 Content DeliveryNetwork,即内容分发网络。CDN 是构建在网络之上的内容分发网络,依靠部署在各地的边际
服务器,经过中心平台的负载均衡、内容分发、调度等功能模块,运用户就近获取所需内容,降低网络拥塞,进步用户访问响
应速度和命中率。CDN 的关键技能主要有内容存储和分发技能。在项目中以 CDN 的方法加载资源,项目中不需求对资源进行
打包,大大削减打包后的文件体积
10. 出产环境封闭 sourceMap
sourceMap 本质上是一种映射关系,打包出来的 js 文件中的代码能够映射到代码文件的具体位置,这种映射关系会协助咱们直接找到在源代码中的错误。但这样会使项目打包速度减慢,项目体积变大,能够在出产环境封闭 sourceMap
11. 按需加载
在开发项目的时分,项目中都会存在十几甚至更多的路由页面。假如咱们将这些页面悉数打包进一个文件的话,虽然将多个请
求合并了,可是同样也加载了许多并不需求的代码,耗费了更长的时刻。那么为了页面能更快地呈现给用户,咱们肯定是希望
页面能加载的文件体积越小越好,这时分咱们就能够运用按需加载,将每个路由页面独自打包为一个文件。以下是常见的按需
加载的场景
* 路由组件按需加载
* 按需加载需引进第三方组件
* 关于一些插件,假如只是在个别组件顶用的到,也能够不要在 main.js 里边引进,而是在组件中按需引进