详解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'] }
内容版权声明:除非注明,否则皆为本站原创文章。