React + webpack 之性能优化
React + webpack 之性能优化一句很经典的话:没到性能瓶颈的时候,最好不要随意的优化。1.性能问题性能问题归根到底就是项目越来越大,文件越来越复杂,导致webpack打包的bundle.js的包越来越大,页面加载也就变的越来越慢。 使用chrome 的 performance分析代码,可以很明显的看到,主要的时间都花在了Evaluate script上面,但这部分我目前没有找到解决方案,所以只能从所以js包的体积入手。 2.基本的解决方案1. 从webpack入手,webpack本身会有一些插件的优化方法。1.UglifyJsPlugin 压缩代码的插件(这个可以很显著的缩小包的体积)
2.CommonsChunkPlugin (合并代码) 两个用法:一个是抽取公共的包,另一个则是把多个保重的公共依赖抽取出来
抽出公共代码(可以抽出一些公用模块,降低整个项目但也仅仅只能减少js下载的时间,并不能减少Evaluate script的时间,并且这还会使得两个包的总体积变大), new webpack.optimize.CommonsChunkPlugin({ names: ['vendor'],filename: '[name].js',minChunks: Infinity })
这个插件用来定义全局变量,在webpack打包的时候会对这些变量做替换。这里替换成了production, new webpack.DefinePlugin({ // <-- 减少 React 大小的关键 'process.env': { NODE_ENV: JSON.stringify('production') } }) 2. 从代码层面入手1.首先你应该要知道code splitting这个东西,这个是代码层面优化的根基。 code splitting,就是代码分割,简而言之就是代码分割成一个个小块,每次页面加载时,我只需要加载那些我需要的部分(加载包的体积变小了),这样可以让页面加载的更快。 那么如何实现呢?
import: const StatsWriterPlugin = require('webpack-stats-plugin').StatsWriterPlugin; const Visualizer = require('webpack-visualizer-plugin'); plugin: new StatsWriterPlugin({ fields: null,stats: { chunkModules: true } }),new Visualizer({ filename: './statistics.html' }) 正常的webpack run 之后,会在你的output的地方出现statistics.html这个文件,直接用网页打开就可以了
这样就可以分析出你到底是什么导致你bundle.js报如此之大了,但有一些包我们是无法缩减的,例如react-dom,react,但是绝大部分的包都是可以进行缩减的. 那么如何缩减呢? 加入你这个界面中用到了一个三方的图形控件,例如你用了Echart,那么这个包总是很大的,即使是最小的也有300k左右,其实你其他的代码可能都不到100k,那么这300k将会非常影响你这个界面的加载速度,所以需要给这个控件做一个按需加载,这样可以先展示其余的这100k所展示的界面,等待其余的300k下载好了再把Echart给补上。 代码实现: 1.npm install bundle-loader --save-dev 2.需要些这样一个 Bundle.js,无法点击则代码在最底部 3. import EchartContainer from 'bundle-loader?lazy!echart'; import { bundle } from '../../../components/Bundle'; constructor(props) { super(props); this.Echart = bundle(EchartContainer); } render() { return ( <div> <this.Echart /> { (this.props.history.isFetching || this.props.monthly.isFetching) && <div className="spinner"> <Spinner /> </div> } </div>); } 3 代码 Bundle.jsimport React from 'react'; import PropTypes from 'prop-types'; class Bundle extends React.Component { state = { // short for "module" but that's a keyword in js,so "mod" mod: null } componentWillMount() { // 加载初始状态 this.load(this.props); } componentWillReceiveProps(nextProps) { if (nextProps.load !== this.props.load) { this.load(nextProps); } } load(props) { // 重置状态 this.setState({ mod: null }); // 传入组件的组件 props.load((mod) => { this.setState({ // handle both es imports and cjs mod: mod.default ? mod.default : mod }); }); } render() { // if state mode not undefined,The container will render children return this.state.mod ? this.props.children(this.state.mod) : null; } } Bundle.propTypes = { load: PropTypes.func,children: PropTypes.func }; export default Bundle; export function bundle(item) { return props => <Bundle load={item}> {Component => <Component {...props} />} </Bundle>; } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |