使用React组件懒加载的形式减少客户端渲染页面首次进入白屏时间,减少首页加载js大小,从而实现更好的用户体验。
通常使用create-react-app构建应用会打包生成3个js文件,main.[hash].chunk.js这是所编写的应用代码,如App.js等,1.[hash].chunk.js这里代码通常是第三方模块,runtime~main.[hash].js这里的代码是webpack运行时一些逻辑,用于加载应用。
在项目较小,或者对加载速度要求不高的场景中,打包成这些文件时完全可行的。但如页面较多,并且对加载速度有一定要求,假设用户只需要访问应用中的某几个路由,但是却要下载全部的js文件,这样对用户来说是很不友好的,所以我们需要根据组件或者路由来对文件进行拆分,在访问时仅需要加载必须的文件即可。
在React 16.6之前的文档中16.5 code-splitting推荐了第三方库React Loadable,使用这个库可以轻松的对组件进行懒加载。基本完美解决这个问题,例如在路由中使用,打包之后按照路由生成多个js文件,在加载对用路由时加载js。
而在React 16.6的时候,官方提供了新的Api React.lazy,使用React.lazy可以轻松动态导入组件16.6 code-splitting,配合Suspense可以解决页面加载loading,这个新方法可以说很方便,也解决了React Loadable一个弊端,在使用React Loadable中,需要为每一个动态加载的组件配置loading,这样一来比较繁琐,而且如果页面中有多个组件都配置loading,在载入的时候就会在页面中有好记得加载中的提示,而使用Suspense则可以避免这些问题。
官方文档中的用法已经比较详细,可以直接套用,但是对比React Loadable发现缺少delay,这样一来即使加载需要时间非常短,也会造成闪屏。不过可以通过添加一些代码自行解决这个问题。
创建Loading组件
import React, {Component} from 'react';
let timer = {};
class Loading extends Component {
state = {
isShow: false
};
componentDidMount() {
// 延迟显示
timer = setTimeout(this.show, 500);
}
componentWillUnmount() {
// 在loading结束时卸载定时器
clearTimeout(timer);
}
show = () => {
this.setState({isShow: true});
};
render() {
return (
this.state.isShow ? <h1>loading</h1> : null
);
}
}
export default Loading;
复制代码
通过这段代码可以解决闪屏问题,并且还可以加入一些其他效果。
注:React.lazy目前并不支持SSR。