webpack

webpack 构建速度和体积优化

2020-12-08  本文已影响0人  阿畅_

构建速度优化

使用 webpack 内置的 stats

"scripts": {
  "build:stats": "webpack --env production --json > stats.json"
},

速度分析

yarn add speed-measure-webpack-plugin -D
const SpeedMeasurePlugin = require("speed-measure-webpack-plugin");
 
const smp = new SpeedMeasurePlugin();
 
const webpackConfig = smp.wrap({
  plugins: [
    ...
  ]
});

分析体积大小 webpack-bundle-analyzer

npm install --save-dev webpack-bundle-analyzer
or
yarn add -D webpack-bundle-analyzer
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
 
module.exports = {
  plugins: [
    new BundleAnalyzerPlugin()
  ]
}

使用高版本的 webpack 和 node.js

使用 webpack4 优化原因

使用 多进程/ 多实例构建

使用 HappyPack 解析资源

const HappyPack = require('happypack');

exports.module = {
  loaders: {
    test: /.js$/,
    loader: 'happypack/loader',
    include: [
      // ...
    ],
  }
};

这个库作者已经不维护了,webpack4 后的推荐使用 thread-loader

使用 thread-loader 解析资源

// 安装
npm install --save-dev thread-loader
// webapck.config.js
module.exports = {
  module: {
    rules: [
      {
        test: /\.js$/,
        include: path.resolve('src'),
        use: [
          'thread-loader',
          // your expensive loader (e.g babel-loader)
        ],
      },
    ],
  },
};

使用 多进程/ 多实例 并行压缩

使用 parallel-uglify-plugin 插件

import ParallelUglifyPlugin from 'webpack-parallel-uglify-plugin';

module.exports = {
  plugins: [
    new ParallelUglifyPlugin({
      uglifyJS: {
        output: {
          beautify: false,
          comments: false
        },
        comperss: {
          // 是否在UglifyJS删除没有用到的代码时输出警告信息,默认为输出,可以设置为false关闭这些作用
          warnings: false,
          drop_console: true,
          collapse_vars: true,
          reduce_vars: true
        }
      },
    }),
  ],
};

使用 uglifyjs-webpack-plugin 开启 parallel 参数

npm i -D uglifyjs-webpack-plugin
const UglifyJsPlugin = require('uglifyjs-webpack-plugin')

module.exports = {
  plugins: [
    new UglifyJsPlugin({
      uglifyOptions: {
        warnings: false,
        parse: {},
        compress: {},
        mangle: true,
        output: null,
        toplevel: false,
        nameCache: null,
        ie8: false,
        keep_fnames: false
      },
      parallel: true
    })
  ]
}

terser-webpack-plugin 开启 parallel 参数

module.exports = {
  optimization: {
    minimizer: [
      new Terserplugin({
        parallel: true
      })
    ]
  }
}

分包构建

使用 html-webpack-externals-plugin

new HtmlWebpackExternalsPlugin({
  externals: [
    {
      module: 'react',
      entry: 'https://cdn.bootcdn.net/ajax/libs/react/17.0.0/cjs/react.production.min.js',
      global: 'React',
    },
  ],
})

缺点如果需要多个基础包,引入的还是过多

使用预编译资源模块

使用

module.exports = {
  context: process.cwd(),
  entry: {
    library: [
      'react',
      'react-dom',
      'redux',
      'react-redux'
    ],
    // 如果有多个,直接在增加一个
  }
  output: {
    // 这里打包后的文字是 library.dll.js
    filename: '[name].dll.js',
    path: path.resolve(__dirname, 'build/libarary'),
    // 暴露的库的名字
    library: '[name]'
  },
  plugins: [
    // 指定包存放的位置
    new webpack.DllPlugin({
      name: '[name]',
      // 描述动态链接库 mainfest 文件输出时的文件名称
      // path: 'manifest.json'
      path: path.resolve(__dirname, 'build/libarary/[name].json')
    })
  ]
}
    
"scripts": {
  "dll": "webpack --config webpack.dll.js"
}
module.exports = {
  plugins: [
    new webpack.DllReferencePlugin({
      // 刚打包后的json文件地址
      // manifest: require('xxx.json'),
      manifest: require('./build/library/libary.json'),
    })
    // 如果引入多个,使用多次此插件
  ]
}

利用缓存提升构建速度

babel-loader 开启缓存

use: [
  {
    loader: 'babel-loader',
    options: {
      cacheDirectory: true
    }
  }
]

terser-webpack-plugin 开启缓存

module.exports = {
  optimization: {
    minimizer: [
      new Terserplugin({
        parallel: true,
        cache: true
      })
    ]
  }
}

使用 hard-source-webpack-plugin 开启缓存

npm install --save-dev hard-source-webpack-plugin or yarn add --dev hard-source-webpack-plugin
// webpack.config.js

const HardSourceWebpackPlugin = require('hard-source-webpack-plugin');

plugins: [
  new HardSourceWebpackPlugin()
]

缩小构建目标来优化构建速度

减少文件搜索范围

合理使用 resolve.alias

module.exports = {
  resolve: {
    alias: {
      react: path.resolve(__dirname, './node_modules/react/dist/react.min.js'),
    }
  }
}

resolve.modules 配置 (减少模块搜索层级)

module.exports = {
  resolve: {
    modules: [path.resolve(__dirname, "node_modules")]
  }
}

resolve.mainFields

module.exports = {
  resolve: {
    //指定入口文件 main 意思是从 package.json 中 main 字段中查找
    mainFields: ['main']
  }
}

resolve.extensions

extensions: [".js", ".json"]

构建体积优化

Tree Shaking

无用的 CSS 如何删除掉的?

const path = require('path')
const glob = require('glob')
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const PurgeCSSPlugin = require('purgecss-webpack-plugin')
const PATHS = {
  src: path.join(__dirname, 'src')
}

module: {
  rules: [
    {
      test: /\.css$/,
      use: [
        MiniCssExtractPlugin.loader,
        "css-loader"
      ]
    }
  ]
},
plugins: [
  new MiniCssExtractPlugin({
    filename: "[name].css",
  }),
  new PurgeCSSPlugin({
    paths: glob.sync(`${PATHS.src}/**/*`,  { nodir: true }),
  }),
]

图片压缩

imagemin 的优点

图片压缩的原理 png

使用 image-webpack-loader

npm install image-webpack-loader --save-dev
// webpack.config.js
rules: [{
  test: /\.(gif|png|jpe?g|svg)$/i,
  use: [
    'file-loader',
    {
      loader: 'image-webpack-loader',
      options: {
        mozjpeg: {
          progressive: true,
        },
        // optipng.enabled: false will disable optipng
        optipng: {
          enabled: false,
        },
        pngquant: {
          quality: [0.65, 0.90],
          speed: 4
        },
        gifsicle: {
          interlaced: false,
        },
        // the webp option will enable WEBP
        webp: {
          quality: 75
        }
      }
    },
  ],
}]

动态 Polyfill

Polyfill 几种方案的优缺点

  1. babel-polyfill
  1. babel-plugin-transform-runtime
  1. 自己map、set的polyfill
  1. polyfill-service

使用

  1. polyfill.io 官方提供的服务
https://polyfill.io/v3/polyfill.min.js
  1. 基于官方自建 polyfill 服务
https://polyfill.io/v3/polyfill.min.js?features=es2015%2Ces2016%2Ces2017
上一篇 下一篇

猜你喜欢

热点阅读