Webpack 拆分 JS,react-router 动态路由,优化 JS 加载速度

网上拆分js的文章已经有很多了。在这针对项目中拆分js、动态路由、优化js加载速度,这三块内容,我就根据我的经验简单谈谈。

配置文件与优化对比一览

废话不说先上package.json看看,看看都有啥包

{
  "name": "***",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "del": "rimraf dist",
    "deln": "rimraf node_modules",
    "biu": "rimraf dist && cross-env NODE_ENV=production webpack  -p --progress --watch --colors",
    "dev": "rimraf dist && cross-env NODE_ENV=development webpack-dev-server",
    "n": "webpack --profile --json > stats.json"
  },
  "author": "***",
  "license": "ISC",
  "dependencies": {
    "D": "^1.0.0",
    "antd": "^2.11.0",
    "axios": "^0.16.2",
    "babel-core": "^6.24.1",
    "babel-loader": "^7.0.0",
    "babel-plugin-import": "^1.2.1",
    "babel-plugin-transform-decorators-legacy": "^1.3.4",
    "babel-plugin-transform-object-assign": "^6.22.0",
    "babel-plugin-transform-proto-to-assign": "^6.23.0",
    "babel-polyfill": "^6.23.0",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-react": "^6.24.1",
    "babel-preset-stage-0": "^6.24.1",
    "bundle-loader": "^0.5.5",
    "cross-env": "^5.0.0",
    "css-loader": "^0.28.4",
    "echarts": "^3.7.2",
    "extract-text-webpack-plugin": "^2.1.0",
    "file-loader": "^0.11.1",
    "immutable": "^3.8.1",
    "less": "^2.7.2",
    "less-loader": "^4.0.4",
    "postcss-loader": "^2.0.5",
    "qs": "^6.4.0",
    "rc-banner-anim": "^0.5.16",
    "rc-queue-anim": "^1.3.1",
    "rc-scroll-anim": "^2.0.2",
    "rc-tween-one": "^1.4.5",
    "react": "^15.5.4",
    "react-addons-update": "^15.6.0",
    "react-dom": "^15.5.4",
    "react-file-download": "^0.3.4",
    "react-hot-loader": "^1.3.1",
    "react-redux": "^5.0.5",
    "react-router": "^4.1.1",
    "react-router-config": "^1.0.0-beta.3",
    "react-router-dom": "^4.1.1",
    "react-router-redux": "^4.0.8",
    "react-sk-countdown": "^1.0.2",
    "redux": "^3.6.0",
    "redux-immutable": "^4.0.0",
    "redux-persist": "^4.8.1",
    "redux-persist-immutable": "^4.3.0",
    "redux-promise-middleware": "^4.2.1",
    "redux-reset": "^0.3.0",
    "redux-saga": "^0.15.3",
    "redux-thunk": "^2.2.0",
    "style-loader": "^0.18.1",
    "url-loader": "^0.5.8",
    "webpack": "^2.6.1",
    "webpack-bundle-analyzer": "^2.9.1",
    "webpack-dev-server": "^2.4.5"
  },
  "devDependencies": {
    "compression-webpack-plugin": "^1.0.1"
  }
}

Webpack 配置文件

const path = require('path');
const webpack = require('webpack');
// 拆 css
const ExtractTextPlugin = require('extract-text-webpack-plugin');
// gzip 压缩
const CompressionPlugin = require('compression-webpack-plugin');
// bundle 大小分析
// const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
// 开发模式
// const DEV = process.env.NODE_ENV === 'development';
// 生产模式
const PROD = process.env.NODE_ENV === 'production';
// 只有在开发模式下启用 source-map
const devtool = PROD ? false : "source-map";
// 指定 filename
const filename = PROD ? '[name].js' : 'bundle.js';
// 提取项目内的公共 js
const entry = PROD ? {
        bundle: './src/index.js',
        eTooltip: 'echarts/lib/component/tooltip',
        eGrid: 'echarts/lib/component/grid',
        eLine: 'echarts/lib/chart/line',
        eTitle: 'echarts/lib/component/title',
        babelPolyfill: 'babel-polyfill',
        constants: ['./src/constants/statusCode.js', './src/constants/sysConstants.js', './src/constants/url.js'],
        cjs: ['./src/js/globalJs.js','./src/js/HocHidden.js','./src/js/msgReducer.js','./src/js/requestUtil.js','./src/js/sagaUtil.js','./src/js/sysMsgUtil.js','./src/js/uploadUtil.js'],
        area: './src/routes/po/components/Area.js',
        aTable: 'antd/lib/table',
        aDatePicker: 'antd/lib/date-picker'
    } : [
        './src/index.js',
    ];
// 提取项目中 css
const extractCSS = new ExtractTextPlugin('stylesheets/[name]-one.css');
// 提取项目中 less
const extractLESS = new ExtractTextPlugin('stylesheets/[name]-two.css');
const plugins = PROD ? [
        // 导出 css
        extractCSS,
        // 导出 less
        extractLESS,
        // 提取公共 js
        new webpack.optimize.CommonsChunkPlugin({
            names:['aDatePicker', 'aTable', 'area', 'cjs', 'constants', 'babelPolyfill', 'eTooltip', 'eGrid', 'eLine', 'eTitle'],
            filename:"js/CommonsLibs/[name].chunk.js",
            minChunks: Infinity
        }),
        // 丑化js
        new webpack.optimize.UglifyJsPlugin({
            minimize: true,
            mangle: false,
            output: {
                // 最紧凑的输出
                beautify: false,
                // 去掉注释
                comments: false,
                screw_ie8: false
            },
            compress: {
                warnings: false,
                // 删除conslos.*
                drop_console: true,
            },
            warnings: false
        }),
        // 设置此模式为生产模式
        new webpack.DefinePlugin({
            'process.env.NODE_ENV': JSON.stringify('production')
        }),
        // gzip 压缩
        new CompressionPlugin({
            asset: "[path].gz[query]",
            algorithm: "gzip",
            test: /\.js$|\.css$|\.html$/,
            threshold: 10240,
            minRatio: 0.8
        })
        // new BundleAnalyzerPlugin()
    ] : [
        // 设置此模式为开发模式
        new webpack.DefinePlugin({
            'process.env.NODE_ENV': JSON.stringify('development')
        })
    ];
const cssIdentName = PROD ? '[hash:base64:10]' : '[path][name]-[local]-[hash:base64:24]';
const cssLoader = PROD ?
    extractCSS.extract({
        fallbackLoader: "style-loader",
        loader: 'css-loader?localIdentName=' + cssIdentName
    })
    : [
        'style-loader', 'css-loader?localIdentName=' + cssIdentName
    ];
const lessLoader = PROD ?
    extractLESS.extract({
        fallback: "style-loader",
        use: [{
            loader: 'css-loader'
        }, {
            // modifyVars 更改全局样式
            loader: 'less-loader?{modifyVars:{"@primary-color":"#0d85db", "@font-size-base":"12px"}}'
        }]
    })
    : ['style-loader', 'css-loader', 'less-loader?{modifyVars:{"@primary-color":"#0d85db", "@font-size-base":"12px"}}'];

module.exports = {
    devtool: devtool,
    entry: entry,
    output: {
        // 打包文件名
        filename: filename,
        // bundle.js 输出路径,是一个绝对路径
        path: path.join(__dirname, 'dist'),
        // 在 html 页面中需要的导入资源的路径
        publicPath: '/dist/',
        // 设置按需加载 js 的名文件名
        chunkFilename: "[name].[hash:8].chunk.js"
    },
    plugins: plugins,
    module: {
        rules:[
            // 解析装载 js
            {
                test: /\.(js|jsx)$/,
                exclude: '/node_modules/',
                loader: 'babel-loader',
                query: {
                    // 加入 antd 模块,并使支持 less
                    plugins: [
                        ['import', [{libraryName: 'antd', style: true}]], // antd 按需引入
                        ["transform-decorators-legacy"], // redux @connect
                    ],
                    cacheDirectory: true,
                },
            },
            // 解析装载图片,等文件
            {
                test: /\.(jpg|gif|png)$/,
                exclude: '/node_modules/',
                // loader: 'file-loader'
                loader: 'url-loader?limit=512&name=[path][name].[ext]?[hash]',
            },
            // 解析装载 css
            {
                test: /\.css$/,
                exclude: '/node_modules/',
                use: cssLoader,
            },
            // 解析装载 less
            {
                test: /\.less$/,
                exclude: '/node_modules/',
                use: lessLoader,

            },
            // 解析 iconfont
            {
                test:/\.(woff|eot|svg|ttf|ppt|pdf|doc)\??.*$/,
                loader:"url-loader?name=fonts/[name].[md5:hash:hex:7].[ext]"
            }
        ]
    },
    // 剔除的js生产环境时需要从 cdn 引入
    externals: PROD ? {
            'react': 'React',
            'react-dom': 'ReactDOM',
            "react-router": "ReactRouter",
            'redux': 'Redux',
            'react-redux': 'ReactRedux',
            'immutable': 'Immutable',
            'moment': 'moment',
            'moment/locale/zh-cn' : 'moment.locale',
        } : {},
    devServer: {
        host: '0.0.0.0',
        port: 8080,
        // hot: true,
        publicPath: '/dist/',
        stats: {
            colors: true
        },
        inline: true,
        // 代理
        /*proxy: {
         '/api': {
         target: 'http://192.168.1.249:8000',
         changeOrigin: true,
         secure: false,
         }
         },*/
        historyApiFallback: true,
        disableHostCheck:true,
        // contentBase: './',
    },
    performance: {
        hints: false,
    },
    cache: false,
};

拆分JS前,打包出来的JS文件

  Asset       Size  Chunks                    Chunk Names
                                             NoMatch.b15e9476.chunk.js    3.11 kB       3  [emitted]         NoMatch
    src/routes/home/assets/banner.jpg?5fdef1dca3b20a658d6d87b312362522     124 kB          [emitted]
      src/routes/home/assets/head.png?0bd162dda92de9f3eb8a4dcea472d6da    6.55 kB          [emitted]
   src/routes/loginHome/assets/bg.jpg?535455e0d36d4ee16ffee51706e3284e     299 kB          [emitted]  [big]
 src/routes/loginHome/assets/logo.png?09a31bb3dbdb670d09c26d4ab5ed454a    14.7 kB          [emitted]
src/routes/loginHome/assets/title.png?03304e154d5eb5fa40586a6dbd293157    16.9 kB          [emitted]
                                               index.b15e9476.chunk.js     181 kB       0  [emitted]         index
                                          InOutMoney.b15e9476.chunk.js    32.7 kB       1  [emitted]         InOutMoney
                                       WalletMessage.b15e9476.chunk.js    8.01 kB       2  [emitted]         WalletMessage
   src/routes/home/assets/banner2.jpg?721a5e7b892c79514d6ee772a9438003     136 kB          [emitted]
                                         NoAuthority.b15e9476.chunk.js    3.08 kB       4  [emitted]         NoAuthority
                                                             bundle.js    8.41 MB       5  [emitted]  [big]  main
                                           index.b15e9476.chunk.js.map     245 kB       0  [emitted]         index
                                      InOutMoney.b15e9476.chunk.js.map    21.6 kB       1  [emitted]         InOutMoney
                                   WalletMessage.b15e9476.chunk.js.map     4.1 kB       2  [emitted]         WalletMessage
                                         NoMatch.b15e9476.chunk.js.map  724 bytes       3  [emitted]         NoMatch
                                     NoAuthority.b15e9476.chunk.js.map  813 bytes       4  [emitted]         NoAuthority
                                                         bundle.js.map    11.8 MB       5  [emitted]         main

拆分JS后,打包出来的JS文件

 Asset     Size  Chunks                    Chunk Names
                                 js/CommonsLibs/babelPolyfill.chunk.js  92.9 kB      65  [emitted]         babelPolyfill
      src/routes/home/assets/head.png?0bd162dda92de9f3eb8a4dcea472d6da  6.55 kB          [emitted]
   src/routes/home/assets/banner2.jpg?721a5e7b892c79514d6ee772a9438003   136 kB          [emitted]
   src/routes/loginHome/assets/bg.jpg?535455e0d36d4ee16ffee51706e3284e   299 kB          [emitted]  [big]
 src/routes/loginHome/assets/logo.png?09a31bb3dbdb670d09c26d4ab5ed454a  14.7 kB          [emitted]
src/routes/loginHome/assets/title.png?03304e154d5eb5fa40586a6dbd293157  16.9 kB          [emitted]
                                             NoMatch.dac1ea70.chunk.js   1.4 kB       0  [emitted]         NoMatch
                                                Home.dac1ea70.chunk.js   145 kB       1  [emitted]         Home
                                               index.dac1ea70.chunk.js   112 kB       2  [emitted]         index
                                            LrPayoff.dac1ea70.chunk.js    81 kB       3  [emitted]         LrPayoff
                                           PurCreate.dac1ea70.chunk.js  72.2 kB       4  [emitted]         PurCreate
                                          SCMaintain.dac1ea70.chunk.js  57.5 kB       5  [emitted]         SCMaintain
                                         SellReceipt.dac1ea70.chunk.js  47.6 kB       6  [emitted]         SellReceipt
                                  SCMaintainBaseInfo.dac1ea70.chunk.js  48.7 kB       7  [emitted]         SCMaintainBaseInfo
                                             ViewSto.dac1ea70.chunk.js  50.4 kB       8  [emitted]         ViewSto
                                       LoanRepayment.dac1ea70.chunk.js  59.6 kB       9  [emitted]         LoanRepayment
                                                Loan.dac1ea70.chunk.js    56 kB      10  [emitted]         Loan
                                                 Pur.dac1ea70.chunk.js  54.3 kB      11  [emitted]         Pur
                                                Func.dac1ea70.chunk.js  70.8 kB      12  [emitted]         Func
                                          SIMaintain.dac1ea70.chunk.js  45.1 kB      13  [emitted]         SIMaintain
                                                User.dac1ea70.chunk.js  29.2 kB      14  [emitted]         User
                                           UserGroup.dac1ea70.chunk.js  28.1 kB      15  [emitted]         UserGroup
                                        SysParameter.dac1ea70.chunk.js  26.3 kB      16  [emitted]         SysParameter
                                                Role.dac1ea70.chunk.js  42.8 kB      17  [emitted]         Role
                                          FBMaintain.dac1ea70.chunk.js  37.3 kB      18  [emitted]         FBMaintain
                                    BorrowerMaintain.dac1ea70.chunk.js  42.6 kB      19  [emitted]         BorrowerMaintain
                                      PurVendorAudit.dac1ea70.chunk.js  36.8 kB      20  [emitted]         PurVendorAudit
                                     PurStoreConfirm.dac1ea70.chunk.js  37.1 kB      21  [emitted]         PurStoreConfirm
                                          PurSoldOut.dac1ea70.chunk.js  37.2 kB      22  [emitted]         PurSoldOut
                                           PurRefuse.dac1ea70.chunk.js  31.6 kB      23  [emitted]         PurRefuse
                                    PurPlatformAudit.dac1ea70.chunk.js  34.8 kB      24  [emitted]         PurPlatformAudit
                                       PurObligation.dac1ea70.chunk.js  32.7 kB      25  [emitted]         PurObligation
                                     PurFundShortage.dac1ea70.chunk.js    33 kB      26  [emitted]         PurFundShortage
                                     PurDropShipping.dac1ea70.chunk.js  35.5 kB      27  [emitted]         PurDropShipping
                                         PurComplete.dac1ea70.chunk.js  32.2 kB      28  [emitted]         PurComplete
                                           PurCancel.dac1ea70.chunk.js  31.2 kB      29  [emitted]         PurCancel
                                    LoanStoreConfirm.dac1ea70.chunk.js  33.5 kB      30  [emitted]         LoanStoreConfirm
                                      LoanForLending.dac1ea70.chunk.js    31 kB      31  [emitted]         LoanForLending
                                          LoanCancel.dac1ea70.chunk.js    31 kB      32  [emitted]         LoanCancel
                                     LoanBeenLending.dac1ea70.chunk.js    31 kB      33  [emitted]         LoanBeenLending
                                       LoanBankAudit.dac1ea70.chunk.js    31 kB      34  [emitted]         LoanBankAudit
                                          LoanCreate.dac1ea70.chunk.js  36.2 kB      35  [emitted]         LoanCreate
                                  SIMaintainBaseInfo.dac1ea70.chunk.js  33.5 kB      36  [emitted]         SIMaintainBaseInfo
                            BorrowerMaintainBaseInfo.dac1ea70.chunk.js  32.3 kB      37  [emitted]         BorrowerMaintainBaseInfo
                                          WalletFund.dac1ea70.chunk.js  23.8 kB      38  [emitted]         WalletFund
                                   LogOperationTable.dac1ea70.chunk.js    16 kB      39  [emitted]         LogOperationTable
                                     ReceivedPayment.dac1ea70.chunk.js  12.9 kB      40  [emitted]         ReceivedPayment
                                            PayMoney.dac1ea70.chunk.js    14 kB      41  [emitted]         PayMoney
                                       ResetPassword.dac1ea70.chunk.js    11 kB      42  [emitted]         ResetPassword
                                            CheckSto.dac1ea70.chunk.js    15 kB      43  [emitted]         CheckSto
                                        BankMaintain.dac1ea70.chunk.js  11.9 kB      44  [emitted]         BankMaintain
                                          BBMaintain.dac1ea70.chunk.js  12.9 kB      45  [emitted]         BBMaintain
                                          WKMaintain.dac1ea70.chunk.js  7.42 kB      46  [emitted]         WKMaintain
                                          InOutMoney.dac1ea70.chunk.js  8.02 kB      47  [emitted]         InOutMoney
                                     StoreAdjustment.dac1ea70.chunk.js  10.1 kB      48  [emitted]         StoreAdjustment
                                 InitialStoreBalance.dac1ea70.chunk.js  8.43 kB      49  [emitted]         InitialStoreBalance
                                          SWMaintain.dac1ea70.chunk.js  11.2 kB      50  [emitted]         SWMaintain
                                       WalletMessage.dac1ea70.chunk.js  2.58 kB      51  [emitted]         WalletMessage
                                              Wallet.dac1ea70.chunk.js  2.53 kB      52  [emitted]         Wallet
                                     StoreSellOutSto.dac1ea70.chunk.js   4.9 kB      53  [emitted]         StoreSellOutSto
                               StoreAdjustmentDetail.dac1ea70.chunk.js  5.32 kB      54  [emitted]         StoreAdjustmentDetail
                                    SalesOutstanding.dac1ea70.chunk.js  1.39 kB      55  [emitted]         SalesOutstanding
                                      FlatSellOutSto.dac1ea70.chunk.js  4.66 kB      56  [emitted]         FlatSellOutSto
                                         NoAuthority.dac1ea70.chunk.js  1.37 kB      57  [emitted]         NoAuthority
                                BankMaintainBaseInfo.dac1ea70.chunk.js  4.08 kB      58  [emitted]         BankMaintainBaseInfo
                                  BBMaintainBaseInfo.dac1ea70.chunk.js  4.65 kB      59  [emitted]         BBMaintainBaseInfo
                                   ToBeAssignedStore.dac1ea70.chunk.js  5.44 kB      60  [emitted]         ToBeAssignedStore
                                     StoreAllotClerk.dac1ea70.chunk.js  5.32 kB      61  [emitted]         StoreAllotClerk
                                          SBMaintain.dac1ea70.chunk.js  4.95 kB      62  [emitted]         SBMaintain
                                  BorrowerAllotStore.dac1ea70.chunk.js  6.64 kB      63  [emitted]         BorrowerAllotStore
                                                             bundle.js   521 kB      64  [emitted]  [big]  bundle
    src/routes/home/assets/banner.jpg?5fdef1dca3b20a658d6d87b312362522   124 kB          [emitted]
                                           js/CommonsLibs/cjs.chunk.js    89 kB      66  [emitted]         cjs
                                        js/CommonsLibs/aTable.chunk.js   231 kB      67  [emitted]         aTable
                                   js/CommonsLibs/aDatePicker.chunk.js   109 kB      68  [emitted]         aDatePicker
                                         js/CommonsLibs/eLine.chunk.js  42.5 kB      69  [emitted]         eLine
                                         js/CommonsLibs/eGrid.chunk.js  16.2 kB      70  [emitted]         eGrid
                                     js/CommonsLibs/constants.chunk.js  22.9 kB      71  [emitted]         constants
                                      js/CommonsLibs/eTooltip.chunk.js  11.9 kB      72  [emitted]         eTooltip
                                          js/CommonsLibs/area.chunk.js  97.6 kB      73  [emitted]         area
                                        js/CommonsLibs/eTitle.chunk.js   220 kB      74  [emitted]         eTitle
                                            stylesheets/bundle-two.css   295 kB      64  [emitted]  [big]  bundle
                                               stylesheets/cjs-two.css    30 kB      66  [emitted]         cjs
                                      SellReceipt.dac1ea70.chunk.js.gz  13.3 kB          [emitted]
                               SCMaintainBaseInfo.dac1ea70.chunk.js.gz  13.6 kB          [emitted]
                                          ViewSto.dac1ea70.chunk.js.gz  13.3 kB          [emitted]
                                             Loan.dac1ea70.chunk.js.gz  14.5 kB          [emitted]
                                    LoanRepayment.dac1ea70.chunk.js.gz  14.2 kB          [emitted]
                                              Pur.dac1ea70.chunk.js.gz  14.4 kB          [emitted]
                                       SIMaintain.dac1ea70.chunk.js.gz  11.9 kB          [emitted]
                                             User.dac1ea70.chunk.js.gz  8.29 kB          [emitted]
                                        UserGroup.dac1ea70.chunk.js.gz  7.67 kB          [emitted]
                                     SysParameter.dac1ea70.chunk.js.gz  7.52 kB          [emitted]
                                       FBMaintain.dac1ea70.chunk.js.gz  10.3 kB          [emitted]
                                             Role.dac1ea70.chunk.js.gz  11.2 kB          [emitted]
                                 BorrowerMaintain.dac1ea70.chunk.js.gz  11.6 kB          [emitted]
                                   PurVendorAudit.dac1ea70.chunk.js.gz  8.35 kB          [emitted]
                                  PurStoreConfirm.dac1ea70.chunk.js.gz  8.46 kB          [emitted]
                                       PurSoldOut.dac1ea70.chunk.js.gz  8.32 kB          [emitted]
                                        PurRefuse.dac1ea70.chunk.js.gz   7.2 kB          [emitted]
                                 PurPlatformAudit.dac1ea70.chunk.js.gz  8.12 kB          [emitted]
                                    PurObligation.dac1ea70.chunk.js.gz  7.54 kB          [emitted]
                                  PurDropShipping.dac1ea70.chunk.js.gz  8.21 kB          [emitted]
                                  PurFundShortage.dac1ea70.chunk.js.gz  7.67 kB          [emitted]
                                      PurComplete.dac1ea70.chunk.js.gz  7.34 kB          [emitted]
                                        PurCancel.dac1ea70.chunk.js.gz   7.1 kB          [emitted]
                                 LoanStoreConfirm.dac1ea70.chunk.js.gz  7.63 kB          [emitted]
                                   LoanForLending.dac1ea70.chunk.js.gz  7.16 kB          [emitted]
                                       LoanCancel.dac1ea70.chunk.js.gz  7.14 kB          [emitted]
                                    LoanBankAudit.dac1ea70.chunk.js.gz  7.14 kB          [emitted]
                                  LoanBeenLending.dac1ea70.chunk.js.gz  7.14 kB          [emitted]
                                       LoanCreate.dac1ea70.chunk.js.gz  9.25 kB          [emitted]
                               SIMaintainBaseInfo.dac1ea70.chunk.js.gz  9.14 kB          [emitted]
                         BorrowerMaintainBaseInfo.dac1ea70.chunk.js.gz  9.03 kB          [emitted]
                                       WalletFund.dac1ea70.chunk.js.gz  5.75 kB          [emitted]
                                LogOperationTable.dac1ea70.chunk.js.gz  5.42 kB          [emitted]
                                         PayMoney.dac1ea70.chunk.js.gz  4.45 kB          [emitted]
                                  ReceivedPayment.dac1ea70.chunk.js.gz   4.2 kB          [emitted]
                                    ResetPassword.dac1ea70.chunk.js.gz  4.23 kB          [emitted]
                                         CheckSto.dac1ea70.chunk.js.gz  3.84 kB          [emitted]
                                     BankMaintain.dac1ea70.chunk.js.gz  3.87 kB          [emitted]
                                  StoreAdjustment.dac1ea70.chunk.js.gz  3.35 kB          [emitted]
                                       BBMaintain.dac1ea70.chunk.js.gz  4.22 kB          [emitted]
                                       SWMaintain.dac1ea70.chunk.js.gz  3.23 kB          [emitted]
                                      js/CommonsLibs/eGrid.chunk.js.gz  6.22 kB          [emitted]
                                   js/CommonsLibs/eTooltip.chunk.js.gz  4.48 kB          [emitted]
                                  js/CommonsLibs/constants.chunk.js.gz  5.26 kB          [emitted]
                                      js/CommonsLibs/eLine.chunk.js.gz  15.1 kB          [emitted]
                                            stylesheets/cjs-two.css.gz  5.52 kB          [emitted]
                                            index.dac1ea70.chunk.js.gz  31.3 kB          [emitted]
                                         LrPayoff.dac1ea70.chunk.js.gz    20 kB          [emitted]
                                        PurCreate.dac1ea70.chunk.js.gz  18.3 kB          [emitted]
                                       SCMaintain.dac1ea70.chunk.js.gz  16.4 kB          [emitted]
                                             Func.dac1ea70.chunk.js.gz  19.8 kB          [emitted]
                              js/CommonsLibs/babelPolyfill.chunk.js.gz  29.5 kB          [emitted]
                                js/CommonsLibs/aDatePicker.chunk.js.gz  24.3 kB          [emitted]
                                        js/CommonsLibs/cjs.chunk.js.gz  27.4 kB          [emitted]
                                             Home.dac1ea70.chunk.js.gz  39.2 kB          [emitted]
                                       js/CommonsLibs/area.chunk.js.gz  26.5 kB          [emitted]
                                     js/CommonsLibs/aTable.chunk.js.gz  60.7 kB          [emitted]
                                         stylesheets/bundle-two.css.gz  52.9 kB          [emitted]
                                     js/CommonsLibs/eTitle.chunk.js.gz  75.4 kB          [emitted]
                                                          bundle.js.gz   106 kB          [emitted]
结论

bundle.js举例说明,可以说拆分JS后效果十分明显。在开启gzip压缩后,效果更是明显。部署在阿里云1M带宽下的展现。

JS 名称 拆分前 JS 大小 (MB) 拆分后未压缩JS 大小 (kb) 拆分压缩后 JS 大小 (kb) 拆分前加载速度 (s) 拆分压缩后加载速度 (s)
bundle.js 8.41 521 106 10-30 2以内

再进行优化前的建议

优化前大家先分析一下项目中bundle.js的组成成分。那么首先介绍2种工具

  1. webpack-chart 可以大致了解下,各个JS的大小以及分布情况
  2. 重点推荐webpack-bundle-analyzer插件通过 npm安装具体安装方式不复述了。
    使用方法:
    具体请看上面webpack配置文件
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;

plugins: new BundleAnalyzerPlugin() // 具体请看上面webpack配置文件

插件加进去后,启动自动会弹出一个网页,详细的告诉你,你每个JS下都由什么JS组成的大小是多少,根据该图可以很容易进行优化拆分工作。

webpack-bundle-analyzer 插件所提供的功能

如何使用 Webpack 拆分 JS

正如前面给出的Webpack配置文件,关于Webpack配置文件的配置这里就不细说了。

  1. 采用 CommonsChunkPlugin 插件 为了提取公共JS
  2. ExtractTextPlugin 插件 为了把公共的CSS、LESSJS中提取出来进一步减少JS的大小
  3. externals 属性 剔除不需要打包的JScdn中引用,达到节约带宽的目的

如何使用 react-router 动态路由

我用的是react-router@4,版本4以下的请绕行。采用该团队提供的bundle-loader包,可以到达动态路由的效果。

  1. 安装 npm i D bundle-loader
  2. 在此基础上我又封装了一个方法,如果组件正常加载则加载,如果没有显示一个正在加载的组件
export const createComponent = (component) => () => (
    <Bundle load={component}>
        {
            (Component) => Component ? <Component /> : <Loading />
        }
    </Bundle>
);
  1. 在路由配置JS文件导入某个组件
import ViewSto from "bundle-loader?lazy&name=ViewSto!../routes/sto/components/ViewSto";
  1. 在路由配置JS文件中使用该组件
<Route path="/appLayout/viewSto" component={createComponent(ViewSto)} />

至此动态路由配置完成。

如何优化 JS 加载速度

正如前面给出的Webpack配置文件

  1. UglifyJsPlugin 丑化JS 具体配置请参照我上面给出的例子,具体参数请看这里
  2. CompressionPlugin 进一步减小JS的大小,压缩JS,具体参数请看这里

关于被拆分、剔除出来的 JS 在 HTML 中的引用顺序

如果引用顺序不对会在访问时报错,不能正常加载首页内容。它们的顺序应该是根据Webpack 配置文件中的CommonsChunkPlugin插件names属性中定义抽取公共JS名称数组,顺序从后往前依次递增。例如:

new webpack.optimize.CommonsChunkPlugin({
            names:['aDatePicker', 'aTable', 'area', 'cjs', 'constants', 'babelPolyfill', 'eTooltip', 'eGrid', 'eLine', 'eTitle'],
            filename:"js/CommonsLibs/[name].chunk.js",
            minChunks: Infinity
}),

HTML 中引用JS的顺序

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>***</title>
    <link rel="stylesheet" href="/dist/stylesheets/cjs-two.css" />
    <link rel="stylesheet" href="/dist/stylesheets/bundle-two.css" />

</head>
<body>
<div id="app">
    <script src="https://cdn.bootcss.com/react/15.5.4/react.min.js"></script>
    <script src="https://cdn.bootcss.com/react/15.5.4/react-dom.min.js"></script>
    <script src="https://cdn.bootcss.com/react-router/4.1.1/react-router.min.js"></script>
    <script src="https://cdn.bootcss.com/redux/3.6.0/redux.min.js"></script>
    <script src="https://cdn.bootcss.com/react-redux/5.0.5/react-redux.min.js"></script>
    <script src="https://cdn.bootcss.com/immutable/3.8.1/immutable.min.js"></script>
    <script src="https://cdn.bootcss.com/moment.js/2.19.3/moment.min.js"></script>
    <script src="https://cdn.bootcss.com/moment.js/2.19.3/locale/zh-cn.js"></script>
    <script src="/dist/js/CommonsLibs/eTitle.chunk.js"></script>
    <script src="/dist/js/CommonsLibs/eLine.chunk.js"></script>
    <script src="/dist/js/CommonsLibs/eGrid.chunk.js"></script>
    <script src="/dist/js/CommonsLibs/eTooltip.chunk.js"></script>
    <script src="/dist/js/CommonsLibs/babelPolyfill.chunk.js"></script>
    <script src="/dist/js/CommonsLibs/constants.chunk.js"></script>
    <script src="/dist/js/CommonsLibs/cjs.chunk.js"></script>
    <script src="/dist/js/CommonsLibs/area.chunk.js"></script>
    <script src="/dist/js/CommonsLibs/aTable.chunk.js"></script>
    <script src="/dist/js/CommonsLibs/aDatePicker.chunk.js"></script>
    <script src="/dist/bundle.js"></script>
</div>
</body>
</html>

实际请求

反向代理使用nginx,使用nginx开启gzip功能具体可以自行查阅这里就不复述了。

至此全文完毕。如果还有更好的提议或者问题请留言多谢。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 205,033评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,725评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,473评论 0 338
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,846评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,848评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,691评论 1 282
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,053评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,700评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 42,856评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,676评论 2 323
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,787评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,430评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,034评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,990评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,218评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,174评论 2 352
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,526评论 2 343