详解React 服务端渲染方案完美的解决方案(6)
动态加载方案
对于大型Web应用程序来说,将所有代码打包成一个文件不是一种优雅的做法,特别是对于单页面应用,用户有时候并不想得到其余路由模块的内容,加载全部模块内容,不仅增加用户等待时间,而且会增加服务器负荷。Webpack提供一个功能可以拆分模块,每一个模块称为chunk,这个功能叫做Code Splitting。你可以在你的代码库中定义分割点,调用require.ensure,实现按需加载,而对于服务端渲染,require.ensure是不存在的,因此需要判断运行环境,提供钩子函数。
重构后的路由模块为
// Hook for server
if (typeof require.ensure !== 'function') {
require.ensure = function(dependencies, callback) {
callback(require)
}
}
const routes = {
childRoutes: [{
path: '/',
component: require('./common/containers/Root').default,
indexRoute: {
getComponent(nextState, callback) {
require.ensure([], require => {
callback(null, require('./home/containers/App').default)
}, 'home')
}
},
childRoutes: [{
path: 'explore',
getComponent(nextState, callback) {
require.ensure([], require => {
callback(null, require('./explore/containers/App').default)
}, 'explore')
}
}, {
path: 'about',
getComponent(nextState, callback) {
require.ensure([], require => {
callback(null, require('./about/containers/App').default)
}, 'about')
}
}]
}]
}
export default routes
优化方案
vendor: ['react', 'react-dom', 'redux', 'react-redux']
所有js模块以chunkhash方式命名
output: {
filename: '[name].[chunkhash:8].js',
chunkFilename: 'chunk.[name].[chunkhash:8].js',
}
提取公共模块,manifest文件起过渡作用
new webpack.optimize.CommonsChunkPlugin({
names: ['vendor', 'manifest'],
filename: '[name].[chunkhash:8].js'
})
提取css文件,以contenthash方式命名
new ExtractTextPlugin('[name].[contenthash:8].css')
模块排序、去重、压缩
new webpack.optimize.OccurrenceOrderPlugin(), // webpack2 已移除
new webpack.optimize.DedupePlugin(), // webpack2 已移除
new webpack.optimize.UglifyJsPlugin({
compress: {warnings: false},
comments: false
})
使用babel-plugin-transform-runtime取代babel-polyfill,可节省大量文件体积
需要注意的是,你不能使用最新的内置实例方法,例如数组的includes方法
{
presets: ['es2015', 'react', 'stage-0'],
plugins: ['transform-runtime']
}
内容版权声明:除非注明,否则皆为本站原创文章。
