在您的情况下绝对不是,因为您使用的是框架。它的工作原理是这样的:
1) 当页面逐渐加载时,从外部文件请求脚本代码。 HTML 解析器必须在知道脚本请求之前解析脚本标签。此代码在调用时执行,但在 JavaScript 解释器可用时将其输入到 JavaScript 解释器中。
2) 当 HTML 代码被 HTML 解析器解析并遇到脚本标记时,直接驻留在页面中的脚本代码被输入解释器。函数内部的代码在调用时执行,但有一个例外。否则代码在解释后立即执行。一个例外是功能块后面紧跟“()”,表示立即调用。
3) 大多数执行的代码最初都是从使用“onload”事件进行的函数调用中执行的。当静态 DOM 从 HTML 解析器完全可用并且请求来自初始静态 HTML 的所有资产请求时,会发生 onload 事件。在旧版浏览器的某些边缘情况下,可能会发生冲突条件,从而在页面中创建竞争条件,从而阻止 onload 事件触发或在异常延迟之后。
4) 您正在使用 jQuery,因此在可用性速度方面您处于严重劣势。 jQuery 代码是 JavaScript 代码,因此它必须像任何其他 JavaScript 一样进入 JavaScript 解释器。在执行任何 jQuery 代码之前,必须遵守这篇文章中的所有先前要点。
5) 当我执行 A/B 测试时,我需要尽可能早、尽可能快地执行代码,以尽量减少页面上的闪烁,因此绝对不能选择框架。在这种情况下,我遵循以下步骤:
5a) 我在需要访问的 DOM 节点之后直接找到第一个 id 属性。
5b) 我写了一个函数来测试这个节点的可用性。如果节点可用,则其上方的区域可用,所以我知道我很可靠。考虑以下示例:
var test = function () {
var a = document.getElementById("first_node_lower_than_I_need");
if (a !== null && typeof a === "object") {
//my code here, because I know my target area is available
} else {
setTimeout(test, 100);
}
};
setTimeout(test, 100);
5c) 请注意,在上面的示例代码中,我使用 setTimout 延迟调用我的函数以给 DOM 一个战斗机会。如果函数提前执行没关系,因为我会延迟递归调用它,以便给 DOM 一些额外的加载时间。如果您将延迟设置为 50 毫秒或更低,那么您在 IE8 中的执行时间会增加,并且会因为对该函数的大量不必要调用而降低。我建议将延迟保持在 100ms 以实现理想的跨浏览器平衡,但如果您真的想在新浏览器中快速执行,则将第一个延迟设置为 50ms,这是函数之外的延迟,另一个保持为 100ms。
5d) 使用上述方法尽量减少对innerHTML 属性的使用,或者对目标页面非常熟悉以了解何时可以使用innerHTML。 innerHTML 的问题在于它会更改页面输出,而不会将这些更改报告回内存中已解析的 DOM,这通常是不相关的断开连接。但是,在这种情况下,它肯定是相关的,因为您注入的代码可以执行得有多快和多早。这是一个问题,因为稍后执行的其他代码,例如 onload 事件或 jQuery 的 ready 事件,将覆盖您的更改,或者将无法找到它们尊重的 DOM 负载并简单地一起放弃它们的执行。如果您的目标是 DOM 树中的一个非常高级的节点,这是一个特别重要的问题,因此为了您的安全,在选择节点以使用 innerHTML 或仅使用 DOM 方法时要非常具体。这有点复杂,因为您不能使用仅 DOM 方法的解决方案,因为您无法使用 nodeValue 方法跨浏览器更改文本节点,因为 IE7 不支持此功能。
如果您需要在完成 DOM 解析之前执行 JavaScript 代码,请不要使用 JavaScript 框架。使用普通的常规 JavaScript 代码编写并优化它。否则,您将始终出现闪烁,并且静态 HTML 下载量越大,闪烁的时间越长越明显。此外,jQuery 代码的执行速度往往比常规优化的 JavaScript 慢得多,因为它依赖于 CSS 之类的选择器。如果您注入的 jQuery 代码需要在非常大的静态 HTML 文档上执行大型任务,那么在 IE7 中完成执行而不会超时。