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就實現了性能