React v16.6 版本引入了React.lazy,Suspense的功能,这个功能主要是利用了webpack对于es6的import动态载入组件,能够实现组件的懒加载,react路由的按需加载之类的功能react
先演示下React Lazy的简单实用webpack
// App.js
import React, { lazy, Suspense } from 'react';
const Child = lazy(() => import('./Child'))
function App() {
return (
<div className="App">
<Suspense fallback={<div>Loading...</div>}>
<Child />
</Suspense>
</div>
);
}
export default App;
复制代码
// Child.js
import React from 'react';
class Child extends React.Component{
render(){
return <div class="childClass">我是子组件啊</div>
}
}
export default Child;
复制代码
这是最简单的一个lazy demo,过多的不讲了,能够参考React性能优化之代码分割es6
启动项目以后能够发现Child.js已经被打包到2.chunk.js了web
从 Lazy demo 能够总结几个点性能优化
抓住这两个重点,能够用属性代理的高阶组件来实现下bash
// App.js
import React from 'react';
import MyLazy from './MyLazy';
import MySuspense from './MySuspense';
const Child = MyLazy(() => import('./Child'))
function App() {
return (
<div className="App">
<MySuspense fallback={<div>Loading...</div>}>
<Child />
</MySuspense>
</div>
);
}
export default App;
复制代码
// MySuspense.js
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
class MySuspense extends PureComponent{
getChildContext(){
return {
fallback: this.props.fallback
}
}
render(){
return this.props.children;
}
}
MySuspense.childContextTypes = {
fallback: PropTypes.element
};
export default MySuspense;
复制代码
// MyLazy.js
import React, { PureComponent } from 'react';
import PropTypes from 'prop-types';
export default load => {
class MyLazy extends PureComponent{
constructor(){
super();
this.state = {
WrappedComponent: null
};
}
componentDidMount(){
load().then(({ default: Comp }) => {
setTimeout(() => {
this.setState({
WrappedComponent: Comp
});
}, 3000);
})
}
render(){
const { WrappedComponent } = this.state;
return WrappedComponent ? <WrappedComponent /> : this.context.fallback
}
}
MyLazy.contextTypes = {
fallback: PropTypes.element
};
return MyLazy;
}
复制代码
// Child.js
import React from 'react';
class Child extends React.Component{
render(){
return <div>i am child</div>
}
}
export default Child;
复制代码
MyLazy就是个属性代理的高阶组件,可是有个两个问题是app
从官网的Suspense解释来看,能够发现Lazy其实能够放在Suspense下children的任何解构,就是说Suspense和Lazy之间的层级是不固定的,那么使用props来传输fallback有点不现实,没有去看过官方源码,因此我采用的是虫洞congtext的方式去实现函数
虫洞的具体实现细节,能够参考React性能优化之代码分割post
到这里,一个自定义最简单的Lazy和Suspense就实现了性能