前端首屏优化方案之一
项目构建时会整体打包成一个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')
)