使用 DOMContentReady 被 Google 视为反模式

发布于 2024-08-17 00:35:46 字数 622 浏览 5 评论 0原文

一位 Google Closure 库团队成员断言正在等待对于 DOMContentReady 事件来说是一个不好的做法。

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

由于他们仍然没有提供更多详细信息,所以我想知道他们如何处理 操作中止 对话框。该对话框是我所知道的等待 DOMContentReady(或加载)事件的唯一关键原因。

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

A Google Closure library team member asserts that waiting for DOMContentReady event is a bad practice.

The short story is that we don't want
to wait for DOMContentReady (or worse
the load event) since it leads to bad
user experience. The UI is not
responsive until all the DOM has been
loaded from the network. So the
preferred way is to use inline scripts
as soon as possible.

Since they still don't provide more details on this, so I wonder how they deal with Operation Aborted dialog in IE. This dialog is the only critical reason I know to wait for DOMContentReady (or load) event.

  1. Do you know any other reason?
  2. How do you think they deal with that IE issue?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

浮生未歇 2024-08-24 00:35:46

首先稍微解释一下:内联 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 可以加快感知页面加载时间并改善用户体验。

缺点

  1. 在最坏的情况下,您会混合演示文稿和业务逻辑,在最好的情况下,您会在整个演示文稿中混合包含脚本,这两者都可能难以管理。在我看来,以及社区的大部分人都不能接受。
  2. 正如无眼睑指出的,如果脚本有问题有外部依赖项(例如库),那么必须首先加载这些依赖项,这将在解析和执行它们时锁定页面渲染。

我使用这种技术吗?不。我更喜欢在页面末尾加载所有脚本,就在结束 标记之前。几乎在每种情况下,对于效果和事件处理程序的感知和实际初始化性能来说,这都足够快。

其他人可以使用它吗?开发人员将做他们想要/需要的事情来完成工作并让他们的客户/老板/营销部门满意。权衡是存在的,只要您理解并管理它们,无论哪种方式都应该没问题。

A little explanation first: The point with inline JavaScript is to include it as soon as possible. However, that "possible" is dependent on the DOM nodes that that script requires being declared. For example, if you have some navigation menu that requires JavaScript, you would include the script immediately after the menu is defined in the 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>

As long as you only address DOM nodes that you know have been declared, you wont run into DOM unavailability problems. As for the IE issue, the developer must strategically include their script so that this doesn't happen. It's not really that big of a concern, nor is it difficult to address. The real problem with this is the "big picture", as described below.

Of course, everything has pros and cons.

Pros

  1. As soon as a DOM element is displayed to the user, whatever functionality that is added to it by JavaScript is almost immediately available as well (instead of waiting for the whole page to load).
  2. In some cases, Pro #1 can result in faster perceived page load times and an improved user experience.

Cons

  1. At worst, you're mixing presentation and business logic, at best you're mixing your script includes throughout your presentation, both of which can be difficult to manage. Neither are acceptable in my opinion as well as by a large portion of the community.
  2. As eyelidlessness pointed out, if the script's in question have external dependencies (a library for example), then those dependencies must be loaded first, which will lock page rendering while they are parsed and executed.

Do I use this technique? No. I prefer to load all script at the end of the page, just before the closing </body> tag. In almost every case, this is sufficiently fast for perceived and actual initialization performance of effects and event handlers.

Is it okay for other people to use it? Developers are going to do what they want/need to get the job done and to make their clients/bosses/marketing department happy. There are trade-offs, and as long as you understand and manage them, you should be okay either way.

硬不硬你别怂 2024-08-24 00:35:46

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

如果您的网站往往很繁忙,从长远来看,这会带来更好的性能。为脚本使用单独的文件的另一个优点是,您往往不会“重复自己”并尽可能声明可重用的函数。 DOMContentReady 不会导致糟糕的用户体验。至少它预先为用户提供了内容,而不是让用户等待 UI 加载,这最终可能会让用户感到厌烦。

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

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

如果你使用 YSlow 你会看到:

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

当且仅当代码更改如此频繁以至于将其放在单独的 js 文件中并不重要并且最终会产生与这些内联脚本相同的影响时,我才能保证内联脚本。不过,浏览器不会缓存这些脚本。浏览器缓存脚本的唯一方法是将其存储在带有 etag

然而,这绝不是 JQuery 与 Google 的终结。封闭有其自身的优点。然而,闭包库使得将所有脚本都放在外部文件中变得很困难(尽管这并不是不可能,只是让它变得困难)。您只是倾向于使用内联脚本。

The biggest problem with inline scripts is that it cannot be cached properly. If you have all your scripts stored away in one js file that is minified(using a compiler) then that file can be cached just once, for the entire site, by the browser.

That leads to better performance in the long run if your site tends to be busy. Another advantage of having a separate file for your scripts is that you tend to not "repeat yourself" and declare reusable functions as much as possible. DOMContentReady does not lead to bad user experience. Atleast it provides the user with the content before-hand rather than make the user wait for the UI to load which might end up becoming a big turn-off for the user.

Also using inline scripts does not ensure that the UI will be more responsive than that when used with DOMContentReady. Imagine a scenario where you are using inline scripts for making ajax calls. If you have one form to submit its fine. Have more than one form and you end up repeating your ajax calls.. hence repeating the same script everytime. In the end, it leads to the browser caching more javascript code than it would have if it was separated out in a js file loaded when the DOM is ready.

Another big disadvantage of having inline scripts is that you need to maintain two separate code bases: one for development and another for production. You must ensure that both code bases are kept in-sync. The development version contains non-minified version of your code and the production version contains the minified version. This is a big headache in the development cycle. You have to manually replace all your code snippets hidden away in those bulky html files with the minified version and also in the end hope that no code breaks! However with maintaing a separate file during development cycle, you just need to replace that file with the compiled minified version in the production codebase.

If you use YSlow you see that:

Using external JavaScript and CSS
files generally produces faster pages
because the files are cached by the
browser. JavaScript and CSS that are
inlined in HTML documents get
downloaded each time the HTML document
is requested. This reduces the number
of HTTP requests but increases the
HTML document size. On the other hand,
if the JavaScript and CSS are in
external files cached by the browser,
the HTML document size is reduced
without increasing the number of HTTP
requests.

I can vouch for inline scripts if and only if the code changes so often that having it in a separate js file is immaterial and would in the end have the same impact as that of these inline scripts. Still, these scripts are not cached by the browser. The only way the browser can cache scripts is if its stored away in an external js file with an etag.

However, this is not JQuery vs Google closure in any manner. Closure has its own advantages. However closure library makes it hard to have all your scripts in external files(though its not that its impossible, just makes it hard). You just tend to use inline scripts.

我喜欢麦丽素 2024-08-24 00:35:46

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

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

One reason to avoid inline scripts is that it requires you place any dependency libraries before them in the document, which will probably negate the performance gains of inline scripts. The best practice I'm familiar with is to place all scripts (in a single HTTP request!) at the very end of the document, just before </body>. This is because script-loading blocks the current request and all sub-requests until the script is completely loaded, parsed, and executed.

Short of a magic wand, we'll always have to make these trade-offs. Thankfully, the HTML document itself is increasingly going to become the least resource-intensive request made (unless you're doing silly stuff like huge data: URLs and huge inline SVG documents). To me, the trade-off of waiting for the end of the HTML document seems the most obvious choice.

太傻旳人生 2024-08-24 00:35:46

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

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

那么,也许关闭团队成员只是试图朝相反的方向前进,并阻止人们在页面加载时进行 DOM 操作?

I think this advise is not really helpful. DOMContentReady may only be bad practice because it currently is over-used (maybe because of jquery's easy-to-use ready event). Many people use it as the "startup" event for any javascript action. Though even jQuery's ready() event was only meant to be used as the startup point for DOM manipulations.

Inferential, DOM manipulations on page load lead to bad user experience!! Because they are not necessary, the server side could just have completely generated the initial page.

So, maybe the closure team members just try to steer in the opposite direction, and prevent people from doing DOM manipulations on page load at all?

最美不过初阳 2024-08-24 00:35:46

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

此外,页面结束之前的 JavaScript 会暂停 HTML 解析/DOM 评估,直到 JS 被解析和评估。在给出有关 JavaScript 的建议之前,Google 应该先看看他们的 Java。

If the time it takes to parse, load, and render layout (the point at which domready should fire) without consideration for image loads takes so long that it causes noticeable UI delay, you've probably got something really ugly building that page on the back-end, and that's your real problem.

Furthermore, JavaScript before the end of the page halts HTML parsing/DOM evaluating until the JS is parsed and evaluated. Google should look to their Java before giving advice on JavaScript.

执笔绘流年 2024-08-24 00:35:46

如果你需要自己处理你的HTML,谷歌的方法似乎很尴尬。他们使用编译的方法,可能会在其他问题上浪费他们的大脑周期,考虑到他们的应用程序的复杂用户界面,这是理智的。如果您追求要求更宽松的东西(阅读:几乎所有其他东西),也许不值得付出努力。

但遗憾的是 GWT 只谈论 Java。

If you need to dispose your HTML on your own, Googles approach seems very awkward. They use the compiled approach and can waste their brain-cycles on other issues, which is sane given the complex ui of their apps. If you head for something with more relaxed requirements (read: almost everything else), maybe it's not worth the effort.

It's a pity that GWT only is talking Java, though.

荒芜了季节 2024-08-24 00:35:46

这可能是因为 Google 并不关心你是否有 Javascript,他们所做的几乎所有事情都需要它。如果您在已经运行的网站之上使用 Javascript 作为补充,那么在 DOMContentReady 中加载脚本就可以了。重点是使用 Javascript 来增强用户体验,而不是在用户没有 JavaScript 的情况下将他们隔离开来。

That's probably because Google doesn't care if you don't have Javascript, they require it for just about everything they do. If you use Javascript as an addition on top of your already-functioning website then loading scripts in DOMContentReady is just fine. The point is to use Javascript to enhance the user's experience, not seclude them if they don't have it.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文