基于webpack 3 打包性能优化

2017-12-07  本文已影响0人  歌风ola

基于webpack 3 打包性能优化

source

Scope Hoisting.


过去 webpack 打包时的一个取舍是将 bundle 中各个模块单独打包成闭包。这些打包函数使你的 JavaScript 在浏览器中处理的更慢。相比之下,一些工具像 Closure Compiler 和 RollupJS 可以提升(hoist)或者预编译所有模块到一个闭包中,提升你的代码在浏览器中的执行速度。

打开方法:

module.exports = {
    plugins: [
        new webpack.optimize.ModuleConcatenationPlugin(),
    ],
};

--display-optimization-bailout 将显示绑定失败的原因。

Minification and Uglification.


这个应该都会用吧. 去掉空格,换行,注释及一些不必要在生产环境中的东东。

    webpack -p // -p is short for "production"

如果没有给node设置production环境变量的话,还需要设置

    NODE_ENV=production PLATFORM=web webpack -p

还有一些第三方库在生产环境中会去掉一些在开发或测试环境中才能用到的功能,使其提升性能和减少体积.
一般来说 -p 已经够用了, 如果还想再进一步减少体积的话可以使用 webpack.optimize.UglifyJsPlugin.

Dynamic Imports for Lazy-loaded Modules.


// update your webpack.config.js
module: {
    rules: [
        {
        test: /\.js$/,
        use: 'babel-loader',
        exclude: /node_modules/,
        },
    ],
},
// update .babelrc
{
    "presets": ["env"],
    "plugins": ["syntax-dynamic-import", "transform-react-jsx"]
}

如果你是使用 es2015 作为preset,那么建议你�换到 env.

//old
import Home from './components/Home';

//now
const Home = import('./components/Home');
// 原来的require.ensure 已经被import()取代.

目前vue �已经可以做到开箱即用,但是react还不可以。我们可以使用 react-code-split 这个库,实现原理就是使用import().

import React from 'react';
import Async from 'react-code-splitting';

const Nav = () => (<Async load={import('./components/Nav')} />);
const Home = () => (<Async load={import('./views/home')} />);
const Countdown = () => (<Async load={import('./views/countdown')} />);

Deterministic Hashes for Caching



增加hash方便缓存。下面�这种增加hash的方式,只有当文件改变了hash值才会变。这种就避免了用户不必要的下载。

const webpack = require('webpack');
const ChunkManifestPlugin = require('chunk-manifest-webpack-plugin');
const WebpackChunkHash = require('webpack-chunk-hash');
const HtmlWebpackPlugin = require('html-webpack-plugin');

/* Shared Dev & Production */

const config = {
/* … our webpack config up until now */

plugins: [
    // /* other plugins here */
    // 
    // /* Uncomment to enable automatic HTML generation */
    // new HtmlWebpackPlugin({
    //   inlineManifestWebpackName: 'webpackManifest',
    //   template: require('html-webpack-template'),
    // }),
],
};

/* Production */

if (process.env.NODE_ENV === 'production') {
config.output.filename = '[name].[chunkhash].js';
config.plugins = [
    ...config.plugins, // ES6 array destructuring, available in Node 5+
    new webpack.HashedModuleIdsPlugin(),
    new WebpackChunkHash(),
    new ChunkManifestPlugin({
    filename: 'chunk-manifest.json',
    manifestVariable: 'webpackManifest',
    inlineManifest: true,
    }),
];
}

module.exports = config;

CommonsChunkPlugin for Vendor Caching


将第三依赖打包到vendor.js里,这样你升级时,这些第三方依赖就不会重新下载.使用 CommonsChunkPlugin

const webpack = require('webpack');
entry: {
    app: './app.js',
    vendor: ['react', 'react-dom', 'react-router'],
},

// 注意这里的name要和entry相同。否则这些�第三方依赖会打包到所有的入口文件
plugins: [
  new webpack.optimize.CommonsChunkPlugin({
    name: 'vendor',
  }),
],

Tips:

Offline Plugin for webpack


�一个离线可访问的webapp. 插件 OfflinePlugin .使用也很简单,自己�去看吧。自己试了一下,ios10 微信�内浏览器不行,Safari� 可以�离线访问

webpack Bundle Analyzer


分析��bundle.js的�工具🔧
yarn add --dev webpack-bundle-analyzer

const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

config = { /* shared webpack config */ };

if (process.env.NODE_ENV !== 'production' && process.env.NODE_ENV !== 'test') {
  config.plugins = [
    ...config.plugins,
    new BundleAnalyzerPlugin(),
  ];
}

how to use:
node_module/.bin/webpack --profile --json > stats.json

原本提到了关于�优化moment打包大小的问题,solution, �这里提一下如果你使用 roadhog 脚手架的话,在 .roadhogrc.js中加上 "ignoreMomentLocale": true 就可以实现(隐藏func).

上一篇下一篇

猜你喜欢

热点阅读