Webpack 拆分 JS,react-router 动态路由,
2018-01-18 本文已影响67人
阿波罗程序猿
网上拆分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种工具
-
webpack-chart 可以大致了解下,各个
JS
的大小以及分布情况 - 重点推荐
webpack-bundle-analyzer
插件通过npm
安装具体安装方式不复述了。
使用方法:
具体请看上面webpack配置文件
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
plugins: new BundleAnalyzerPlugin() // 具体请看上面webpack配置文件
插件加进去后,启动自动会弹出一个网页,详细的告诉你,你每个JS
下都由什么JS
组成的大小是多少,根据该图可以很容易进行优化拆分工作。
如何使用 Webpack 拆分 JS
正如前面给出的Webpack
配置文件,关于Webpack
配置文件的配置这里就不细说了。
- 采用
CommonsChunkPlugin 插件
为了提取公共JS
-
ExtractTextPlugin 插件
为了把公共的CSS、LESS
从JS
中提取出来进一步减少JS
的大小 -
externals 属性
剔除不需要打包的JS
从cdn
中引用,达到节约带宽的目的
如何使用 react-router 动态路由
我用的是react-router@4
,版本4以下的请绕行。采用该团队提供的bundle-loader
包,可以到达动态路由的效果。
- 安装
npm i D bundle-loader
- 在此基础上我又封装了一个方法,如果组件正常加载则加载,如果没有显示一个正在加载的组件
export const createComponent = (component) => () => (
<Bundle load={component}>
{
(Component) => Component ? <Component /> : <Loading />
}
</Bundle>
);
- 在路由配置JS文件导入某个组件
import ViewSto from "bundle-loader?lazy&name=ViewSto!../routes/sto/components/ViewSto";
- 在路由配置JS文件中使用该组件
<Route path="/appLayout/viewSto" component={createComponent(ViewSto)} />
至此动态路由配置完成。
如何优化 JS 加载速度
正如前面给出的Webpack
配置文件
关于被拆分、剔除出来的 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
功能具体可以自行查阅这里就不复述了。
至此全文完毕。如果还有更好的提议或者问题请留言多谢。