媒介:在现实项目中,我们能够很少须要从头开始去设置一个webpack 项目,特别是webpack4.0宣布今后,零设置启动一个项目成为一种标配。正因为零设置的webpack对项目自身供应的“打包”和“紧缩”功用已做了优化,所以现实运用中,我们能够把精神更多专注在营业层面上,而无需分心于项目构建上的优化。然则从学习者的角度,我们须要相识webpack在项目标构建和打包紧缩过程当中做了哪些的优化,以及在原有默许设置上,还能够做哪些机能方面上的革新。
最近在完成vue的单页面运用后萌生了一个主意,扬弃掉vue-cli的构建设置,从零开始举行webpack优化,并将过程当中的思绪和体味分享在这篇文章中。webpack的初始设置在我之前写的另一篇
手把手教你从零熟悉webpack4.0文章中,以下内容也不对基本的webpack设置做过量论述。
一,优化的方向
1.1 项目开辟
对开辟者而言,我们愿望webpack这个东西能够给我们带来流通的开辟体验。比方,当不断修正代码时,我们愿望代码的变动能及时的关照浏览器革新页面,而不是手动去革新页面。更进一步的我们愿望,代码的修正只会部份替代某个模块,而不是全部页面的革新。如许能够使我们不须要在守候革新中糟蹋许多时刻,大大进步了页面的开辟效力。
1.2 项目布置
项目布置上线时,机能优化是我们斟酌的重点,有两个方向能够作为中心斟酌的点,一个是削减HTTP请求,我们晓得在网速雷同的前提下,下载一个100KB的图片比下载两个50KB的图片要快,因而,我们请求webpack将多个文件打包成一个或许少许个文件;另一个优化的重点是削减单次请求的时刻,也就是尽量削减请求文件的体积大小。
webpack中在机能优化所做的勤奋,也约略围绕着这两个大方向睁开。别的在构建项目中,我们也愿望能延续的进步构建效力。
二, 提拔开辟效力
2.1 削减体积
开辟环境下,我们依旧对代码的体积有肯定的请求,更小的体积能够让加载速率更快,开辟效力更高,固然设置也相对简朴。
// webpack.dev.js 开辟环境webpack设置
module.exports = {
devServer: {
contentBase: path.join(__dirname, 'dist'),
port: 9000,
compress: true, // 代码紧缩
},
}
2.2 模块热更新(HMR)
开辟过程当中,我们愿望修正代码的过程当中,页面能及时且不须要手动的革新。因而运用HRM, HMR 既防止了频仍手动革新页面,也削减了页面革新时的守候,大幅度进步了开辟效力。
// webpack.dev.js
module.exports = {
devServer: {
compress: true,
hot: true // 开启设置
},
plugins: [
new webpack.NamedModulesPlugin(),
new webpack.HotModuleReplacementPlugin(),
],
}
三,构建体积优化
3.1 临盆中的sourcemap 情势
webpack 在构建中供应了不少于7种的sourcemap情势,个中eval情势虽然能够进步构建效力,然则构建后的剧本较大,因而临盆上并不实用。而source-map 情势能够经由过程天生的 .map 文件来追踪剧本文件的 细致位置,进而减少剧本文件的体积,这是临盆情势的首选,而且在临盆中,我们须要隐蔽细致的剧本信息,因而能够运用 cheap 和module 情势来到达目标。
综上,在临盆的webpack devtool选项中,我们运用 cheap-module-source-map
的设置
// webpack.pro.js 临盆webpack设置剧本
module.exports = {
mode: 'production',
devtool: 'cheap-module-source-map',
}
3.2 自力css 文件
以单进口文件而论,一般我们会将页面的一切静态资本都打包成一个JS 文件,这已完成了1.2 中的优化部份,将代码兼并成一个静态资本,削减了HTTP 请求。
星散前
然则接下来,我们须要将css代码自力开来,为何呢?最主要的一点是我们愿望更好的应用浏览器的缓存,当零丁修正了款式时,自力的css文件能够不须要运用去加载全部的剧本文件,进步效力。而且,当碰到多页面的运用时,能够零丁将一些大众部份的款式抽脱离来,加载一个页面后,接下来的页面一样能够应用缓存来削减请求。
webpack4.0 中供应了抽离css文件的插件,mini-css-extract-plugin
,只须要简朴的设置便能够将css文件星散开来
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
module.exports = {
···
plugins: [
new MiniCssExtractPlugin({
filename: "[name].[contenthash].css",
chunkFilename: "[name].[contenthash].css"
})
],
module: {
rules: {
test: /\.(css|scss)$/,
use: [process.env.NODE_ENV == 'production' ? MiniCssExtractPlugin.loader : 'style-loader', {
loader: 'css-loader',
options: {
sourceMap: true
},
}, "sass-loader"]
}
}
···
}
星散后
3.3 紧缩js, html, css 文件
要想优化构建后的体积,不断削减静态资本文件的大小,我们愿望webpack协助我们尽量紧缩文件的体积。关于js 剧本文件而言,webpack4.0 在mode 为‘production’时,默许会启动代码的紧缩。除此之外,我们须要手动对html和css 举行紧缩。
针对html 的紧缩,只须要对html-webpack-plugin举行相干设置。
// webpack.base.js
module.exports = {
plugins: [
new HtmlWebpackPlugin({
title: 'minHTML',
filename: 'index.html',
template: path.resolve(__dirname, '../index.html'),
minify: { // 紧缩 HTML 的设置
collapseWhitespace: true,
removeComments: true,
useShortDoctype: true
}
}),
]
}
针对css 的紧缩, webpack4.0 运用optimize-css-assets-webpack-plugin
来紧缩零丁的css 文件。
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
module.exports = {
plugins: [
new OptimizeCSSAssetsPlugin()
],
}
对照之下,我们能够看到显著的效果,关于紧缩css 更多的设置能够参考optimize-css-assets-webpack-plugin
3.4. 兼并紧缩图片
处置惩罚完前端的三大块js,html,css后, 接下来优化能想到的是处置惩罚图片。前面提到,提拔机能的一个主要的前提是下降http请求数,而运用中经常会有大大小小的图片须要处置惩罚,对运用中的小图标来讲,css sprite 是首选,将种种图标集合成一张大的图片能够很好的削减收集请求数。而关于须要自力开的图片,且大小在合理局限内时,我们能够将图片转换成 base64位编码,内嵌到css 中,一样能够削减请求。
3.4.1 base64 转换
处置惩罚图片资本时,webpack 供应了 file-loader 和url-loader 两个loaders供挑选,file-loader 和url-loader 的作用,能够用来剖析项目中图片文件的url引入题目。二者的区分在于,url-loader 能够将小于指定字节的文件转为DataURL, 大于指定字节 的依旧会运用file-loader 举行剖析
// webpack.base.js
module.exports = {
module: {
rules: [{
test: /\.(png|jpe?g|gif|svg|ttf|woff2|woff)(\?.*)?$/,
use: [{
loader: 'url-loader',
options: {
limit: 10000, // 限制大小
}
},
]
},
}
3.4.2 紧缩图片
处置惩罚完雪碧图和小图片的base64转换后,关于大图片来讲,webpack还能够做到对图片举行紧缩,引荐运用image-webpack-loader
,插件供应了多种情势的紧缩,细致能够参考官网文档
// webpack.base.js
module.exports = {
module: {
rules: [
{
loader: 'image-webpack-loader',
options: {
optipng: { // 运用 imagemin-optipng 紧缩 png,enable: false 为封闭
enabled: true,
},
pngquant: { // 运用 imagemin-pngquant 紧缩 png
quality: '65-90',
speed: 4
},
}
}
]
}
}
效果对照方下:
3.5 依靠库星散
一个中大型运用中,第三方的依靠,巨大得恐怖,占有了打包后文件的一半以上。然则,这些依靠模块又是很少变动的资本,和css 代码星散的逻辑类似,星散第三方依靠库,能够更好的应用浏览器缓存,提拔运用机能。因而,将依靠模块从营业代码中星散是机能优化主要的一环。
webpack4.0 中,依靠库的星散只须要经由过程 optimization.splitChunks 举行设置即可。
// webpack.pro.js
module.exports = {
optimization: {
splitChunks: {
cacheGroups: {
vendor: {
chunks: "initial",
test: path.resolve(__dirname, "../node_modules"),
name: "vendor", // 运用 vendor 进口作为大众部份
enforce: true,
},
},
},
},
}
大众库星散后的效果
3.6 依靠剖析
正如前面所讲,在优化剖析中,现实影响体积最大的是 node_modules 的第三方库,这一部份的优化能够大大的削减打包后的体积。这里我们运用最新的webpack-bundle-analyzer
插件来剖析打包好后的模块,它能够将打包后的内容束展现位轻易交互的直观树状图,经由过程它,能够晓得项目大抵有哪些模块构成,哪一个模块占有的体积较大,是不是是可替代的。
我们大抵能够从几个方向斟酌
- 1.推断依靠是不是不可或缺,依靠在项目中运用率是不是太低。在项目中,能够针对某个运算,某个功用,我们运用了一个巨大的库,这个库在体积上的占比较大,而功用运用却较少。这个时刻我们能够寻觅体积更小,且功用满足的替代库,或许手动完成某些依靠的功用来替代他。
- 2.大型库是不是能够经由过程定制功用的体式格局削减体积。显著的一个例子是 echart, echart完全版的依靠紧缩后也有几百k 之多,这显现是难以接收的。现实项目中,我们能够只须要少许或许部份的echart 功用,这时候我们能够经由过程制订图表的情势,下载图表用到的功用,到达体积最优化。
- 3.某些不可优化的大型库是不是能够经由过程外部援用的体式格局削减文件体积。比方像bootstrap,vue这类没法优化的第三方库,经由过程免费开源的cdn效劳不只能够削减文件体积,还能够进步网站的加载速率,也是个优化机能的要领
3.7 按需加载
前面提到依靠剖析的方向中,假如大型库不可或缺,而且运用率也不算低的时刻,我们能够经由过程按需加载的情势。这类体式格局现实上是先把你的代码在一些逻辑断点处星散开,然后在一些代码块中完成某些操纵后,马上援用或行将援用别的一些新的代码块。如许加速了运用的初始加载速率,减轻了它的整体体积,因为某些代码块能够永久不会被加载。
webpack中应用require.ensure()完成按需加载,在不运用按需加载的情况下,首屏加载时会把一切的剧本同时加载出来,这每每会拖累首屏显现时刻,带来不好的用户体验。例子来讲。当项目须要运用大型的图表类库,而首页并不须要时,按需加载每每比同时加载在用户体验上好好得多。
当不须要按需加载的时刻,我们的代码多是如许的:
import test from './components/test.vue'
import test2 from './components/test2.vue'
开启按需加载时,我们的代码修正为:
const test = r => require.ensure([], () => r(require('./components/test.vue')), 'chunk1')
const test2 = r => require.ensure([], () => r(require('./components/test2.vue')), 'chunk2')
webpack 设置修正为
output: {
···
chunkFilename: '[name].[hash].js'
}
这时候编译出来的文件会从本来的一个,变成了多个小文件。每一个路由加载时会去加载差别的资本。特别在首屏的资本加载长进一步优化了运用的体验。
只管如此,现实中我们须要依据项目标需求来衡量按需加载的可用性,只管在首屏优化上获得较大的提拔,但按需加载毕竟会将大的文件拆分红多个小文件,增加了http 的请求数。这又违犯了机能优化的基本。所以现实中须要弃取,更须要衡量。
3.8 删除冗余代码
代码体积优化到这一步,基本能够优化的处所已优化终了了。接下来能够捉住一些细节做更细的优化。比方能够删除项目中上下文都未被援用的代码。这就是所谓的 Tree shaking 优化。webpack 4.0中,mode 为production 默许启动这一优化。然则,假如在项目中运用到babel的 话,须要把babel剖析语法的功用关掉。只须要
// .babelrc
{
"presets": [["env", { "modules": false }]]
}
四,构建速率优化
说完怎样削减项目构建后的大小后,接下来简朴的谈一下怎样进步构建的速率。现实上webpack的 构建速率,只须要简朴的修正设置便能大幅进步速率。罕见的设置以下。
4.1 babel-loader构建时刻太长
4.1.1 限制加载器作用局限
因为babel-loader须要将语法举行转换,所消耗的时刻较长,所以第一步须要限制babel-loader 作用的局限,让babel-loader 的搜刮和转换正确的定位到指定模块。大幅进步构建速率。
比方:
// webpack.base.js
module.exports = {
module:{
rules: [
{
test: /\.js$/,
include: [resolve('src')],// 限制局限
use: {
loader: 'babel-loader',
},
},]
}
}
4.1.2 缓存加载器实行效果
正因为babel-loader在剖析转换上耗时太长,所以我们愿望能缓存每次实行的效果。webpack的loader中恰好有 cacheDirectory 的选项,默许为false 开启后将运用缓存的实行效果,打包速率显著提拔。
// webpack.base.js
module.exports = {
module: {
rules: [
{
test: /\.js$/,
include: [resolve('src')],
use: {
loader: 'babel-loader?cacheDirectory',
},
},]
}
}
4.2 resolve 剖析优化
webpack 的resolve 做相干的设置后,也能够让项目标构建速率加速。细致看下文的设置:
- 当项目中涌现 import ‘react’ 既不是绝对途径也不是相对途径时,指定好搜刮的途径,能够不必过量的查询
- 尽量少的运用 resolve.alias 来设置途径别号,因为会影响到tree shaking 的优化
- 后缀自动补全尽量的少。削减途径查询的事情
- 当运用的第三方库过大,而且不包括import require define 的挪用。能够运用noParse让库不被loaders 剖析
// webpack.base.js
module.exports = {
resolve: {
modules: [
path.resolve(__dirname, 'node_modules'),
],
extensions: [".js"],
// 防止新增默许文件,编码时运用细致的文件途径,代码会更轻易解读,也有益于进步构建速率
mainFiles: ['index'],
},
module: {
noParse: function(content){
return /jquery/.test(content)
}
}
}
五,结语
webpack机能优化的瓶颈照样集合在构建时刻和构建体积上,作为构建东西业界霸主,webpack一向不断的优化构建打包流程。经由过程对旧有项目标优化也能够对webpack这个东西以及机能优化的学问有更深的相识。
转载请说明出处
https://blog.csdn.net/yuanyan…