React Lazy 和 Suspense
作者:互联网
文章目录
React.lazy 定义
React.lazy
函数能让你像渲染常规组件一样处理动态引用的组件- 什么意思呢,其实就是懒加载。其原理就是利用
ES6 import()
函数。这个import
不是import
命令。 - 同样是引人模块,
import
命令是同步引人模块,而import ()
函数动态引入
代码分割
- 当Webpack 解析到该语法时,它会自动地开始进行代码分割,分割成一个文件,当使用到这个文件的时候才会被异步加载
- 当你的程序越来越大,代码量越来越多。一个页面上堆积了很多功能,也许有些功能很有可能都用不到,但是一样下载到页面上,所以这里面肯定有优化空间。比如图片懒加载
import 函数
math.js
文件
const add = (x, y) => {
return x + y;
}
export default add;
//import 命令
import { add } from './math';
console.log(add(16, 26));
//import函数
import("./math").then(math => {
console.log(math.add(16, 26));
});
动态
import()
语法目前只是一个 ECMAScript (JavaScript) 提案, 而不是正式的语法标准。预计在不远的将来就会被正式接受
import 函数示例
test.html
代码如下:
<div id="root">
页面无内容
</div>
<button id="btn">加载js</button>
<script>
document.getElementById('btn').onclick=function(){
import('./test.js').then(d=>{
d.test()
})
}
</script>
test.js
代码如下:
function test(){
document.getElementById('root')
root.innerHTML='页面变的有内容了'
}
export {test}
- 这时候打开web服务让页面以http的方式访问
- 我们在chrome的开发者工具下的Network可以看到只请求了一个页面。
-
但是当我们点击加载js,你会发现test.js会以动态的方式加入到代码中,同时执行了test函数,使页面的内容发生了变化。
-
在
React.lazy
和常用的三方包react-loadable
,都是使用了这个原理,然后配合webpack进行代码打包拆分达到异步加载,这样首屏渲染的速度将大大的提高。 -
由于
React.lazy
不支持服务端渲染,所以这时候react-loadable
就是不错的选择。
React.lazy 使用
-
下面示例代码使用create-react-app脚手架搭建:
-
OtherComponent.jsx
文件内容
// 普通的子组件
import React from 'react';
const OtherComponent = ()=>{
return(
<div>我已加载</div>
)
}
App.jsx
文件内容
import React, {Component} from 'react';
const OtherComponent = React.lazy(()=>import('./OtherComponent'));
class App extends Component{
constructor(props){
super(props);
this.state = {};
}
render(){
return (
<div>
<OtherComponent />
</div>
)
}
}
export default App;
index.js
文件内容
import ReactDOM from 'react-dom'
import App from './Lazy/App';
ReactDOM.render(
<App />,
document.getElementById('root')
)
- 运行结果:
这是最简单的React.lazy
,但是这样页面会报错。这个报错提示我们,在React使用了lazy
之后,会存在一个加载中的空档期,React不知道在这个空档期中该显示什么内容,所以需要我们指定。接下来就要使用到Suspense
。
Suspense
如果在
App
渲染完成后,包含Other
的模块还没有被加载完成,我们可以使用加载指示器为此组件做优雅降级。这里我们使用Suspense
组件来解决。
- 这里将
App
组件改一改
import React, {Suspense,Component} from 'react';
const OtherComponent = React.lazy(()=>import('./OtherComponent'));
class App extends Component{
constructor(props){
super(props);
this.state = {
visible:false
};
}
render(){
return (
<div>
<button onClick={() => {
this.setState({ visible: true })
}}>
加载OtherComponent组件
</button>
<Suspense fallback={<div>Loading...</div>}>
{
this.state.visible
?
<OtherComponent />
:
null
}
</Suspense>
</div>
)
}
}
export default App;
- 我们指定了空档期使用Loading展示在界面上面,等
OtherComponent
组件异步加载完毕,把OtherComponent
组件的内容替换掉Loading上。
- 可以从上面图片看出,当点击加载的时候,页面的head会插入``这段代码,发出一个get请求,页面开始显示loading,去请求
2.chunk.js
文件 - 请求结束返回内容就是
OtherComponent
组件的内容,只是文件名称和文件内容经过webpack处理过 - 注意:
Suspense
使用的时候,fallback
一定是存在且有内容的, 否则会报错。
标签:Lazy,OtherComponent,App,lazy,React,Suspense,import,加载 来源: https://blog.csdn.net/qq_45677671/article/details/116072355