前端性能优化实践(构建优化)

文章详细介绍了使用webpack进行构建优化的各种策略,包括并行构建、缓存、代码切割和按需加载,以及如何通过SplitChunksPlugin、DllPlugin等工具提高构建速度和减少包体积。同时,提到了构建缓存如hard-source-webpack-plugin的使用,以及包体积、构建速度和性能的测量方法,如webpack-bundle-analyzer和speed-measure-webpack-plugin。通过这些优化,实现了非首次构建和编译时间的显著减少以及包体积的压缩。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

构建层面优化

  1. 并行构建(thread-loader、happypack)
  2. 构建缓存(cache-loader、hard-source-webpack-plugin)
  3. 代码切割(splitChunks):按需加载,分离基础库和公共代码库。通过分割打包,可以将公共代码或外包依赖项单独打包,并从客户端缓存中受益。在此过程中,整个的包体积没有变小,且需要执行的请求可能会变多,但缓存的好处可以弥补这一成本。
  4. Hash 缓存
  5. 减少构建(external、DllPlugin)
  6. Tree Shaking
  7. 预渲染
  8. 分离样式:通过 css-loader、style-loader等一系列loader打包好了的css,如果是通过内联到js中,就会存在 css 无法缓存、增加了js文件体积和未样式化元素闪动(FOUC)问题。
  9. 静态资源、图片内联: 使用url-loader 内联资源,将小图像转换为base64形式的字符串,从而减少http请求。

性能好坏的测量

  • 测量构建体积: webpack-bundle-analyzer (注:在上生产时注释掉该功能,不然会导致包已构建成功,但一直停留在构建中)
  • 测量构建速度: speed-measure-webpack-plugin

如何优化

  • 包体积优化:gzip压缩、图片压缩、静态文件压缩等;分包(splitchunks)按需加载,分离基础库和公共代码库。
  • 构建速度优化:构建缓存(hard-source-webpack-plugin 插件做缓存,在webpack5 中已内置),
  • 减少构建次数:对项目中依赖同一包的不同版本的,尽量统一到同一版本。
    1. 代码分隔以按需加载,分离基础库,提取公共代码。(SplitChunksPlugin)
    2. DllPlugin 和 DllReferencePlugin 用某种方式实现了拆分 bundles,同时还大幅度的提升了构建的速度。

Chunk 和 Bundle 的关系

  • Chunk(块):指若干个 js Module的集合
  • Bundle: 形式上是块的集合,是一个可以运行的整体。

注:

  • 使用 html-webpack-externals-plugin 基础库分离,通过 CDN 引入,不打入 bundle 中。

  • 使用 SplitChunksPlugin 不仅可以分离基础包,还可以提取公共带代码(推荐)。官方推荐将不需要立刻使用的代码通过异步的方式引入,这样才是加快网页速度的关键。

  • 使用 DLLPlugin 预编译资源模块分离基础包(内置插件,更好的分包),减少不常更新的第三方包重复构建。

  • 使用 hard-source-webpack-plugin 是 DLL 的更好替代者

实践

通过构建缓存减少构建优化构建

  1. 使用构建缓存(hard-source-webpack-plugin 插件做缓存,在webpack5 中已内置)

  2. 分割代码(splitPlugins)按需加载,分离基础库和公共代码库,包体积不会减小,但可以减少依赖项的构建次数,从而减少构建时常;
    调用 splitChunks 之后:
    在这里插入图片描述

  3. DllPlugin 和 DllReferencePlugin 用某种方式实现了拆分 bundles,同时还大幅度的提升了构建的速度。可以减小构建包的大小。

// vue.config.js
const HardSourceWebpackPlugin = require('hard-source-webpack-plugin')
const SpeedMeasureWebpackPlugin = require('speed-measure-webpack-plugin')
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
const path = require('path')
const apiData = require('./config/api.json')
const webpack = require('webpack')

const smp = new SpeedMeasureWebpackPlugin()

module.exports = {
  ...
  configureWebpack: smp.wrap({
        entry: './src/main.js',
        plugins: process.env.NODE_ENV === 'development' ? [
            // new webpack.DllReferencePlugin({
            //     context: process.cwd(),
            //     name: 'vendor',
            //     manifest: require('./vendor-manifest.json')
            // }),
            // 开发环境复制配置文件到构建目录
            new CopyWebpackPlugin([
                {
                    from: path.resolve(__dirname, './config/config.json'),
                    to: path.resolve(__dirname, './dist/solution/cdy/edge/config.json')
                },
                {
                    from: path.resolve(__dirname, './config/dev.config.json'),
                    to: path.resolve(__dirname, './dist/solution/cdy/edge/env.config.json')
                }
            ]),
            new BundleAnalyzerPlugin(),
            new HardSourceWebpackPlugin() // 构建加速
        ] : [],
        optimization: {
            splitChunks: {
                chunks: 'all',
                cacheGroups: {
                    sfcloud: {
                        enforce: true,
                        test: /[\\/]node_modules[\\/]sf-cloud-el-ui[\\/]/
                    }
                }
            }
        }
    }),
    ...
}

优化前

优化前在这里插入图片描述
–包体积:

优化前–非首次编译时常:
在这里插入图片描述
优化前–非首次构建时常:
在这里插入图片描述
优化前:
在这里插入图片描述

增加 **构建缓存(hard-source-webpack-plugin 插件)**后,二次构建(yarn serve)速度提升
splitChunkPlugin 分离公共代码库:
splitChunksPlugin 是webpack内置的插件,无需另外安装插件,可执行调用。

// vue.config.js
configureWebpack: {
    optimization: {
            splitChunks: { // 分离代码包:按需加载,将基础库和公共代码库。
                chunks: 'all',
                cacheGroups: {
                    sfcloud: {
                        enforce: true,
                        test: /[\\/]node_modules[\\/]sf-cloud-el-ui[\\/]/
                    }
                }
            }
        }
}

在这里插入图片描述

体积优化策略

  • scope Hoisting 原理:将所有模块的代码按照引用顺序放在一个函数的作用域里,然后适当的重命名一些变脸以防止变量名冲突。通过 scope hoisting 可以减少函数声明代码和内存开销。mode为 ‘production’ 时,默认开启。
    1、将mode 设置为none, 时的包体积大小:
// vue.config.js
module.exports = {
...
  configureWebpack: {
    mode: 'none',
    ...
  }
  ...
}

在这里插入图片描述
2. 生产环境打包(yarn build),明显包体积小了很多
在这里插入图片描述
项目实践最终结果:
非首次编译(yarn serve)时常:
在这里插入图片描述

非首次构建(yarn build)时常:
在这里插入图片描述

最终包体积:
在这里插入图片描述

优化后:
在这里插入图片描述
总结

指标优化前优化后提升率
非首次构建时长55.41s38.01s31.4%
非首次编译19.83s3.5s82.3%
包体积3.64MB2.17MB40.4%
性能指标1531106.7%
LCP10.8s7.9s17.6%
FCP2.9s2.6s10.3%
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值