下面是我的一些想法
你可以这么写
<script src="https://cdn.staticfile.org/vue/2.6.14/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.min.js"></script>
解决重复加载,可以这么写的(目前我是这么用的
<script src="https://cdn.staticfile.org/vue/2.6.14/vue.min.js"></script>
<script>
window.Vue ||
document.write(
'<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.min.js"><\/script>'
);
</script>
当然这还是写死的,同时两个CDN挂了还是出事(应该不会吧),或许还能这样
<script>
// const arr = "https://cdn.staticfile.org/vue/2.6.14/vue.min.js";
const arr = fetch('你的服务器'); // 伪代码, 动态获取CDN地址,可以通过后端配置
let node = document.createElement('script');
node.src = arr;
document.head.appendChild(node);
node = null;
</script>
在官方issue里看到一个有意思的仓库,瞄了一下还没使用过
https://github.com/EtherDream...
四五年前折腾过前端资源高可用,19年的时候写过一篇分享,其实蛮简单的,但是细节蛮多的,想做的深入一些,还需要做好监控,和运维团队合作。
言归正传,简单的场景使用 onerror
方式能够解决问题,但是一旦业务复杂,资源量比较大的时候,就需要针对方法进行封装,或者采用模块加载器动态加载、以及需要针对构建工具产物进行调整。
先来聊聊简单场景的解决方案:
<script>
function loadOthers(resource) {
var script = document.createElement('script');
script.src = resource.src.replace('demo-cdn.lab.io','demo.cdn2.io');
document.head.appendChild(script);
}
</script>
<script src="//demo-cdn.lab.io/assets/app.js" onerror="loadOthers(this)"></script>
为了进一步防患未然,我们一般不会只准备一套 CDN 候选,那处理方式还需要进一步调整
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script>
function loadResource(links, fnSuccess, fnError) {
var script = document.createElement('script');
script.onerror = function () {
document.head.removeChild(script);
fnError();
};
script.onload = fnSuccess
script.src = links.shift();
document.head.appendChild(script);
}
function autoSwitch(resourceList) {
var resource = resourceList.shift();
loadResource([resource], function (success) {
console.log('loaded');
}, function (err) {
console.log('load error')
autoSwitch(resourceList);
});
}
</script>
</head>
<body>
<script>
var resourceList = [
'http://demo-cdn.lab.io/assets/app.js',
'http://demo.cdn2.io/assets/app.js',
'assets/app.js',
];
autoSwitch(resourceList);
</script>
</body>
</html>
现代一些的应用,为了解决性能问题,我们一般会使用资源加载器,如何在这个场景下保证资源高可用呢?
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script src="assets/require-v2.3.6.min.js"></script>
<script>
function autoSwitch(resourceList) {
var resource = resourceList.shift();
requirejs([resource], function (success) {
console.log('loaded');
}, function (err) {
console.log('load error')
autoSwitch(resourceList);
});
}
</script>
</head>
<body>
<script>
var resourceList = [
'http://demo-cdn.lab.io/assets/app.js',
'http://demo.cdn2.io/assets/app.js',
'assets/app.js',
];
autoSwitch(resourceList);
</script>
</body>
</html>
讲到这里,资源自动加载几乎讲完了,但是实际上还存在一些额外的坑。
比如结合当前最流行的构建工具 webpack 使用,图片资源是一次性写死的,需要支持动态化等等。
最后,附上19年分享的内容: https://soulteary.com/2019/05...
8 回答4.7k 阅读✓ 已解决
6 回答3.4k 阅读✓ 已解决
5 回答2.8k 阅读✓ 已解决
6 回答2.3k 阅读
5 回答6.3k 阅读✓ 已解决
4 回答2.3k 阅读✓ 已解决
4 回答2.8k 阅读✓ 已解决