环顾四周,找不到讨论的这个具体问题。可以肯定的是,差异可以忽略不计,只是对您的想法感到好奇。
场景:在页面渲染之前不需要加载的所有 Javascript 都被放置在结束</body>
标记之前。通过在触发 DOM 加载/就绪事件时执行的头部中的一些 Javascript 代码来延迟加载这些是否有任何好处或坏处?假设这只涉及下载一个完整的 .js 文件,其中包含完整的功能,而不是在使用时根据需要延迟加载几个单独的文件。
希望这很清楚,谢谢。
环顾四周,找不到讨论的这个具体问题。可以肯定的是,差异可以忽略不计,只是对您的想法感到好奇。
场景:在页面渲染之前不需要加载的所有 Javascript 都被放置在结束</body>
标记之前。通过在触发 DOM 加载/就绪事件时执行的头部中的一些 Javascript 代码来延迟加载这些是否有任何好处或坏处?假设这只涉及下载一个完整的 .js 文件,其中包含完整的功能,而不是在使用时根据需要延迟加载几个单独的文件。
希望这很清楚,谢谢。
在我看来,有很大的不同。
当您在标签底部内联 JS 时<body>
,您会强制页面<script>
同步(现在必须发生)和顺序(连续)加载这些 s,因此您必须减慢页面速度等待这些 HTTP 调用完成并等待 JS 引擎解释您的脚本。如果您将大量 JS 堆叠在页面底部,您可能会在网络排队上浪费用户的时间(在旧浏览器中,每个主机一次只有 2 个连接),因为脚本可能相互依赖,所以它们必须按顺序下载。
如果您希望您的 DOM 更快地准备好(通常是大多数人等待执行任何事件处理和动画),您必须尽可能减少所需脚本的大小并使其并行化。
例如,YUI3 有一个小的依赖解析和下载脚本,您必须在页面中按顺序加载(参见 YUI3 的 seed.js)。之后,您浏览页面并收集依赖项并对他们的 CDN(或您自己的服务器)进行 1 次异步和管道调用,以获得一大堆 JS。返回 JS 球后,您的脚本将执行您提供的回调。这是一般模式:
<script src="seed.js"></script>
<script>
YUI().use('module', function(Y) {
// done when the ball returns and is interpretted
});
</script>
我不是特别喜欢将您的脚本放入 1 个大球中(因为如果 1 个依赖项发生更改,您必须重新下载并重新解释整个内容!),但我喜欢流水线(组合脚本)和基于事件的模型。
当您确实允许异步、基于事件的加载时,您会获得更好的性能,但可能不会感知到性能(尽管这可以抵消)。
例如,页面的某些部分可能不会加载一两秒钟,因此看起来不同(如果您使用 JS 来影响页面样式,我不建议这样做)或者直到您(或托管您网站的人)返回您的脚本。
此外,您必须做一些工作以确保您<script>
的 s 具有正确的依赖关系才能正确执行。例如,如果您没有 jQuery 或 Prototype,则无法成功调用:
<script>
$(function () {
/* do something */
});
</script>
或者
<script>
document.observe('dom:loaded', function {
/* do something */
});
</script>
因为解释器会说“变量 $ 未定义”之类的东西。即使您同时将两个 s 添加到 DOM 也会发生这种情况,<script>
因为我敢打赌 jQuery 或 Prototype 比您的应用程序的 JS 大(因此对数据的请求需要更长的时间)。无论哪种方式,如果没有某种类型的限制,您将把它留给机会。
所以,选择真的取决于你。如果您可以正确地分割您的依赖关系 - 即把您需要的东西放在前面,然后懒惰地加载其他东西,这将导致更快的整体时间,直到您准备好 DOM。
但是,如果您使用像 jQuery 这样的单体库,或者用户希望能够立即看到涉及 JS 动画或样式的内容,则内联可能更适合您。
就可用性而言,您绝对不应该对用户期望快速响应的任何内容执行此操作,例如让按钮除了其他功能之外还具有加载触发器的双重功能。
OTOH在用户滚动时通过不断加载页面来替换分页是一个非常好的主意。当加载触发器接近页面末尾时,我确实发现它会分散注意力,最好将其放在向下的 1/2 到 3/4 处。