使用 import 语句,定义按需加载的起始模块
对于这个需求,ECMA Script 标准有一个提案,专门用于动态加载模块,语法是 import(someModule)。
注意,这里的 import 和我们一般用于引入模块的静态声明方式不同,比如 import something from ‘somemodule’ 。
但这里的 import 是作为一个函数动态运行的,这个 import() 函数会返回一个 Promise。
这样,在模块加载成功后,就可以在 Promise 的 then 回调函数中去使用这个模块了。
虽然这只是一个提案,并没有成为标准,但是 Webpack 等打包工具利用了这样的语法去定义代码的分包。
也就是说,Webpack 实现了这样的语法。
1 | function ProfilePage() { |
import() 这个语句完全是由 Webpack 进行处理的。
按需加载的实现原理:Webpack 利用了动态 import 语句,自动实现了整个应用的拆包。
而在实际开发中,其实并不需要关心 Webpack 是如何做到的,
而只需要考虑:该在哪个位置使用 import 语句去定义动态加载的拆分点。
总体需要采用的策略是:按业务模块为目标去做隔离,尽量在每个模块的起始页面去定义这个拆分点。
react-loadable,专门用于 React 组件的按需加载。
1 | import Loadable from "react-loadable"; |
可以看到 Loadable 这个高阶组件主要就是两个 API。
loader:用于传入一个加载器回调,在组件渲染到页面时被执行。
在这个回调函数中,我们只需要直接使用 import 语句去加载需要的模块就可以了。
loading:表示用于显示加载状态的组件。在模块加载完成之前,加载器就会渲染这个组件。
如果模块加载失败,那么 react-loadable 会将 errors 属性传递给 Loading 组件,方便你根据错误状态来显示不同的信息给用户。
按需加载可以说是减少首屏加载时间最为有效的手段,它可以让用户在打开应用时,无需加载所有代码就能开始使用,从而提升用户体验。
使用 service worker 缓存前端资源
和浏览器自动的资源缓存机制相比,Service Worker 加上 Cache Storage 这个缓存机制,具有更高的准确性和可靠性。
因为它可以确保两点:
缓存永远不过期。你只要下载过一次,就永远不需要再重新下载,除非主动删除。
永远不会访问过期的资源。换句话说,如果发布了一个新版本,那么你可以通过版本化的一些机制,来确保用户访问到的一定是最新的资源。