控制整个应用的大小,提高加载性能是前端开发需要的挑战。
提高首屏加载速度:
- 对应用分包
- 采用高效的缓存策略
实现按需加载
使用 import 语句,定义按需加载的起始模块
本质在于,需要有动态加载模块的能力——import(ECMA Script 标准的一个提案)。
这里的 import 作为一个函数动态运行,会返回一个 Promise,在模块加载成功后可以在 Promise 的 then 回调函数中去使用这个模块。
function Page() {
const [RealPage, setRealPage] = useState(null);
import("./RealPage").then((comp) => {
setRealPage(comp);
});
if (!RealPage) return "Loading...";
return <RealPage />;
}
import 语句完全由 Webpack 进行处理的。Webpack 会把./RealPage’这个模块为起点的所有依赖模块单独打成一个包。
策略:按业务模块为目标去做隔离,精良在每个模块的起始页去定义这个拆分点。
使用 react-loadble 实现组件的异步加载
import Loadable from "react-loadable";
export default Loadable({
loader: () => import("./HelloLazyLoad"),
loading({ error }) {
return error ? "Failed" : "Loading";
},
});
- loader:用于传入一个加载器回调,在组件渲染到页面时被执行
- loading:用于显示加载状态的组件
使用 service worker 缓存前端资源
对于加载性能的优化除了按需加载之外,还有就是前端资源的缓存。合理的缓存策略可以保证同样的前端资源永远只下载一次。
service worker 通常用于开发离线的 web 应用。它还提供了拦截前端请求的能力使得它可以结合 localStoage 成为一个独立的缓存方案(可以看作一种前端的资源请求代理)。
service worker 加上 cache storage(存储静态资源在浏览器端)具有更高的准确性和可靠性。
- 缓存永远不过期
- 永远不会访问过期的资源
注册 Service Worker
if ("serviceWorker" in navigator) {
navigator.serviceWorker.register("sw.js").then(() => {
console.log("registered.");
});
}
其中 sw.js 就是 Service Worker 脚本的代码路径。
在 Service Worker 安装后初始化缓存机制
在 Service Worker 的实现代码被下载和执行后,就会触发安装完成的事件,可以在 sw.js 内监听这个事件,从而初始化自己的缓存机制。
// 在sw.js中监听安装完成事件
self.addeventListener("install", (e) => {
const cachePromise = caches.open("app_cache");
e.waitUntil(cachePromise);
});
Cache Storage 是浏览器提供的一种缓存机制。
拦截请求
可以通过监听 fetch 事件来处理所有的请求。
self.addeventListener("fetch", (e) => {});
思考题
除了按需加载和 Service Worker,还想到哪些提升应用加载性能的方法?