在瀏覽器打開React單頁應(yīng)用,習(xí)慣上會(huì)把整個(gè)應(yīng)用所有的JS文件一次性加載完。什么?暫時(shí)不需要的JS文件也要加載,這肯定很慢吧?對(duì)。那你不妨試試下面這種對(duì)JS文件的懶加載,看合不合你項(xiàng)目使用。
一、安裝bundle-loader依賴
npm i --save-dev bundle-loader
二、定義一個(gè)叫作lazy.js的React高階類。
import React, {Component} from 'react'
import PropTypes from 'prop-types'
class Lazy extends Component {
constructor (props) {
super(props)
this.state = {
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({
mod: mod.default ? mod.default : mod
})
})
}
render () {
return this.state.mod ? this.props.children(this.state.mod) : null
}
}
Bundle.propTypes = {
load: PropTypes.any,
children: PropTypes.any
}
export default function lazy (lazyClass) {
return function Wrapper (props) {
return <Bundle load={lazyClass}>
{(Clazz) => <Clazz {...props} />}
</Bundle>
}
}
三、對(duì)<Router>部分的代碼進(jìn)行修改。
改前:
<Router history={hashHistory}>
<div>
<Route exact path={['/', '/index.html']} component={Home} />
<Route path='/case' component={Demo} />
<Route path='/about' component={About} />
<Route path='/article' component={Article} />
</div>
</Router>
改后:
<Router history={hashHistory}>
<div>
<Route exact path={['/', '/index.html']} component={lazy(Home)} />
<Route path='/case' component={lazy(Demo)} />
<Route path='/about' component={lazy(About)} />
<Route path='/article' component={lazy(Article)} />
</div>
</Router>
使用之前,記得先把lazy.js import進(jìn)來。如
import lazy from './lazy.js'
看到?jīng)]有,就是用一個(gè)叫做lazy()的方法,去包住原來的那個(gè)React自定義組件名,如Home, About等。
四、正常運(yùn)行你的webpack的編譯過程,你會(huì)發(fā)現(xiàn)原來所生成的單一的JS文件,如bundle.js,現(xiàn)在已經(jīng)變成了像下面這樣的四個(gè)文件。
bundle.js
bundle-0.js
bundle-1.js
bundle-2.js
bundle-3.js
五、快去打開瀏覽器看看,是不是真的實(shí)現(xiàn)了JS懶加載。
如打開http://localhost:7000/about
,會(huì)加載bundle.js和bundle-3.js
image.png
如打開http://localhost:7000/case,會(huì)加載bundle.js和bundle-1.js
image.png
(本文供刁導(dǎo)參考)