Webpack性能优化

减少Webpack打包时间

1.优化Loader

对于Loader,影响打包效率的是它的属性Babel.Babel会将代码转为字符串 生成AST,然后对AST继续进行转变最后生成新的代码,项目越大,转换代码越多,效率就越低。

优化Loader的文件搜索范围
module.exports = {
        module:{
            rules:[
              {
                //js文件才使用babel
                test:/\.js$/,
                loader:'babel-loader',
                //只在src文件夹下查找
                include:[resolve('src')],
                //不会去查找的路径
                exclude:/node_modules/
              }
            ]
        }
    }
把Babel编译过的文件缓存起来

下次只需要编译更改过的代码文件即可

loader: 'babel-loader?cacheDirectory=ture'
HappyPack

因为Node是单线程运行的,所以Webpack在打包的过程中也是单线程的,特别是在执行Loader的时候,这样会导致等待的情况
HappyPack可以将Loader的同步执行转换为并行的

module:{
        loader:[
           {
                //js文件才使用babel
                test:/\.js$/,
                //只在src文件夹下查找
                include:[resolve('src')],
                exclude:/node_modules/,
                //id后面的内容对应下面
                loader:'happypack/loader?id=happypack'
           }
        ]
    },
    plugins:[
      new HappyPack({
        id:'happypack',
        loaders:['babel-loader?cacheDirectory'],
        //开启4个线程
        threads:4
      })
    ]
DllPlugin

DllPlugin可以将特定的类库提前打包然后引入。这种方式可以极大的减少打包类库的次数,只有当类库更新版本才有需要重新打包,并且也实现了将公共代码抽离成单独文件的优化方案

//单独配置在一个文件里
    //webpack.dll.conf.js
    const path = require('path')
    const webpack = require('webpack')
    module.exports = {
        entry:{
            //想统一打包的库
            vendor:['react']
        },
        output:{
            path:path.join(__dirname,'dist'),
            filename:'[name].dll.js',
            library:'[name]-[hash]'
        },
        plugins:[
          new webpack.DllPlugin({
            //name必须和output.library一致
            name:'[name]-[hash]',
            //该属性需要与DllReferencePlugin中一致
            context:__dirname,
            path:path.join(__dirname,'dist','[name]-mainfest.json')
          })
        ]
    }

然后需要执行这个配置文件生成依赖文件,接下来需要使用DllReferencePluhin将依赖文件引入项目中

 //webpack.conf.js
   module.exports={
    //...省略其他配置
    plugins: [
      new webpack.DllReferencePlugin({
        context: __dirname,
        mainfest:require('./dist/vendor-mainfest.json')
      })
    ]
   }

减少Webpack打包后的文件体积

按需加载

如果我们把十几个页面甚至更多的路由页面,把这些页面全部打包进一个JS文件的话,虽然将多个请求合并了,但是同样也加载了很多并不需要的代码,耗费了更长的时间。那么为了首页能更快地呈现给客户,这时候我们就可以使用按需加载,将每个路由页面单独打包为一个文件,当然不仅路由可以按需加载,对于loadash这种大型类库可以使用这个功能。

当使用的时候再去下载对应文件,返回一个Promise当Promise成功以后去执行回调
Scope Hoisting

Scope Hoisting会分析出模块之间的依赖关系,尽可能的把打包出来的模块合并到一个函数中去。

比如我们希望打包两个模块
   //test.js
   export const a=1
   //index.js
   import {a} from './test.js'
   对于这种情况,我们打包出来的代码类似这样
   [
     function (module,exports,require){
        //...
     },
     function(module,exports,require){
        //...
     }

   ]
   但是如果我们使用Scope Hoisting的话,代码就会尽可能的合并到一个函数去,也就变成了这样的类似代码
   [
     function(module,exports,require){
        //...
     }
   ]
   这样的打包方式生成的代码明显比之前的少了多了。如果在webpack4中希望开启这个功能,只需要启用
   optimization.concatenateModules就可以了
   module,exports={
    optimization:{
        concatenateModules:true
    }
   }
Tree Shaking

Tree Shaking 可以实现删除项目中未被引用的代码

 //test.js
   export const a = 1;
   export const b = 2;
   //index.js
   import {a} from './test.js'

test文件中的变量b如果没有在项目中使用到的话,就不会被打包到文件中。
webpack4的话,开启生产环境就会自动启动这个优化功能。

你可能感兴趣的:(Webpack性能优化)