前端首屏優化方案之一
項目構建時會整體打包成一個bundle的JS文件,而有的代碼、模塊是加載時不需要的,需要分割出來單獨形成一個文件塊chunk(不會打包在main里),讓模塊懶加載(想加載時才加載),以減少應用體積、減少加載時的體積。
import
是關鍵字而非函數(類比typeof
,typeof '123
’ ortypeof('123')
)- 靜態導入:
import xxx from ''
,導入并加載時,導入的模塊會被編譯,不是按需編譯 - 動態導入:
import('')
根據條件或按需的模塊導入 - 動態導入應用場景:
- 模塊太大,使用可能性低
- 模塊的導入占用了大量系統內存
- 模塊需要異步獲取
- 導入模塊時需要動態構建路徑(路徑拼接)
import('./' + a + '.js')
- 模塊中的代碼需要程序觸發了某些條件才運行(比如點擊事件)
- 不能濫用動態導入:靜態導入有利于初始化依賴,動態導入不能用于靜態的程序分析和tree shaking
// module.js
export default class MyTest {construct() {console.log('構造器')}
}
<template><div><button class="test" @click="clickBtn">查看</button></div>
</template><script>
export default {name: "Plan",methods: {async clickBtn() {const res = await import("../libs/module.js");// import返回值是Promiseconsole.log("res", res);let myTest = res.default;new myTest();},},
};
</script>
// module.js
export const plus = (a, b) => {return a + b
}
<script>
export default {name: "Plan",methods: {async clickBtn() {import("../libs/module.js").then((res) => {const { plus } = res;console.log("plus 1 + 2 =", plus(1, 2)); // 3});},},
};
</script>
- 如果使用vite/腳手架(create react app)搭建的項目 → 可以直接使用
import()
- 如果是手動做webpack的配置,查看代碼分割指南
webpack動態導入 - 如果是用babel解析
import()
需要安裝依賴@babel/plugin-syntax-dynamic-import
(在動態注冊vue-router時,出現對import的語法錯誤,可能就是需要安裝該依賴)
react中使用
- 對于動態import的內容,不會直接打包進main.js里;如果是靜態導入的就會直接打包進一個js里
function Button() {// 函數里定義方法,要寫關鍵字聲明 和類不同const handleClick = async () => {// 若export default 接收到的就是default;否則接收到導出的const plus = await import('./index.js').then(res => res.default)// await + then 將res.default保存到resplus(1, 2)}return (<button onClick={handleClick}>getSum</button>)
}
ReactDOM.render(<Button />,document.getElementById('app')
)