JS 脚本加载失败如何重试

2024-07-24  本文已影响0人  Cherry丶小丸子
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script>
        const backupDomains = ["123.cn", "456.com", "789.net"];
        const nextDomain = {};
        window.addEventListener("error", e => {
            console.log(e);
            if(e instanceof ErrorEvent || e.target.tagName !== "SCRIPT") {
                return;
            }
            const url = new URL(e.target.src);
            const pathname = url.pathname;
            if(!nextDomain[pathname]) {
                nextDomain[pathname] = 0;
            }
            const index = nextDomain[pathname];
            if(index >= backupDomains.length) {
                return;
            }
            const domain = backupDomains[index];
            url.hostname = domain;
            const newUrl = url.toString();
            document.write(`\<script src="${newUrl}">\<\/script>`);
            nextDomain[pathname]++;
        }, true);
    </script>
</head>
一、script标签特性

① script 标签默认是同步加载的。当 HTML 页面在加载的过程中,遇到了一个 script 标签,就会中断 HTML 页面的加载,然后根据对应的 src 地址向服务器发起请求,当对应的 javascript 脚本加载完成后,HTML 页面仍然不能加载,还必须等加载的 javascript 脚本执行完成后,HTML 页面才能继续往下加载。

② 当遇到 script 标签的时候会立即渲染一次。当 HTML 页面加载的过程中,遇到了一个 script 标签,如果之前已经加载了部分 HTML 内容,那么会先将之前加载的 HTML 内容渲染出来,然后再去加载对应的 javascript 脚本。

二、script 标签优化

script 标签默认是同步加载的,但是其提供了一些属性可以变成异步加载,如: async、defer、type=“module”

① async: 异步加载对应的 javascript 脚本,不阻塞 HTML 页面的渲染,当对应的 javascript 加载完成后,如果此时 HTML 页面还未加载完成,那么会阻塞页面的渲染,等 javascript 执行完成后再继续 HTML 页面的加载。

② defer: 异步加载对应的 javascript 脚本,不阻塞 HTML 页面的渲染,当对应的 javascript 加载完成后,如果此时 HTML 页面还未加载完成,那么不会阻塞页面的渲染,等 HTML 页面加载完成后再接着执行加载完成的 javascript 脚本。

③ type=“module”: 也是能起到异步加载的效果,效果同 defer,不过其可以配合 async 属性让 javascript 加载完成后立即执行。

上一篇下一篇

猜你喜欢

热点阅读