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

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

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理