13

为了避免javascript阻塞网页渲染,我们不能把所有要加载/执行的JS文件/代码都放在结束</body>标记之前吗?

所有的 JS 文件和代码只有在所有页面都被渲染后才会被下载和执行,所以需要像这篇文章中建议的关于非阻塞技术来加载 JS 文件的技巧。他基本上建议使用如下代码:

document.getElementsByTagName("head")[0].appendChild(script);

为了在让网页被渲染的同时延迟脚本加载,从而导致网页的渲染速度快。

但是如果不使用这种类型的非阻塞技术(或其他类似的技术)</body> ,我们不是通过简单地将我们所有的 JS 文件(要加载/执行)放在结束标记之前来实现相同的非阻塞结果吗?

我更加惊讶,因为作者(在同一篇文章中)建议将他的代码放在结束</body>标记之前(参见文章的“脚本放置”部分),所以他基本上是在结束</body>标记之前加载脚本。那么,他的代码需要什么?

我很困惑,任何帮助表示赞赏,谢谢!


更新

仅供参考,谷歌分析正在使用类似的非阻塞技术来加载他们的跟踪代码:

<script type="text/javascript">
...
(function() 
{
   var ga = document.createElement('script');
   ga.type = 'text/javascript';
   ga.async = true;
   ga.src = 'your-script-name-here.js';
   var s = document.getElementsByTagName('script')[0];
   s.parentNode.insertBefore(ga, s); //why do they insert it before the 1st script instead of appending to body/head could be the hint for another question.
})();
</script>
</head>
4

3 回答 3

1

一般说不。即使在页面的所有内容之后加载脚本,加载和执行脚本也会阻塞页面。原因是脚本中可能存在写命令。

但是,如果您想要实现的只是加载页面内容的速度,那么在标签之前放置脚本标签的结果与</body>动态创建脚本标签的结果相同。最显着的区别是,当您以常见的静态方式加载脚本时,它们会被一一执行,换句话说,脚本文件不会并行执行(在旧浏览器中,下载脚本也是如此)。

于 2011-07-28T11:04:15.997 回答
1

如果你想要异步脚本。 如果 (HTML5) async 标记在您所在的浏览器中可用,请使用它。这就是 Google Analytics 在您发布的代码中所做的事情(特别是ga.async = true MDN Link 行,向下滚动以查看 async)。

但是,这可能会导致您的脚本在页面加载期间的任意时间加载 - 这可能是不可取的。在选择使用异步之前,有必要问自己以下问题。

不需要用户输入?然后使用 async 属性。

需要响应按钮或导航?然后你需要把它们放在页面的顶部(在 head 中)而不是使用 async 标记。

异步脚本以任意顺序运行,因此如果您的脚本依赖于(比如说)jQuery,并且 jQuery 加载到另一个标签中,那么您的脚本可能会在 jQuery 脚本之前运行 - 导致错误。


为什么人们不把东西放在身体标签的底部?如果脚本需要足够的时间来加载它会减慢/暂停网站的加载,那么该脚本很可能会在网站加载后暂停/挂起网站(预计在不同的浏览器上会有不同的行为) - 使您的网站出现无响应(单击一个按钮,没有任何反应)。在大多数情况下,这并不理想,这就是发明 async 属性的原因。


或者,如果您的脚本需要很长时间才能加载 - 您可能希望(在测试之后)缩小连接您的脚本,然后再将其发送到服务器。

我推荐使用require.js进行缩小和连接,它很容易运行和使用。

缩小可减少需要下载的数据量。

连接脚本减少了到服务器的“往返”次数(对于具有 200 毫秒 ping 的远距离服务器,5 个请求需要 1 秒)。

于 2015-04-17T01:27:39.180 回答
0

异步加载(尤其是分析代码片段之类的内容)的一个优点是,至少如果您将其放在顶部,它将尽快加载,而不会花费任何时间来呈现页面。因此,通过分析,在用户离开页面之前(可能在页面完全加载之前)实际跟踪用户的机会会更高。

并且使用 insertBefore 而不是 append,因为如果我没记错的话有一个错误(我认为在某些 IE 版本中,另请参阅下面的链接,在评论中有一些内容)。

对我来说这个链接: Async JS 是迄今为止我发现的最有用的。特别是因为它也带来了问题,即使使用谷歌的分析代码,onload 事件仍然会被阻止(至少在某些浏览器中)。如果您不希望这种情况发生,最好将该函数附加到 onload 事件。

对于将异步代码段放在底部,实际上在您发布的链接中进行了解释。他似乎只是为了确保在不使用 onload 事件的情况下完全加载 DOM。因此,这可能取决于您的脚本在做什么,如果您不操作 DOM,则没有理由将其添加到正文的底部。除此之外,我个人更喜欢将它添加到 onload-event 中。

于 2011-07-28T18:51:35.217 回答