innerHTML 是异步的吗? [英] Is innerHTML asynchronous?

查看:45
本文介绍了innerHTML 是异步的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望我不会自欺欺人,但我正在努力了解这两行代码中发生的事情:

document.body.innerHTML = 'something';alert('别的东西');

我观察到的是,警报在 HTML 更新之前显示(或者可能已经更新,但页面尚未刷新/重新绘制/无论如何)

查看这个

如您所见,所有 JavaScript 都首先发生.然后页面被样式化、布局、绘制和合成——渲染".并非所有这些管道都会在每一帧执行.这取决于更改了哪些页面元素(如果有),以及它们需要如何重新呈现.

注意:alert() 也是同步的,并在 JavaScript 步骤期间执行,这就是为什么在您看到网页更改之前会出现警报对话框的原因.

您现在可能会问等等,在管道中的那个‘JavaScript’步骤中到底运行了什么?我的所有代码每秒运行 60 次吗?"答案是否定的,这要追溯到 JS 事件循环的工作原理.JS 代码只有在堆栈中时才会运行 - 来自事件侦听器、超时等.请参阅之前的视频(真的).

https://developers.google.com/web/fundamentals/performance/rendering/

I hope I won't make a fool of myself but I'm trying to understand what is happening in those two lines of code:

document.body.innerHTML = 'something';
alert('something else');

What I am observing is that alert shows before HTML has been updated (or maybe it has but the page hasn't been refreshed/repainted/whatever)

Checkout this codepen to see what I mean.

Please note that even putting alert in setTimeout(..., 0) does not help. Looks like it takes more event loops for innerHTML to actually update page.

EDIT:

I forgot to mention I am using Chrome and did not check other browsers. Looks like it's only visible in Chrome. Nevertheless I am still interested why is that happening.

解决方案

Setting innerHTML is synchronous, as are most changes you can make to the DOM. However, rendering the webpage is a different story.

(Remember, DOM stands for "Document Object Model". It's just a "model", a representation of data. What the user sees on their screen is a picture of how that model should look. So, changing the model doesn't instantaneously change the picture - it take some time to update.)

Running JavaScript and rendering the webpage actually happen separately. To put it simplistically, first all of the JavaScript on the page runs (from the event loop - check out this excellent video for more detail) and then after that the browser renders any changes to the webpage for the user to see. This is why "blocking" is such a big deal - running computationally intensive code prevents the browser from getting past the "run JS" step and into the "render the page" step, causing the page to freeze or stutter.

Chrome's pipeline looks like this:

As you can see, all of the JavaScript happens first. Then the page gets styled, laid out, painted, and composited - the "render". Not all of this pipeline will execute every frame. It depends on what page elements changed, if any, and how they need to be rerendered.

Note: alert() is also synchronous and executes during the JavaScript step, which is why the alert dialog appears before you see changes to the webpage.

You might now ask "Hold on, what exactly gets run in that 'JavaScript' step in the pipeline? Does all my code run 60 times per second?" The answer is "no", and it goes back to how the JS event loop works. JS code only runs if it's in the stack - from things like event listeners, timeouts, whatever. See previous video (really).

https://developers.google.com/web/fundamentals/performance/rendering/

这篇关于innerHTML 是异步的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆