文章目錄
-
- React.lazy 定義
-
- 代碼分割
- import 函數
- import 函數示例
- 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
,都是使用了這個原理,然後配合webpack進行代碼打包拆分達到異步加載,這樣首屏渲染的速度将大大的提高。react-loadable
- 由于
不支援服務端渲染,是以這時候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使用了React.lazy
之後,會存在一個加載中的空檔期,React不知道在這個空檔期中該顯示什麼内容,是以需要我們指定。接下來就要使用到lazy
。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
元件的内容替換掉Loading上。OtherComponent
- 可以從上面圖檔看出,當點選加載的時候,頁面的head會插入``這段代碼,發出一個get請求,頁面開始顯示loading,去請求
檔案2.chunk.js
- 請求結束傳回内容就是
元件的内容,隻是檔案名稱和檔案内容經過webpack處理過OtherComponent
- 注意:
使用的時候,Suspense
一定是存在且有内容的, 否則會報錯。fallback