前言

創(chuàng)新互聯(lián)公司是專業(yè)的灤南網(wǎng)站建設(shè)公司,灤南接單;提供網(wǎng)站設(shè)計(jì)制作、成都網(wǎng)站設(shè)計(jì),網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行灤南網(wǎng)站開(kāi)發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛(ài)的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來(lái)合作!
本文講述怎么實(shí)現(xiàn)動(dòng)態(tài)加載組件,并借此闡述適配器模式。
一、普通路由例子
import Center from 'page/center';
import Data from 'page/data';
function App(){
return (
<Router>
<Switch>
<Route exact path="/" render={() => (<Redirect to="/center" />)} />
<Route path="/data" component={Data} />
<Route path="/center" component={Center} />
<Route render={() => <h2 style={{ textAlign: 'center', marginTop: '160px', color:'rgba(255, 255, 255, 0.7)' }}>頁(yè)面不見(jiàn)了</h2>} />
</Switch>
</Router>
);
}以上是最常見(jiàn)的React router。在簡(jiǎn)單的單頁(yè)應(yīng)用中,這樣寫(xiě)是ok的。因?yàn)榇虬蟮膯我籮s文件bundle.js也不過(guò)200k左右,gzip之后,對(duì)加載性能并沒(méi)有太大的影響。
但是,當(dāng)產(chǎn)品經(jīng)歷多次迭代后,追加的頁(yè)面導(dǎo)致bundle.js的體積不斷變大。這時(shí)候,優(yōu)化就變得很有必要。
二、如何優(yōu)化
優(yōu)化使用到的一個(gè)重要理念就是——按需加載。
可以結(jié)合例子進(jìn)行理解為:只加載當(dāng)前頁(yè)面需要用到的組件。
比如當(dāng)前訪問(wèn)的是/center頁(yè),那么只需要加載Center組件即可。不需要加載Data組件。
業(yè)界目前實(shí)現(xiàn)的方案有以下幾種:
•react-router的動(dòng)態(tài)路由getComponent方法(router4已不支持)
•使用react-loadable小工具庫(kù)
•自定義高階組件進(jìn)行按需加載
而這些方案共通的點(diǎn),就是利用webpack的code splitting功能(webpack1使用require.ensure,webpack2/webpack3使用import),將代碼進(jìn)行分割。
接下來(lái),將介紹如何用自定義高階組件實(shí)現(xiàn)按需加載。
三、自定義高階組件
3.1 webpack的import方法
webpack將import()看做一個(gè)分割點(diǎn)并將其請(qǐng)求的module打包為一個(gè)獨(dú)立的chunk。import()以模塊名稱作為參數(shù)名并且返回一個(gè)Promise對(duì)象。
因?yàn)閕mport()返回的是Promise對(duì)象,所以不能直接給<Router/>使用。
3.2 采用適配器模式封裝import()
適配器模式(Adapter):將一個(gè)類的接口轉(zhuǎn)換成客戶希望的另外一個(gè)接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些類可以一起工作。
當(dāng)前場(chǎng)景,需要解決的是,使用import()異步加載組件后,如何將加載的組件交給React進(jìn)行更新。
方法也很容易,就是利用state。當(dāng)異步加載好組件后,調(diào)用setState方法,就可以通知到。
那么,依照這個(gè)思路,新建個(gè)高階組件,運(yùn)用適配器模式,來(lái)對(duì)import()進(jìn)行封裝。
3.3 實(shí)現(xiàn)異步加載方法asyncComponent
import React from 'react';
export const asyncComponent = loadComponent => (
class AsyncComponent extends React.Component {
constructor(...args){
super(...args);
this.state = {
Component: null,
};
this.hasLoadedComponent = this.hasLoadedComponent.bind(this);
}
componentWillMount() {
if(this.hasLoadedComponent()){
return;
}
loadComponent()
.then(module => module.default ? module.default : module)
.then(Component => {
this.setState({
Component
});
})
.catch(error => {
/*eslint-disable*/
console.error('cannot load Component in <AsyncComponent>');
/*eslint-enable*/
throw error;
})
}
hasLoadedComponent() {
return this.state.Component !== null;
}
render(){
const {
Component
} = this.state;
return (Component) ? <Component {...this.props} /> : null;
}
}
);
// 使用方式
const Center = asyncComponent(()=>import(/* webpackChunkName: 'pageCenter' */'page/center'));如例子所示,新建一個(gè)asyncComponent方法,用于接收import()返回的Promise對(duì)象。
當(dāng)componentWillMount時(shí)(服務(wù)端渲染也有該生命周期方法),執(zhí)行import(),并將異步加載的組件,set入state,觸發(fā)組件重新渲染。
3.4 釋疑
•state.Component初始化
this.state = {
Component: null,
};這里的null,主要用于判斷異步組件是否已經(jīng)加載。
•module.default ? module.default : module
這里是為了兼容具名和default兩種export寫(xiě)法。
•return (Component) ? <Component {...this.props} /> : null;
這里的null,其實(shí)可以用<LoadingComponent />代替。作用是:當(dāng)異步組件還沒(méi)加載好時(shí),起到占位的作用。
this.props是通過(guò)AsyncComponent組件透?jìng)鹘o異步組件的。
3.5 修改webpack構(gòu)建
output: {
path: config.build.assetsRoot,
filename: utils.assetsPath('js/[name].[chunkhash].js'),
chunkFilename: utils.assetsPath('js/[id].[chunkhash].js')
}在輸出項(xiàng)中,增加chunkFilename即可。
四、小結(jié)
自定義高階組件的好處,是可以按最少的改動(dòng),來(lái)優(yōu)化已有的舊項(xiàng)目。
像上面的例子,只需要改變import組件的方式即可。花最少的代價(jià),就可以得到頁(yè)面性能的提升。
其實(shí),react-loadable也是按這種思路去實(shí)現(xiàn)的,只不過(guò)增加了很多附屬的功能點(diǎn)而已。
以上所述是小編給大家介紹的React router動(dòng)態(tài)加載組件之適配器模式的應(yīng)用,希望對(duì)大家有所幫助,如果大家有任何疑問(wèn)請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)創(chuàng)新互聯(lián)網(wǎng)站的支持!
本文名稱:Reactrouter動(dòng)態(tài)加載組件之適配器模式的應(yīng)用詳解
文章出自:http://www.chinadenli.net/article12/gidgdc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供域名注冊(cè)、品牌網(wǎng)站建設(shè)、標(biāo)簽優(yōu)化、網(wǎng)站導(dǎo)航、營(yíng)銷型網(wǎng)站建設(shè)、App開(kāi)發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)