前端性能优化之《webpack提升构建速度》

简介: 前端性能优化之《webpack提升构建速度》

使用CommonsChunkPlugin

多入口情况下,使用CommonsChunkPlugin来提取公共代码

module.exports = {
  plugins: [
    new CommonsChunkPlugin({
      name: 'vender', // 公共代码的chunk命名为 'verder'
      filename: '[name].bundle.js' // 生成的文件名为 vender.bundle.js
    })
  ]
};

使用externals

通过externals配置来提取常用库

module.exports={
    configureWebpack:{
        externals: {
            'element-ui': 'ELEMENT',
            'vue': 'Vue',
            'vue-router': 'VueRouter',
        }
    }
}

使用Happypack

使用Happypack 实现多线程加速编译

const HappyPack = require('happypack');
module.exports = {
    ...
    module: {
        rules: [
            test: /\.js$/,
            // use: ['babel-loader?cacheDirectory'] 之前是使用这种方式直接使用 loader
            // 现在用下面的方式替换成 happypack/loader,并使用 id 指定创建的 HappyPack 插件
            use: ['happypack/loader?id=babel'],
            // 排除 node_modules 目录下的文件
            exclude: /node_modules/
        ]
    },
    plugins: [
        ...,
        new HappyPack({
            /*
             * 必须配置
             */
            // id 标识符,要和 rules 中指定的 id 对应起来
            id: 'babel',
            // 需要使用的 loader,用法和 rules 中 Loader 配置一样
            // 可以直接是字符串,也可以是对象形式
            loaders: ['babel-loader?cacheDirectory']
        })
    ]
}

使用webpack-uglify-parallel

使用webpack-uglify-parallel来提升uglifyPlugin的压缩速度。

原理上webpack-uglify-parallel采用了多核并行压缩来提升压缩速度

//npm i webpack-parallel-uglify-plugin
module.exports = {
    new ParallelUglifyPlugin({
          cacheDir: ".cache/",
          uglifyJS: {
            output: {
              comments: false
            },
            warnings: false,
            compress: {
              drop_debugger: true,
              drop_console: true
            }
          }
        })
}

JS代码压缩

terser是一个JavaScript的解释、绞肉机、压缩机的工具集,可以帮助我们压缩、丑化我们的代码,让bundle更小。在production模式下,webpack


默认就是使用 TerserPlugin 来处理我们的代码的。如果想要自定义配置它,配置方法如下:

const TerserPlugin = require('terser-webpack-plugin')
module.exports = {
    ...
    optimization: {
        minimize: true,
        minimizer: [
            new TerserPlugin({
                parallel: true // 电脑cpu核数-1
            })
        ]
    }
}

CSS代码压缩

CSS压缩通常是去除无用的空格等,因为很难去修改选择器、属性的名称、值等。CSS的压缩我们可以使用另外一个插件:css-minimizer-webpack-plugin。

// npm install css-minimizer-webpack-plugin -D
const CssMinimizerPlugin = require('css-minimizer-webpack-plugin')
module.exports = {
    // ...
    optimization: {
        minimize: true,
        minimizer: [
            new CssMinimizerPlugin({
                parallel: true
            })
        ]
    }
}

HTML文件压缩

使用HtmlWebpackPlugin插件来生成HTML的模板时候,通过配置属性minify进行html优化。

module.exports = {
    ...
    plugin:[
        new HtmlwebpackPlugin({
            ...
            minify:{
                minifyCSS:false, // 是否压缩css
                collapseWhitespace:false, // 是否折叠空格
                removeComments:true // 是否移除注释
            }
        })
    ]
}

文件大小压缩

对文件的大小进行压缩,减少http传输过程中宽带的损耗。

// npm install compression-webpack-plugin -D
new ComepressionPlugin({
    test:/\.(css|js)$/,  // 哪些文件需要压缩
    threshold:500, // 设置文件多大开始压缩
    minRatio:0.7, // 至少压缩的比例
    algorithm:"gzip", // 采用的压缩算法
})

图片压缩

一般来说在打包之后,一些图片文件的大小是远远要比 js 或者 css 文件要来的大,所以图片压缩较为重要。

module: {
  rules: [
    {
      test: /\.(png|jpg|gif)$/,
      use: [
        {
          loader: 'file-loader',
          options: {
            name: '[name]_[hash].[ext]',
            outputPath: 'images/',
          }
        },
        {
          loader: 'image-webpack-loader',
          options: {
            // 压缩 jpeg 的配置
            mozjpeg: {
              progressive: true,
              quality: 65
            },
            // 使用 imagemin**-optipng 压缩 png,enable: false 为关闭
            optipng: {
              enabled: false,
            },
            // 使用 imagemin-pngquant 压缩 png
            pngquant: {
              quality: '65-90',
              speed: 4
            },
            // 压缩 gif 的配置
            gifsicle: {
              interlaced: false,
            },
            // 开启 webp,会把 jpg 和 png 图片压缩为 webp 格式
            webp: {
              quality: 75
            }
          }
        }
      ]
    },
  ]
} 

Tree Shaking

使用Tree-shaking和Scope Hoisting来剔除多余代码


useExports(通过标记某些函数是否被使用,之后通过Terser来进行优化)

usedExports只需要将usedExports设为true;使用之后,没被用上的代码在webpack打包中会加入unused

harmony export mul注释,用来告知 Terser 在优化时,可以删除掉这段代码

module.exports = {
    ...
    optimization:{
        usedExports:true;
    }
}

sideEffects(跳过整个模块/文件),直接查看该文件是否有副作用

sideEffects配置方法在package.json中设置sideEffects属性,如果sideEffects设置为false,就是告知webpack可以安全的删除未用到的exports。如果有些文件需要保留,可以设置为数组的形式。

"sideEffecis":[
    "./src/util/format.js",
    "*.css" // 所有的css文件
]

代码分离

将代码分离到不同的bundle中,之后可以按需加载,或者并行加载这些文件。默认情况下,所有的JS代码在首页全部加载,会影响到首页的加载速度。代码可以分出更小的bundle,以及控制资源加载的优先级,提供代码的加载性能。通过插件splitChunksPlugin来实现。

module.exports = {
    ...
    optimization:{
        splitChunks:{
            chunks:"all"
        }
    }
}

内联chunk

可以通过InlineChunkHtmlPlugin插件将一些chunk的模块内嵌到html

const InlineChunkHtmlPlugin = require('react-dev-utils/InlineChunkHtmlPlugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
    ...
    plugin:[
        new InlineChunkHtmlPlugin(HtmlWebpackPlugin,[/runtime.+\.js/]
}

优化loader配置

在使用loader时,可以通过配置include、exclude、test属性来匹配文件,接触include、exclude规定哪些匹配应用loader

如采用 ES6 的项目为例,在配置 babel-loader时,可以这样:

module.exports = {
  module: {
    rules: [
      {
        // 如果项目源码中只有 js 文件就不要写成 /\.jsx?$/,提升正则表达式性能
        test: /\.js$/,
        // babel-loader 支持缓存转换出的结果,通过 cacheDirectory 选项开启
        use: ['babel-loader?cacheDirectory'],
        // 只对项目根目录下的 src 目录中的文件采用 babel-loader
        include: path.resolve(__dirname, 'src'),
      },
    ]
  },
};

使用 resolve.extensions

在开发中我们会有各种各样的模块依赖,这些模块可能来自于自己编写的代码,也可能来自第三方库, resolve可以帮助webpack从每个

require/import 语句中,找到需要引入到合适的模块代码

通过resolve.extensions是解析到文件时自动添加拓展名,默认情况如下:


module.exports = {
    ...
    extensions:[".warm",".mjs",".js",".json"]
}

当我们引入文件的时候,若没有文件后缀名,则会根据数组内的值依次查找

当我们配置的时候,则不要随便把所有后缀都写在里面,这会调用多次文件的查找,这样就会减慢打包速度

优化 resolve.modules

resolve.modules 用于配置 webpack

去哪些目录下寻找第三方模块。默认值为[‘node_modules’],所以默认会从node_modules中查找文件

当安装的第三方模块都放在项目根目录下的 ./node_modules目录下时,所以可以指明存放第三方模块的绝对路径,以减少寻找,配置如下:

module.exports = {
  resolve: {
    // 使用绝对路径指明第三方模块存放的位置,以减少搜索步骤
    // 其中 __dirname 表示当前工作目录,也就是项目根目录
    modules: [path.resolve(__dirname, 'node_modules')]
  },
};

优化 resolve.alias

alias给一些常用的路径起一个别名,特别当我们的项目目录结构比较深的时候,一个文件的路径可能是./…/…/的形式

通过配置alias以减少查找过程

module.exports = {
    ...
    resolve:{
        alias:{
            "@":path.resolve(__dirname,'./src')
        }
    }
}

使用 DLLPlugin 插件

利用DllPlugin和DllReferencePlugin预编译资源模块

通过DllPlugin来对那些我们引用但是绝对不会修改的npm包来进行预编译,再通过DllReferencePlugin将预编译的模块加载进来。

使用步骤分成两部分:

  • 打包一个 DLL 库
  • 引入 DLL 库

打包一个 DLL 库

webpack内置了一个DllPlugin可以帮助我们打包一个DLL的库文件

module.exports = {
    ...
    plugins:[
        new webpack.DllPlugin({
            name:'dll_[name]',
            path:path.resolve(__dirname,"./dll/[name].mainfest.json")
        })
    ]
}

引入 DLL 库

使用 webpack 自带的 DllReferencePlugin 插件对 mainfest.json

映射文件进行分析,获取要使用的DLL库,然后再通过AddAssetHtmlPlugin插件,将我们打包的DLL库引入到Html模块中

module.exports = {
    ...
    new webpack.DllReferencePlugin({
        context:path.resolve(__dirname,"./dll/dll_react.js"),
        mainfest:path.resolve(__dirname,"./dll/react.mainfest.json")
    }),
    new AddAssetHtmlPlugin({
        outputPath:"./auto",
        filepath:path.resolve(__dirname,"./dll/dll_react.js")
    })
}

使用 cache-loader

在一些性能开销较大的 loader之前添加 cache-loader,以将结果缓存到磁盘里,显著提升二次构建速度

保存和读取这些缓存文件会有一些时间开销,所以请只对性能开销较大的 loader 使用此loader

module.exports = {
    module: {
        rules: [
            {
                test: /\.ext$/,
                use: ['cache-loader', ...loaders],
                include: path.resolve('src'),
            },
        ],
    },
};

terser 启动多线程

使用多进程并行运行来提高构建速度

module.exports = {
  optimization: {
    minimizer: [
      new TerserPlugin({
        parallel: true,
      }),
    ],
  },
};
相关文章
|
4天前
|
缓存 JavaScript 前端开发
探讨如何通过一系列优化策略来提升TypeScript与Webpack的构建性能。
【6月更文挑战第11天】本文探讨了优化TypeScript与Webpack构建性能的策略。理解Webpack的解析、构建和生成阶段是关键。优化包括:调整tsconfig.json(如关闭不必要的类型检查)和webpack.config.js选项,启用Webpack缓存,实现增量构建,代码拆分和懒加载。通过这些方法,可以提升构建速度,提高开发效率。
29 0
|
1天前
|
前端开发 JavaScript 编译器
Svelte框架:编译时优化的高性能前端框架
Svelte是一款由Rich Harris于2016年创建的高性能前端框架,以其编译时优化著称。它将复杂UI逻辑转化为高效的JavaScript,减少运行时开销。Svelte的核心理念是将编译时和运行时的复杂性分离,通过模板语法、组件系统、响应式系统和编译器实现高性能。关键优化策略包括声明式更新、模板内联、计算属性缓存、事件处理优化和代码分割。Svelte提供热模块替换、类型检查和丰富的生态系统,如SvelteKit。其响应式系统基于Reactive Statements,自动更新组件。
7 0
|
2天前
|
缓存 自然语言处理 前端开发
JVM系列8-前端编译与优化
JVM系列8-前端编译与优化
6 0
|
3天前
|
缓存 前端开发 JavaScript
Webpack作为模块打包器,为前端项目提供了高度灵活和可配置的构建流程
【6月更文挑战第12天】本文探讨了优化TypeScript与Webpack构建性能的策略。理解Webpack的解析、构建和生成阶段是关键。优化包括:调整tsconfig.json(如关闭不必要的类型检查)和webpack.config.js选项,启用Webpack缓存,实现增量构建,代码拆分和懒加载。这些方法能提升构建速度,提高开发效率。
25 3
|
4天前
|
缓存 前端开发 JavaScript
前端性能优化技巧
在当今互联网快速发展的时代,前端性能优化成为了开发者们关注的焦点之一。本文将介绍一些实用的前端性能优化技巧,包括减少HTTP请求、压缩代码、图片优化、减少重绘与重排等方面,帮助开发者们提升网站的加载速度和用户体验。
|
6天前
|
前端开发 算法 JavaScript
优化算法在前端性能提升中的应用
随着互联网应用的日益复杂,前端性能优化成为开发者关注的焦点。本文探讨了优化算法在前端性能提升中的重要作用,包括对JavaScript代码的优化、资源加载的算法选择以及页面渲染的优化策略。通过合理应用优化算法,可以有效提升前端应用的性能和用户体验。
|
11天前
|
存储 缓存 前端开发
全面解析:前端超大文件下载的关键技巧与优化策略
全面解析:前端超大文件下载的关键技巧与优化策略
17 1
全面解析:前端超大文件下载的关键技巧与优化策略
|
13天前
|
前端开发 JavaScript 缓存
如何优化前端网页加载速度
网页加载速度是用户体验和SEO排名的重要指标之一。本文将探讨如何通过优化前端代码、资源加载和网络请求等方面来提高网页加载速度,从而提升用户满意度和网站流量。
|
17天前
|
缓存 前端开发 JavaScript
基于JavaScript的前端性能优化技术探讨
基于JavaScript的前端性能优化技术探讨
28 1