关于前端:多页面应用升级webpack5带来的编译优化

7次阅读

共计 4848 个字符,预计需要花费 13 分钟才能阅读完成。

1、背景

以后网站我的项目采纳的是多页面,开发和重构拆散,开发新页面时,因为重构开发可能常常会增加款式文件或者调整款式程序,因而小组采纳了如下开发模式

随着页面越来越多,依赖的款式文件变多,gulp工作也随之变多,打包编译速度慢的问题逐步裸露进去,这种模式下的打包工夫截图如下:

能够看到 gulp 工作大概须要 30s, webpack 工作须要30s, 加起来第一次构建须要 1 分多钟,而二次构建也须要 8 秒左右,设想每次构建脑袋中都跳出这个场景,这能忍耐?可见曾经到了必(ren) 须(wu)要 (ke) 改(ren)的境地了好吗

于是决定批改以后构建形式,分为以下步骤进行

1、去掉 gulp
批改后的模式如下图,其中绿色为新增流程,和原流程相比去掉了 gulp 打包 css 流程转而也交给 webpack 解决

切换到这种模式后,第一次打包工夫大概 20s, 增量编译大略 8s

2、webpack构建速度优化

2.1 exclude include优化

在匹配规定里指定须要解决和排除在外不解决的文件,放大查找和解决文件范畴,确保编译尽可能少的文件,针对我的项目状况增加对应的 includeexclude配置,具体配置如下

rules: [
    {test: /\.[jt]s$/,
        include: [path.resolve(process.cwd(), 'src')],
        exclude: [/node_modules/, path.resolve(process.cwd(), 'src/vendor')],
    },
    {
        test: /\.css$/,
        include: RESOURCES.CSS.cwd,
    }
]

加上下面配置后,第一次打包工夫大概 16s, 增量编译大略 8s

2.2 thread-loaderesbuild-loader 优化

thread-loader是采纳多过程打包的形式,放在 thread-loader 前面的 loader 会独自的 worker 池里运行,
esbuild是由 Go 开发的用于打包压缩 tsjs 的工具,特点是打包速速很快,官网 github 介绍与 webpack, rollup, Parcel 相比拟要快几十甚至上百倍,然而 esbuild 目前还不能反对 css, 并且没有插件机制,所以目前临时代替不了 webpack,然而有用于 webpack 中的 loaderesbuild-loader, 引入一下试一下成果, ViteSnowpack 底层都采纳了 esbuild,参考thread-loader 官网阐明和 esbuild-loader 官网阐明后要害配置如下

const cpuNum = require('os').cpus().length;

const tsWorkerPool = {
    workers: 6,
    poolTimeout: Infinity
};

const cssWorkerPool = {
    workers: cpuNum - tsWorkerPool.workers,
    poolTimeout: Infinity
};

threadLoader.warmup(tsWorkerPool, ['esbuild-loader']);
threadLoader.warmup(cssWorkerPool, ['css-loader']);

module: {
    rules: [
        {test: /\.[jt]s$/,
            use: [
                {
                    loader: 'thread-loader',
                    options: tsWorkerPool
                },
                {
                    loader: 'esbuild-loader',
                    options: {
                        loader: 'ts',
                        target: 'es2015',
                        tsconfigRaw: require('../tsconfig.json')
                    },
                },
                {loader: path.resolve(__dirname, 'loaders/importcss-loader.js'),
                    options: {include: path.resolve(process.cwd(), 'src/app'),
                    }
                },
            ],
            include: [path.resolve(process.cwd(), 'src')],
            exclude: [/node_modules/, path.resolve(process.cwd(), 'src/vendor')],
        },
        {
            test: /\.css$/,
            use: [
                {loader: MiniCssExtractPlugin.loader,},
                {
                    loader: 'thread-loader',
                    options: cssWorkerPool
                },
                {
                    loader: 'css-loader',
                    options: {esModule: false,}
                },
                {
                    loader: 'esbuild-loader',
                    options: {
                        loader: 'css',
                        minify: true
                    }
                }
            ],
            include: RESOURCES.CSS.cwd,
        }
    ],
},

通过测试,加上 thread-loader 后,第一次打包工夫大概 12s, 增量编译大略3s, 再加上esbuild-loader 后,第一次打包工夫缩短到 8s 左右,增量编译大略 2s
留神: https://esbuild.github.io/api/#target文档中提到针对大部分语法 esbuild-loader 只反对转换到es6,因而只适宜在开发环境应用,生产环境不倡议应用

2.3 图片压缩和去掉冗余 css 款式文件

图片压缩配置如下

loader: 'image-webpack-loader',
options: {
    // 生产环境启用压缩
    disable: process.env.NODE_ENV === 'production' ? false : true,
    // 压缩 jpg/jpeg 图片
    mozjpeg: {
        progressive: true,
        quality: 80 // 压缩率
    },
    // 压缩 png 图片
    pngquant: {quality: [0.65, 0.90],
        speed: 4
    }
}

去掉冗余款式应用 purgecss 插件,配置如下, 须要针对非凡的不能去除的加上配置

new PurgecssPlugin({
    paths: glob.sync([path.resolve(__dirname, '../../server/views/**/*.html'),
        path.resolve(`${PATH.SRC}/**/*.vue`),
    ]),
    safelist: [
        /data-v-.*/, // vue scope 款式保留
        /market-message/, // 解决营销告诉栏背景色彩由配置决定导致须要剔除款式不确定的非凡解决
        /vip/, // 动静渲染 vip 等级款式保留
    ]
})

3、降级到webpack5

webpack去年公布了 webpack5 带来了很多优化,次要几点比方:
1、默认开启长久化缓存并缓存在内存中,而 webpack4 则须要借助 cache-loaderhard-source-webpack-plugin来做缓存
2、NodeJSpolyfill脚本被移除, 而在 webpack4 及以前的版本中,对于大多数的 Node 模块将主动增加 polyfill 脚本,导致打包后体积会变大。
3、更好的 TreeShaking
通过下面优化后,想进一步测试一下 webpack5 版本能带来的优化成果,将 webpack 包和相干依赖降级到最新版本,去掉不兼容的 speed-measure-webpack-plugin 和曾经不须要的 hard-source-webpack-plugin 插件后,解决大略 65 个文件,第一次打包工夫缩短到 6.5s 左右,增量编译工夫 1.5s 左右,能够看到工夫进一步缩短。

4、热加载和热更新

webpack.dev.js中增加以下配置

devServer: {contentBase: path.join(PATH.DIST, 'js'),
    inline: true,
    compress: true,
    port: 5000,
    writeToDisk: true,
    host: '0.0.0.0',
    hot: true,
    disableHostCheck: true,
    headers: {
        'Access-Control-Allow-Origin': 'https://www.midasbuy.com',
        'Access-Control-Allow-Headers': '*',
        'Access-Control-Allow-Methods': '*',
        'Access-Control-Allow-Credentials': true,
    },
},

因为咱们开发时是用的 whistle 代理配合域名拜访, 在检测到文件文件更新时是通过 websocket 来进行音讯告诉的,因而须要在 whistle 中增加规定如下, 第一条是建设 websocket 连贯,第二条用于热更新时申请更新的内容, 这里次要实现了 vue 组件的热更新和 js 的热刷新,css 热跟新临时没实现。

https://www.midasbuy.com:5000 http://127.0.0.1:5000/
^https://www.midasbuy.com/oversea_web/static/***hot-update***  http://127.0.0.1:5000/oversea_web/static/$1hot-update$2

坑:测试热刷新时,批改了文件, 页面刷新后展现如下报错

而后再次手动刷新就好了,半天没找到起因,一度还狐疑是 whistle 代理的起因,之后狐疑是发送告诉更新指令太早了,而后写了一个 hack 办法来提早发送更新指令,发现能够了,然而具体起因还没找到,直到切换到服务端终端,更新文件时看到了如下打印

才明确了,咱们的流程是 client 端编译好文件后,会将文件复制到 server 文件夹上面来提供给 ejs include 进来应用,server应用了 nodemon,文件变更时会进行复制文件操作,触发了nodemon 的重启导致浏览器 reload 时申请失败,所以解决办法是在 nodemon 配置文件中把复制文件的目录疏忽掉,因为复制的真正内容是 <style link='*****'></style><script src='*****'></script>这样的内容,所以齐全是能够疏忽的,疏忽后文件变更时服务端也不会重启,问题解决。

5、vue devtools定位到组件目录

针对 vue devtools 提供的在浏览器抉择组件时,点击时能够间接关上编译器并关上组件所在源代码文件,参考文档在 webpack.dev.js 下新增上面配置

const openInEditor = require('launch-editor-middleware');

devServer: {
    ...
    before(app) {app.use('/__open-in-editor', openInEditor('code', path.resolve(process.cwd(), 'src')));
    },
},

whistle 增加一行规定

https://www.midasbuy.com/__open-in-editor http://127.0.0.1:5000/__open-in-editor

如下图,点击圈出的该地位时会关上 vscode 编辑器并定位到组件对应源文件代码

6、总结

MacBook Pro Intel Core i7 16G 内存 250G 硬盘大小测试环境下 比照不同计划下的编译工夫和次要文件的 gzip 压缩前的大小后果如下,在解决大概 65 个文件状况下,能够看到编译工夫大大缩短,js文件大小也有所减小,然而因为局部图片被 base64 编码打进 css 导致款式文件大小有所增加。

计划 第一次编译工夫 第二次编译工夫 buypage.js propsOrder.js buypage.css propsOrder.css
gulp+webpack4 60s 8s 178kb 157kb 17.58kb 24.74kb
webpack5 6.5s 1.5s 123kb 112kb 28kb 35kb
正文完
 0