3

我正在尝试分析一个网站的性能,我相当有信心在页面上加载 JavaScript 文件会减慢该网站的速度。

页面上多次包含相同的 JavaScript 文件,并且<script />标签分散在整个页面中,而不是包含在底部

正如我所怀疑的,在查看 FireBug 的“Net”选项卡时,大多数时间(不是全部)在加载 JavaScript 时,没有请求其他文件。浏览器等待 JavaScript 完成加载。

不过也有一些例外。在少数情况下会加载 JavaScript,但与此同时,其他资源似乎也被加载,例如其他 JavaScript 文件和图像。

我一直认为 JavaScript 会阻止页面上其他资源的加载。我的想法是否不正确,或者这种行为是否因浏览器或浏览器版本而异?

更新:
对于那些已经解释加载脚本如何阻止加载其他资源的人,我已经意识到这一点。我的问题是为什么脚本不会阻止其他资源的加载。Firebug 显示某些 JavaScript 文件不会阻止加载其他资源。我想知道为什么会发生这种情况。

4

10 回答 10

7

Javascript 资源请求确实是阻塞的,但是有一些方法可以解决这个问题(即:头部中的 DOM 注入脚本标签和 AJAX 请求),而我自己没有看到页面很可能是这里发生的事情。

包含同一个 JS 资源的多个副本是非常糟糕的,但不一定是致命的,并且是典型的大型站点,这些站点可能是从不同团队的工作中吸收的,或者只是简单的旧的糟糕的编码、规划或维护。

至于 yahoo 建议将脚本放在正文底部,这可以提高感知响应时间,并且可以在一定程度上提高实际加载时间(因为所有以前的资源都允许先异步),但它永远不会那么有效作为非阻塞请求(尽管它们具有很高的技术能力障碍)。

这里对非阻塞 JS 进行了相当不错的讨论。

于 2009-06-04T14:23:22.633 回答
2

我不完全确定 Firebug 是否能真实反映浏览器中正在发生的事情。资源加载的时机似乎很好,但我不确定它是否真实反映了正在发生的事情。我有更好的运气使用 HTTP 嗅探器/代理应用程序来监控来自浏览器的实际 HTTP 请求。我使用 Fiddler,但我知道还有其他工具。

简而言之,这很多是工具的问题,而不是实际加载资源的方式……至少值得排除。

于 2009-06-09T16:08:52.907 回答
1

我想您使用的是 Firefox 3.0.10 和 Firebug 1.3.3,因为它们是最新版本。

Firebug 1.4 beta 对 net 选项卡做了很多改进,但它需要 Firefox 3.5。如果您想在 Firefox 3.0 中对其进行测试,请使用之前的1.4 alpha 版本之一。但即使有了改进,我仍然很难理解结果。我希望 Firebug 开发人员能够更准确地记录下载的每个部分的含义。对我来说,为什么在连接后排队是没有意义的。

我的结论是不相信 Firebug 中的结果,最终使用了WebPageTest。来自美国在线真是太好了;-)

另外,在加载 javascript 的同时加载了哪些资源?尝试跟踪同时加载的资源,并查看它是否在 css/iframe/html-ajax 中引用。我猜测没有加载其他内容的原因是因为浏览器在看到脚本标记(没有延迟)时停止解析当前的 HTML。由于它不能继续解析 HTML,它没有更多的请求。

如果您可以提供指向您正在谈论的页面的链接。这将有助于每个人给出更准确的答案。

于 2009-06-09T22:48:11.997 回答
0

我相信内容已下载,但在 JavaScript 完成加载之前不会呈现。

从服务器的 POV 来看,这没什么大不了的,但对用户来说,它可以在速度上产生巨大的差异。

于 2009-06-04T12:40:24.167 回答
0

如果您考虑一下,标签必须先完成处理,然后才能继续呈现内容。如果标签使用 document.write 或其他一些非常愚蠢的东西怎么办?在脚本标签中的任何内容完成运行页面之前,无法确定它将显示什么。

于 2009-06-04T14:12:21.970 回答
0

浏览器通常会向单个域打开一定数量的连接。
因此,如果您从同一个域加载所有脚本,您通常会一个接一个地加载它们。
但是,如果这些脚本是从多个域加载的,它们将被并行加载。

于 2009-06-09T16:14:07.713 回答
0

浏览器在 JavaScript 下载期间阻塞的原因是浏览器怀疑脚本内部会创建 DOM 节点。

例如,脚本中可能有“dcoument.write()”调用。

一种向浏览器提示脚本不包含任何 DOM 生成的方法是使用“defer”属性。所以,

<script src="script.js" type="text/javascript" defer="defer"></script>

应该允许浏览器继续并行化请求。

参考:

http://www.w3.org/TR/REC-html40/interact/scripts.html#adef-defer

http://www.websiteoptimization.com/speed/tweak/defer/

于 2009-06-09T21:25:19.450 回答
0

正如其他人所说,该脚本可能正在通过 DOM 注入加载其他资源。

Script.aculo.us 实际上是通过这样做自己加载其子组件/脚本——<script>为它们注入其他标签到 DOM 中。

如果您想查看是否是这种情况,请使用 Firebug 的分析器并查看脚本在做什么。

于 2009-06-10T01:51:18.367 回答
0

就像其他人所说,一种非阻塞方式是<script>在页面中注入标签head

但是firefox也可以<script>并行执行loadeds:复制下面两行:

http://streetpc.free.fr/tmp/test.js
http://streetpc.free.fr/tmp/test2.js

然后转到此页面,粘贴输入文本区域,单击“JavaScript”,然后单击“加载脚本”(构建并添加一个<script>子元素head)。

在 FF 中尝试:您会看到“test2 ok”,移动对话框以查看“test ok”。在其他浏览器中,您应该会看到“test ok”(后面没有其他对话框),然后是“test2 ok”(Safari 4 除外,在测试前显示 tes2)。

于 2009-06-10T15:59:11.540 回答
0

Firefox 3 引入了连接并行功能以提高加载网页时的性能,我敢打赌这是您问题的根源;)

当您打开一个包含许多不同对象(如图像、Javascript 文件、框架、数据馈送等)的网页时,浏览器会尝试一次下载其中的几个以获得更好的性能。

这是关于它的 ZDNET 博客文章。

于 2009-06-16T04:48:54.580 回答