使用DOMContentReady被Google视为反模式

时间:2010-01-07 22:04:32

标签: javascript internet-explorer google-closure-library document-ready domready

等待DOMContentReady事件的Google Closure库团队成员asserts是一种不好的做法。

  

短篇小说是我们不想要的   等待DOMContentReady(或者更糟   负载事件)因为它导致坏   用户体验。用户界面不是   响应直到所有DOM都已存在   从网络加载。所以   首选方法是使用内联脚本   尽快。

由于他们仍然没有提供更多详细信息,所以我想知道他们如何处理IE中的Operation Aborted对话框。这个对话框是我知道等待DOMContentReady(或load)事件的唯一重要原因。

  1. 你知道其他任何原因吗?
  2. 您认为他们如何处理IE问题?

7 个答案:

答案 0 :(得分:29)

首先解释一下:内联JavaScript的要点是尽快包含它。但是,“可能”取决于该脚本需要声明的DOM节点。例如,如果您有一些需要JavaScript的导航菜单,则在HTML中定义菜单后立即包含该脚本。

<ul id="some-nav-menu">
    <li>...</li>
    <li>...</li>
    <li>...</li>
</ul>
<script type="text/javascript">
    // Initialize menu behaviors and events
    magicMenuOfWonder( document.getElementById("some-nav-menu") );
</script>

只要您只解决已知的DOM节点,就不会遇到DOM不可用问题。至于IE问题,开发人员必须策略性地包含他们的脚本,以便不会发生这种情况。这不是一个很大的问题,也不是很难解决。这个问题的真正问题在于“大局”,如下所述。

当然,一切都有利有弊。

赞成

  1. 只要向用户显示DOM元素,JavaScript中添加的任何功能几乎都可以立即使用(而不是等待整个页面加载)。
  2. 在某些情况下,Pro#1可以加快感知页面加载时间并改善用户体验。
  3. 缺点

    1. 在最糟糕的情况下,您混合了演示文稿和业务逻辑,充其量只是在整个演示文稿中混合了script包含,这两者都很难管理。在我看来,以及社区的很大一部分都不能接受。
    2. 正如eyelidlessness指出的那样,如果有问题的脚本有外部依赖项(例如一个库),那么必须首先加载这些依赖项,这将在解析和执行它们时锁定页面呈现。
    3. 我是否使用此技术?不。我更喜欢在结束</body>标记之前加载页面末尾的所有脚本。几乎在每种情况下,这对于效果和事件处理程序的感知和实际初始化性能来说足够快。

      其他人可以使用它吗?开发人员会做他们想要/需要完成工作的事情,并让他们的客户/老板/营销部门感到高兴。有一些权衡,只要你理解和管理它们,你应该没办法。

答案 1 :(得分:1)

内联脚本的最大问题是它无法正确缓存。如果您将所有脚本存储在一个缩小的js文件中(使用编译器),则该文件只能由浏览器缓存一次,对于整个站点。

如果您的网站容易繁忙,那么从长远来看会带来更好的性能。为脚本提供单独文件的另一个好处是,您不会“重复自己”并尽可能多地声明可重用的函数。 DOMContentReady不会导致糟糕的用户体验。 Atleast它为用户提供了事先的内容,而不是让用户等待加载UI,这可能最终成为用户的一大转折。

同样使用内联脚本并不能确保UI与DOMContentReady一起使用时的响应速度更快。想象一下您使用内联脚本进行ajax调用的场景。如果您有一份表格提交罚款。有多个表单,你最终重复你的ajax调用..因此每次都重复相同的脚本。最后,它导致浏览器缓存更多的javascript代码,如果它在DOM准备好时加载的js文件中分离出来的话。

使用内联脚本的另一个主要缺点是您需要维护两个单独的代码库:一个用于开发,另一个用于生产。您必须确保两个代码库保持同步。开发版本包含代码的非缩小版本,生产版本包含缩小版本。这是开发周期中的一大难题。您必须手动替换隐藏在那些笨重的html文件中的所有代码片段与缩小版本,并且最终希望没有代码中断!但是,在开发周期中维护一个单独的文件时,您只需要将该文件替换为生产代码库中已编译的缩小版本。

如果您使用YSlow,您会看到:

  

使用外部JavaScript和CSS   文件通常会生成更快的页面   因为文件是由缓存的   浏览器。 JavaScript和CSS是   内联HTML文档得到   每次下载HTML文档   请求。这减少了数量   HTTP请求但增加了   HTML文档大小。另一方面,   如果JavaScript和CSS在   浏览器缓存的外部文件,   HTML文档大小减少了   不增加HTTP的数量   请求。

当且仅当代码经常变化以至于在单独的js文件中使用它并不是非常重要且最终会产生与这些内联脚本相同的影响时,我可以保证内联脚本。但是,这些脚本不会被浏览器缓存。浏览器缓存脚本的唯一方法是将其存储在带有etag的外部js文件中。

然而,这不是JQuery vs Google以任何方式关闭。闭合有其自身的优点。然而,关闭库使得很难将所有脚本都放在外部文件中(尽管它不是不可能的,只是让它变得困难)。您只是倾向于使用内联脚本。

答案 2 :(得分:1)

如果在不考虑图像加载的情况下解析,加载和渲染布局(domready应该触发的点)所花费的时间花了很长时间才会导致显着的UI延迟,你可能会得到一些非常难看的构建在后端的页面,这是你真正的问题。

此外,在页面结束之前的JavaScript会停止HTML解析/ DOM评估,直到解析和评估JS。在提供有关JavaScript的建议之前,谷歌应该关注他们的Java。

答案 3 :(得分:0)

避免内联脚本的一个原因是它要求您在文档中放置任何依赖库,这可能会抵消内联脚本的性能提升。我熟悉的最佳实践是将所有脚本(在单个HTTP请求中!)放在文档的最末端,就在</body>之前。这是因为脚本加载会阻止当前请求和所有子请求,直到脚本完全加载,解析和执行。

如果没有魔杖,我们将不得不做出这些权衡。值得庆幸的是,HTML文档本身越来越成为资源密集度最低的请求(除非您正在做一些愚蠢的事情,如巨大的data: URL和巨大的内联SVG文档)。对我而言,等待HTML文档结束的权衡似乎是最明显的选择。

答案 4 :(得分:0)

我认为这个建议并没有多大帮助。 DOMContentReady可能只是不好的做法,因为它目前被过度使用(可能是因为jquery易于使用的就绪事件)。许多人将其用作任何 javascript操作的“启动”事件。虽然即使是jQuery的ready()事件也只是用作DOM操作的启动点。

推理,对页面加载的DOM操作会导致糟糕的用户体验!!因为它们不是必需的,服务器端可能只是完全生成了初始页面。

所以,关闭团队成员可能只是试图向相反方向转向,并阻止人们对页面加载进行DOM操作?

答案 5 :(得分:0)

如果您需要自己处理HTML,Googles方法似乎非常尴尬。他们使用编译的方法,并且可以在其他问题上浪费他们的脑力循环,考虑到他们的应用程序的复杂ui,这是理智的。如果你寻求更宽松的要求(阅读:几乎所有其他的东西),也许这不值得努力。

遗憾的是GWT只是在谈论Java。

答案 6 :(得分:-1)

这可能是因为谷歌并不关心你是否没有Javascript,他们只需要他们所做的一切。如果您在已经运行的网站上使用Javascript作为补充,那么在DOMContentReady中加载脚本就可以了。重点是使用Javascript来增强用户的体验,如果他们没有,则不要将其排除在外。