内容简介:React + webpack 之性能优化
React + webpack 之性能优化
一句很经典的话:没到性能瓶颈的时候,最好不要随意的优化。
1.性能问题
性能问题归根到底就是项目越来越大,文件越来越复杂,导致webpack打包的bundle.js的包越来越大,页面加载也就变的越来越慢。
使用chrome 的 performance分析代码,可以很明显的看到,主要的时间都花在了Evaluate script上面,但这部分我目前没有找到解决方案,所以只能从所以js包的体积入手。
2.基本的解决方案
1. 从webpack入手,webpack本身会有一些插件的优化方法。
1.UglifyJsPlugin 压缩代码的插件(这个可以很显著的缩小包的体积)
new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false } }),
2. CommonsChunkPlugin (合并代码)
两个用法:一个是抽取公共的包,另一个则是把多个保重的公共依赖抽取出来
-
抽取公共包可以优化整体包的体积,一般用在开发环境,可以加快rebuild的速度
-
抽取公共依赖可以优化整体包的体积,即可以一次下载多次使用,后面的包因为公共依赖的被提取,包的体积减小,可以加快运行速度。
抽出公共代码(可以抽出一些公用模块,降低整个项目但也仅仅只能减少js下载的时间,并不能减少Evaluate script的时间,并且这还会使得两个包的总体积变大),
new webpack.optimize.CommonsChunkPlugin({
names: ['vendor'],
filename: '[name].js',
minChunks: Infinity
})
-
Defineplugin
这个插件用来定义全局变量,在webpack打包的时候会对这些变量做替换。这里替换成了production,
react代码中有很多的NODE_ENV变量判断
new webpack.DefinePlugin({ // <-- 减少 React 大小的关键
'process.env': {
NODE_ENV: JSON.stringify('production')
}
})
2. 从代码层面入手
1.首先你应该要知道code splitting这个东西,这个是代码层面优化的根基。
code splitting,就是代码分割,简而言之就是代码分割成一个个小块,每次页面加载时,我只需要加载那些我需要的部分(加载包的体积变小了),这样可以让页面加载的更快。
那么如何实现呢?
-
route层面入手
route2-3中有一个叫做getComponent的方法,可以配置按需加载route,即原来A,B,C三个界面生成一个bundle.js的包,使用了按需加载之后,会变为一个bundle.js包加上3个chunk包,这个时候bundle.js包加上三个chunk包的总大小会比原来的bundle.js包稍微大一点,但是我想进入A界面,我只需要加载bundle.js包和A的chunk包,那么我的A页面加载速度便会变得快许多。
-
实际代码入手
1.先学会分析代码,分析代码结构,分析你的包中到底是什么东西如此之大。
借助工具:
npm install webpack-visualizer-plugin webpack-stats-plugin --save-dev
配置:
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.js
import 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>;
}
以上所述就是小编给大家介绍的《React + webpack 之性能优化》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- 性能优化第一课:性能指标
- 【前端性能优化】vue性能优化
- Golang 性能测试 (2) 性能分析
- 【前端性能优化】02--vue性能优化
- Java性能 -- 性能调优标准
- Java性能 -- 性能调优策略
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Numerical Recipes 3rd Edition
William H. Press、Saul A. Teukolsky、William T. Vetterling、Brian P. Flannery / Cambridge University Press / 2007-9-6 / GBP 64.99
Do you want easy access to the latest methods in scientific computing? This greatly expanded third edition of Numerical Recipes has it, with wider coverage than ever before, many new, expanded and upd......一起来看看 《Numerical Recipes 3rd Edition》 这本书的介绍吧!