• webpack打包极限优化


    webpack打包极限优化--基本介绍

    1.为什么我们需要构建工具

    (a)转换ES6语法

    (b)转换JSX

    (c)CSS前缀补全/预处理器

    (d)压缩混淆

    (e)图片压缩

    2.初级分析-使用Webpack内置的stats

    (a)stats:构建的统计信息
    (b)package.json中使用status

     1 "scripts": { 2 "build:stats": "webpack ---env production --json > stats.json" 3 ... 4 } 

    (c)Node API中使用

     1 const webpack = require('webpack');
     2 const config = require('./webpack.config.js')("production");
     3 
     4 webpack(config, (err, stats) => {
     5   if (err) {
     6     return console.error(err);
     7   }
     8   if (stats.hasErrors()) {
     9     return console.error(stats.toString("errors-only"))
    10   }
    11   console.log(stats);
    12 })

    3.速度分析-使用speed-measure-webpack-plugin

     1 const speedMeasurePlugin = require("speed-measure-webpack-plugin");
     2 const smp = new SpeedMeasurePlugin();
     3 
     4 const webpackConfig = smp.wrap({
     5   plugins: {
     6     new MyPlugin(),
     7     new MyOtherPlugin()
     8   }
     9 })
    10 // 可以看到每个loader和插件执行耗时

    4.体积分析-使用webpack-bundle-analyzer

    1 const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
    2 module.exports = {
    3   plugins: {
    4     new BundleAnalyzerPlugin()
    5   }
    6 }
    7 // 构建完成后会在8888端口展示各个打包后文件的大小

    webpack打包极限优化--构建速度优化

    1.速度优化策略

    (a)使用webpack4

    (b)多进程/多实例构建

    (c)分包

    (d)缓存

    (e)缩小构建目标

    2.使用webpack4-优化原因

    (a)V8带来的优化(for of替代forEach、Map和Set替代Object、includes替代indexOf)

    (b)默认使用更快的md4 hash算法

    (c)webpacks AST可以直接从loader传递给AST,减少解析时间

    (d)使用字符串方法替代正则表达式

    3.多进程/多实例-使用HappyPack解析资源

    原理:每次webpack解析一个模块,HappyPack会将它及它的依赖分配给worker线程中

     1 exports.plugins = {
     2   new HappyPack({
     3     id: 'jsx',
     4     threads: 4, // 固定线程数,但是不建议
     5     loaders: ['babel-loader']
     6   }),
     7   new HappyPack({
     8     id: 'styles',
     9     threads: 2, // 固定线程数,但是不建议
    10     loaders: ['style-loader', 'css-loader', 'less-loader']
    11   })
    12 }

    4.多进程/多实例-并行压缩

    方法一:使用parallel-uglify-plugin插件(webpack3使用)

     1 const ParallelUglifyPlugin = require('webpack-parallel-uglify-plugin');
     2 module.exports = {
     3   plugins: [
     4     new ParallelUglifyPlugin({
     5       uglifyJS: {
     6         output:{
     7           beautity: false,
     8           comments: false,
     9         },
    10         compress: {
    11           warnings: false,
    12           drop_console: true,
    13           collapse_vars: true,
    14           reduce_vars: true
    15         }
    16       }
    17     })
    18   ]
    19 }

    方法二:使用uglifyjs-webpack-plugin开启parallel参数(webpack4使用)

     1 const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
     2 module.exports = {
     3   plugins: [
     4     new UglifyJsPlugin({
     5       uglifyOptions: {
     6         warnings: false,
     7         parse: {},
     8         compress: {},
     9         mangle: true,
    10         output: null,
    11         toplevel: false,
    12         nameCache: null,
    13         ie8: false,
    14         keep_fnames: false
    15       },
    16       parallel: true
    17     })
    18   ]
    19 }

    5.分包-设置Externals

    思路:将react、react-dom基础包通过cdn引入,不打入bundle中
    方法:使用html-webpack-externals-plugin

     1 const HtmlWebpackExternalsPlugin = require('html-webpack-externals-plugin');
     2 plugins: [
     3   new HtmlWebpackExternalsPlugin({
     4     external: [
     5       {
     6         module: 'react',
     7         entry: '........./react-with-addons.min.js?_bid=313',
     8         global: 'React'
     9       },
    10       {
    11         module: 'react-dom',
    12         entry: '........./react-dom.min.js?_bid=313',
    13         global: 'ReactDOM'
    14       }
    15     ]
    16   })
    17 ]

    6.进一步分包-预编译资源模块

    思路:将react、react-dom、redux、react-redux基础包和业务基础包打包成一个文件。
    方法:使用DLLPlugin进行分包,DllReferencePlugin对manifest.json引用

    1 module.exports = {
    2   plugins: [
    3     new webpack.DllPlugin({
    4       name: '[name]',
    5       path: './build/library/[name].json'
    6     })
    7   ]
    8 }

    7.缓存

    目的:提升二次构建速度
    方法:使用HardSourceWebpackPlugin或者cache-loader
    比较推荐使用HardSourceWebpackPlugin,速度更快

    8.缩小构建目标

    目的:尽可能的少构建模块
    比如babel-loader不解析node_modules

    1 module.exports = {
    2   rules: {
    3     test: /.js$/,
    4     loader: 'happypack/loader',
    5     exclude: 'node_modules'
    6   }
    7 }

    webpack打包极限优化--构建体积优化

    1.体积优化策略

    (a)Scope Hoisting

    (b)Tree-shaking

    (c)公共资源分离

    (d)图片压缩

    (e)动态Polyfill

    2.Scope Hoisting

    原理:将所有模块的代码按照引用顺序放在一个函数作用域里,然后适当的重命名一些变量以防止变量名冲突
    对比:通过scope hoisting可以减少函数声明代码

    1 // 代码示例:
    2 module.exports = {
    3   plugins: [
    4     new webpack.opimize.ModuleConcatenationPlugin()
    5   ]
    6 }
    7 // 要求:必须是ES6的语法,CJS的方式不支持

    3.Tree-shaking

    概念:1个模块可能有多个方法,只要其中的某个方法使用到了,则整个文件都会被打到bundle里面去,Tree-shaking
    就是只把用到的方法打入bundle,没用到的方法会在uglify阶段被删掉
    使用:webpack默认支持,在.babelrc里设置modules:false即可
    要求:必须是ES6的语法,CJS的方式不支持

    4.公共资源分离

    目的:提取多页面公共JS chunk代码
    使用:webpack3使用CommonsChunkPlugin
    webpack4使用SplitChunksPlugin

    5.图片压缩

    要求:基于Node库的imagemin或者tinypng API

    使用:配置image-webpack-loader

  • 相关阅读:
    SQL 里面的COALESCE函数
    php SESSION 不能跨页面传递
    eclipse[日文版] 的SVN 上传步骤
    从一个SVN下载的导入另一个SVN里面
    VB 活动添加item元素
    分享8款精美的jQuery图片播放插件
    java初学者必看经典
    (转载)Java NIO:NIO原理分析(二)
    (转载)Java NIO:NIO概述(一)
    磁盘格式化
  • 原文地址:https://www.cnblogs.com/wanghao123/p/10550325.html
Copyright © 2020-2023  润新知