脚本加载失败后如何重试?

7views

前言

让我们看一个例子,假设一个 html 文件中引入了如下 js 文件。

image.png

假如某些情况下导致某个 js 无法加载出来,我们要尽量避免影响用户。

因为目前大多都是单页面应用,某些js未加载肯定会对功能上有影响。

那如何解决?

多数情况需要重试,或者换个域名再重试。
因此解决办法主要围绕重试,得出两个关键点:

  1. 何时重试?
  2. 如何重试?

何时重试?

当然是js加载失败的时候重试。
我们可以这样写:
image.png

请注意这里两个细节:

  1. script 位置
  2. listener 中第三个参数为 true,表示捕获事件而非冒泡事件。

如何重试?

    <script>
      const domains = ["xxx1.com", "xxx2.com", "xxx3,com"];
      const retry = {};
      window.addEventListener(
        "error",
        (e) => {
          if (e instanceof ErrorEvent || e.target.tagName !== "SCRIPT") {
            return;
          }
          const url = new URL(e.target.src);
          const pathname = url.pathname;
          if (!(pathname in retry)) {
            retry[pathname] = 0;
          }
          const index = retry[pathname];
          if (index >= domains.length) {
            return;
          }
          const newDomain = domains[index];
          url.host = newDomain;
          document.write(`\<script src="${url.toString()}"><\/script>`);
          // const script = document.createElement("script");
          // script.src = url.toString();
          // e.target.parentElement.insertBefore(script, e.target);
          retry[pathname]++;
          e.target.remove();
        },
        true
      );
    </script>

Open inCodeSandBox
最终得到的效果:

image.png