Skip to content

多个 widget 同时加载时卡顿

问题描述

在看板页面中,存在多个 widget,每个 widget 内部都会去请求 widget.js 文件,导致请求数过多,一次性会加载几十 MB 的内容,从而导致页面加载缓慢。

解决方案

实际上,这些 widget 大部分请求都是重复的,只是加载回来使用的组件不同而已。

因此,可以对 widget 的请求进行去重处理。对于相同 widget url 的请求,下一次的请求不会继续发送,而是使用上一次的请求结果。

ts
const codeCache: Record<string, Promise<string> | undefined> = {};

let code = '';
if (!!codeCache[url]) {
  code = (await codeCache[url]) as string;
} else {
  const promise = nativeWindow.fetch(url).then((res) => res.text());
  codeCache[url] = promise;
  code = (await promise.catch((e) => {
    console.error('Widget 加载失败', e);
    codeCache[url] = undefined;
  })) as string;
}

请求缓存后,会发现看板页面不再有重复的 widget 请求,加载速度有所提升。

但是这样又导致另外一个问题:由于多个 widget 采用同一个请求回来的结果,多个 widget 同时采用微前端的方式进行创建 window/document 然后执行 js 时,会导致加载页面卡顿。

这是因为多个 widget js 是以同步的形式执行,加起来比较耗时,从而导致页面卡顿。

解决方式是,将 widget js 的执行放到异步环境中去执行,比如 setTimeout/requestIdleCallback 等,让 js 的执行在合适的时机执行,避免影响用户的交互行为。