脚本加载失败重试机制

概述

前端脚本资源加载的时候可能会出错,特别是cdn资源,因此我们可以写一个js资源加载失败的重试机制,根据备用域名依次加载资源,最大程度提高用户体验。

效果

问题点

  1. 什么时间重试?

    在script加载事件出错的时候进行事件拦截处理

  2. 如何重试?

通过全局Err事件监听,然后根据script加载出错处理

  1. script插入方式?

通过document.write(会阻塞页面保证脚本顺序)插入最新的脚本请求到页面,注意:如果js加载过程中,严格区分前后加载顺序就不能动态创建script的形式重试

实现

html 复制代码
<!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 backupsDomain = [
            "https://cdn.bootcdn.newt",
            "https://cdnjs.cloudflare.com",
            "https://cdn.bootcdn.net",
        ]


        const nextDomain = {}

        window.addEventListener("error", (e) => {
            if (e.target.tagName === "SCRIPT") {
                const target = new URL(e.target.src)
                const pathName = target.pathname
                if (nextDomain[pathName] >= backupsDomain.length) {
                    console.log("所有域名均不可用")
                    return
                }
                if (!nextDomain[pathName]) {
                    nextDomain[pathName] = 0
                }
                const index = nextDomain[pathName]
                const domain = backupsDomain[index]
                const newUrl = new URL(domain + target.pathname + target.search);

                console.log("target", newUrl)
                // 方式1(不区分顺序可以用这种)
                const script = document.createElement("script")
                script.src = newUrl.toString()
                // e.target.parentElement.insertBefore(script, e.target)
                // 方式2(严格按照页面js脚本引入顺序加载)
                document.write(`\<script src="${newUrl.toString()}"><\/script>`)
                e.target.remove()
                nextDomain[pathName]++

            }
        }, true)
    </script>
</head>

<body>
    <script src="https://cdn.bootcdn.net1/ajax/libs/vue/3.5.20/vue.global.js"></script>
    <script src="https://cdn.bootcdn.net/ajax/libs/socket.io/4.8.1/socket.io.min.js"></script>

    <div id="app"></div>
    <script>
        console.log("结束", Vue)

        Vue.createApp({
            data() {
                return {
                    message: 'Hello Vue!',
                    count: 0
                }

            },
            methods: {
                test() {
                    console.log("test")
                    this.count++
                    this.message = 'Button clicked ' + this.count + ' times.'
                }
            },
            template: `<div @click="test">{{ message }}</div>`
        }).mount('#app')
    </script>

</body>

</html>

注意

document.write() 是 JavaScript 中用于向文档写入内容的方法,支持插入文本、HTML 标签或 JavaScript 代码。以下是其核心要点及使用场景:

核心功能

  • 写入内容‌:接受字符串参数(如文本、HTML 或 JavaScript 代码),并将其插入到文档流中。 ‌
  • 应用场景‌:动态生成页面内容、注入脚本、测试调试等。 ‌

注意事项

  • 页面加载期间使用‌:仅在页面加载过程中有效,若在文档加载完成后使用会导致整个页面内容被清空。 ‌
  • 阻塞解析‌:同步操作会阻塞页面解析,不建议用于异步加载或页面加载完成后。 ‌
  • 内容覆盖‌:会覆盖原有内容,需谨慎使用以避免意外覆盖重要信息。 ‌
相关推荐
@PHARAOH3 小时前
WHAT - GitLens vs Fork
前端
yqcoder3 小时前
前端性能优化:如何减少重绘与重排?
前端·性能优化
洋子4 小时前
Yank Note 系列 13 - 让 AI Agent 进入笔记工作流
前端·人工智能
wenzhangli76 小时前
Ooder A2UI 核心架构深度解析:WEB 拦截层的设计与实现
前端·架构
前端百草阁7 小时前
【前端性能优化全链路指南】从开发编写到构建运行的多维度实践
前端·性能优化
神探小白牙7 小时前
eCharts 多系列柱状图增加背景图
javascript·ecmascript·echarts
女生也可以敲代码7 小时前
AI时代下的50道前端开发面试题:从基础到大模型应用
前端·面试
ZhengEnCi7 小时前
M5-markconv自定义CSS样式指南 📝
前端·css·python
IT_陈寒8 小时前
SpringBoot自动配置的坑差点让我加班到天亮
前端·人工智能·后端
xingpanvip8 小时前
星盘接口开发文档:星相日历接口指南
android·开发语言·前端·css·php·lua