webpack打包后的效果_webpack 打包优化的四种方法(多进程打包,多进程压缩,资源 CDN,动态 polyfill)...

如今,webpack 毫无疑问是前端构建领域里最耀眼的一颗星,无论你前端走哪条路线,都需要有很强的webpack 知识。webpack 的基本用法这里就不展开讲了。主要探讨一下如何提高 webpack 的打包速度。

这篇文章以 vue cli3.0+,webpack4.0+,nodejs10.0+ 这几个版本为例。

一、打包分析

1.1、速度分析

我们的目的是优化打包速度,那肯定需要一个速度分析插件,此时 speed-measure-webpack-plugin 就派上用场了。它的作用如下:

分析整个打包总耗时

每个 plugin 和 loader 的耗时情况

首先,安装插件

npm i -D speed-measure-webpack-plugin

然后修改 vue.config.js 配置文件 (vuecli3+ 版本的配置文件统一在这个文件里修改,如果没有该文件,在根目录新建一个)

// 导入速度分析插件

const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");

// 实例化插件

const smp = new SpeedMeasurePlugin();

module.exports = {

configureWebpack: smp.wrap({

plugins: [

// 这里是自己项目里需要使用到的其他插件

new yourOtherPlugin()

]

})

}

运行打包命令之后,可以看到,打包总耗时为 2min,51.99s

1.2、体积分析

分析完打包速度之后,接着我们来分析打包之后每个文件以及每个模块对应的体积大小。使用到的插件为 webpack-bundle-analyzer,构建完成后会在 8888 端口展示大小。

首先,安装插件

npm i -D webpack-bundle-analyzer

修改 vue.config.js 配置文件

// 导入速度分析插件

const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");

// 导入体积分析插件

const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;

// 实例化速度分析插件

const smp = new SpeedMeasurePlugin();

module.exports = {

configureWebpack: smp.wrap({

plugins: [

// 实例化体积分析插件

new BundleAnalyzerPlugin()

]

})

}

构建之后可以看到,其中黄色块 chunk-vendors 文件占比最大,为 1.34MB

二、打包优化

2.1、多进程多实例构建,资源并行解析

多进程构建的方案比较知名的有以下三个:

thread-loader (推荐使用这个)

parallel-webpack

HappyPack

这里以 thread-loader 为例配置多进程多实例构建

安装 loader

npm i -D thread-loader

接下来在 vue.config.js 配置文件中使用该 loader

// 导入速度分析插件

const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");

// 实例化插件

const smp = new SpeedMeasurePlugin();

module.exports = {

configureWebpack: smp.wrap({

module: {

rules: [

{

test: /\.js$/,

use: ['thread-loader']

}

]

}

})

}

然后看下构建花费的时间, 2min,49.21s,相较于之前提升了 5s

2.2、公用代码提取,使用 CDN 加载

对于vue,vuex,vue-router,axios,echarts,swiper等我们可以利用webpack的externals参数来配置,这里我们设定只需要在生产环境中才需要使用。

下面配置 vue.config.js

// 导入速度分析插件

const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");

// 导入体积分析插件

const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;

//判断是否为生产环境

const isProduction = process.env.NODE_ENV === 'production';

//定义 CDN 路径,这里采用 bootstrap 的 cdn

const cdn = {

css: [

'https://cdn.bootcss.com/Swiper/4.5.1/css/swiper.min.css'

],

js: [

'https://cdn.bootcss.com/vue/2.6.10/vue.min.js',

'https://cdn.bootcss.com/vue-router/3.1.3/vue-router.min.js',

'https://cdn.bootcss.com/vuex/3.1.1/vuex.min.js',

'https://cdn.bootcss.com/axios/0.19.0/axios.min.js',

'https://cdn.bootcss.com/echarts/4.3.0/echarts.min.js',

'https://cdn.bootcss.com/Swiper/4.5.1/js/swiper.min.js',

]

}

// 实例化插件

const smp = new SpeedMeasurePlugin();

module.exports = {

chainWebpack: config => {

// 生产环境配置

if (isProduction) {

// 生产环境注入 cdn

config.plugin('html')

.tap(args => {

args[0].cdn = cdn;

return args;

});

}

},

configureWebpack: smp.wrap({

module: {

rules: [

{

test: /\.js$/,

use: ['thread-loader']

}

]

},

plugins: [

new BundleAnalyzerPlugin()

],

//生产环境注入 cdn

externals: isProduction && {

'vue': 'Vue',

'vuex': 'Vuex',

'vue-router': 'VueRouter',

'axios': 'axios',

'echarts': 'echarts',

'swiper': 'Swiper'

} || {}

})

}

紧接着,改造 html 页面。用于让我们配置的 cdn 路径注入到 html 页面

We're sorry but eye-admin doesn't work properly without JavaScript enabled. Please enable it to continue.

最重要的一步,看下效果,可以看到现在耗时 1min,39.19s,整整提升了 1 分多钟!

2.3、多进程多实例并行压缩

并行压缩主流有以下三种方案

使用 parallel-uglify-plugin 插件

uglifyjs-webpack-plugin 开启 parallel 参数

terser-webpack-plugin 开启 parallel 参数 (推荐使用这个,支持 ES6 语法压缩)

安装插件依赖

npm i -D terser-webpack-plugin

接下来在 vue.config.js 配置文件中使用插件,最终的配置文件如下

// 导入速度分析插件

const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");

// 导入代码压缩插件

const TerserPlugin = require("terser-webpack-plugin");

// 导入体积分析插件

const BundleAnalyzerPlugin = require("webpack-bundle-analyzer").BundleAnalyzerPlugin;

//判断是否为生产环境

const isProduction = process.env.NODE_ENV === 'production';

//定义 CDN 路径,这里采用 bootstrap 的 cdn

const cdn = {

css: [

'https://cdn.bootcss.com/Swiper/4.5.1/css/swiper.min.css'

],

js: [

'https://cdn.bootcss.com/vue/2.6.10/vue.min.js',

'https://cdn.bootcss.com/vue-router/3.1.3/vue-router.min.js',

'https://cdn.bootcss.com/vuex/3.1.1/vuex.min.js',

'https://cdn.bootcss.com/axios/0.19.0/axios.min.js',

'https://cdn.bootcss.com/echarts/4.3.0/echarts.min.js',

'https://cdn.bootcss.com/Swiper/4.5.1/js/swiper.min.js',

]

}

// 实例化插件

const smp = new SpeedMeasurePlugin();

module.exports = {

chainWebpack: config => {

// 生产环境配置

if (isProduction) {

// 生产环境注入 cdn

config.plugin('html')

.tap(args => {

args[0].cdn = cdn;

return args;

});

}

},

configureWebpack: smp.wrap({

module: {

rules: [

{

test: /\.js$/,

use: ['thread-loader']

}

]

},

plugins: [

new BundleAnalyzerPlugin()

],

//生产环境注入 cdn

externals: isProduction && {

'vue': 'Vue',

'vuex': 'Vuex',

'vue-router': 'VueRouter',

'axios': 'axios',

'echarts': 'echarts',

'swiper': 'Swiper'

} || {},

optimization: {

minimizer: [

new TerserPlugin({

parallel: 4

})

]

}

})

}

2.4、使用 polyfill 动态服务

动态 polyfill 指的是根据不同的浏览器,动态载入需要的 polyfill。 Polyfill.io 通过尝试使用 polyfill 重新创建缺少的功能,可以更轻松地支持不同的浏览器,并且可以大幅度的减少构建体积。

Polyfill Service 原理

识别 User Agent,下发不同的 Polyfill

使用方法:在 index.html 中引入如下 script 标签

三、完结

At last,看完之后有什么不懂的,可以留言反馈。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值