如果外部资源未在 Firefox 上加载,我该如何取消阻止我的网页呈现?
How do I unblock the rendering of my web page if an external resource isn't loading on Firefox?
如果外部资源需要一段时间才能加载,我不想延迟我的页面呈现,所以我实现了这个逻辑......
<script type="text/javascript">
function importScript (sSrc, fOnload) {
var oScript = document.createElement("script");
oScript.type = "text\/javascript";
oScript.defer = true;
if (fOnload) { oScript.onload = fOnload; }
document.currentScript.parentNode.insertBefore(oScript, document.currentScript);
oScript.src = sSrc;
}
importScript(“//thirdpartysite.com/theirscript.js", function () { doStuff(); });
});
</script>
除 Mac Firefox(我使用的是 45.0.1 版)外,它工作得很好。在该浏览器上,页面不会呈现,直到加载此资源。有谁知道一种方法可以在不阻止页面呈现的情况下延迟加载资源,这种方法最好在 Chrome 和 Firefox 上都可以使用(所有浏览器都不错,但我没有时间测试它们)。
由于您已经有一个接受 URL 然后调用回调的系统,因此您可以轻松地在其中插入一个 setTimeout。像
function importScript(sSrc, fOnload) {
setTimeout(function () {
var oScript = document.createElement("script");
oScript.type = "text\/javascript";
oScript.defer = true;
if (fOnload) {
oScript.onload = fOnload;
}
document.currentScript.parentNode.insertBefore(oScript, document.currentScript);
oScript.src = sSrc;
}, 100);
}
当然,在 DOMReady 事件上执行导入。这几乎可以破解任何可能发生的渲染阻塞。
然而,当您添加依赖项时,系统会变得极其复杂,只有在组件完全加载后才需要执行的代码。这让我相信,更流畅的界面(如 Promise 系统)可以改进您的设计,并且还可能缓和超时甚至延迟执行,直到 DOMReady 已被触发到所有涉及的元素。
这里是一个没有类似 promise 语法的示例,但假设所有第三方脚本和依赖项仅从一个点开始:
var loadingChainStarted = false;
function importScript(sSrc, fOnload) {
if (document.readyState !== "complete") {
window.addEventListener("onload", function () {
importScript(sSrc, fOnload);
}, false);
return;
}
if (!loadingChainStarted) {
loadingChainStarted = true;
setTimeout(function () {
importScript(sSrc, fOnload);
}, 100);
return;
}
var oScript = document.createElement("script");
oScript.type = "text\/javascript";
oScript.defer = true;
if (fOnload) {
oScript.onload = fOnload;
}
document.currentScript.parentNode.insertBefore(oScript, document.currentScript);
oScript.src = sSrc;
}
这只会在 DOMReady 之后并且在第一次延迟 100 毫秒后执行脚本。链的其余部分将正常执行,因为 DOMReady 已被触发并且延迟已经过去。
如果外部资源需要一段时间才能加载,我不想延迟我的页面呈现,所以我实现了这个逻辑......
<script type="text/javascript">
function importScript (sSrc, fOnload) {
var oScript = document.createElement("script");
oScript.type = "text\/javascript";
oScript.defer = true;
if (fOnload) { oScript.onload = fOnload; }
document.currentScript.parentNode.insertBefore(oScript, document.currentScript);
oScript.src = sSrc;
}
importScript(“//thirdpartysite.com/theirscript.js", function () { doStuff(); });
});
</script>
除 Mac Firefox(我使用的是 45.0.1 版)外,它工作得很好。在该浏览器上,页面不会呈现,直到加载此资源。有谁知道一种方法可以在不阻止页面呈现的情况下延迟加载资源,这种方法最好在 Chrome 和 Firefox 上都可以使用(所有浏览器都不错,但我没有时间测试它们)。
由于您已经有一个接受 URL 然后调用回调的系统,因此您可以轻松地在其中插入一个 setTimeout。像
function importScript(sSrc, fOnload) {
setTimeout(function () {
var oScript = document.createElement("script");
oScript.type = "text\/javascript";
oScript.defer = true;
if (fOnload) {
oScript.onload = fOnload;
}
document.currentScript.parentNode.insertBefore(oScript, document.currentScript);
oScript.src = sSrc;
}, 100);
}
当然,在 DOMReady 事件上执行导入。这几乎可以破解任何可能发生的渲染阻塞。
然而,当您添加依赖项时,系统会变得极其复杂,只有在组件完全加载后才需要执行的代码。这让我相信,更流畅的界面(如 Promise 系统)可以改进您的设计,并且还可能缓和超时甚至延迟执行,直到 DOMReady 已被触发到所有涉及的元素。
这里是一个没有类似 promise 语法的示例,但假设所有第三方脚本和依赖项仅从一个点开始:
var loadingChainStarted = false;
function importScript(sSrc, fOnload) {
if (document.readyState !== "complete") {
window.addEventListener("onload", function () {
importScript(sSrc, fOnload);
}, false);
return;
}
if (!loadingChainStarted) {
loadingChainStarted = true;
setTimeout(function () {
importScript(sSrc, fOnload);
}, 100);
return;
}
var oScript = document.createElement("script");
oScript.type = "text\/javascript";
oScript.defer = true;
if (fOnload) {
oScript.onload = fOnload;
}
document.currentScript.parentNode.insertBefore(oScript, document.currentScript);
oScript.src = sSrc;
}
这只会在 DOMReady 之后并且在第一次延迟 100 毫秒后执行脚本。链的其余部分将正常执行,因为 DOMReady 已被触发并且延迟已经过去。