Chrome浏览器内部揭秘(四)

571 阅读2分钟

本文转自 Inside look at modern web browser (part 4) - Chrome Developers,原作者为 Mariko Kosaka

阅读后觉得内容非常不错,为了加深记忆和理解,决定翻译一些重要的部分。(虽然掘金里已经有好几篇本文翻译了)

从浏览器视角来看输入事件

当用户点击屏幕时,浏览器进程首先接收到点击事件,它把事件类型和坐标传递给渲染进程,由渲染进程来找到 event target 并触发绑定的事件。

合成器收到输入事件

如果页面上没有监听的事件,合成器线程可以独立主线程之外生成合成器帧,但如果有监听的事件呢?

理解非快速滚动区域

合成器线程在生成合成器帧的时候,会在将有监听事件的区域进行标记,这些区域被称为“非快速滚动区域”,如果输入事件是在这些区域的话,合成器线程就会将事件传递给主线程,由主线程执行 JS,否则合成器线程就会合成一个新的合成器帧,而不会等待主线程响应。

绑定事件的注意事项

Web 开发者喜欢通过事件委托来由 body 监听事件,这样就可以由一个元素来监听其子元素的所有事件。当时这样也就导致真个页面都成为非快速滚动区域,这样的话每次有输入事件发生,合成器线程都需要去和主线程通信并等待主线程返回,最终导致合成器带来的顺畅的滚动体验消失。

为了避免这种情况,你可以通过在事件监听中加入 passive:true 选项,来告诉浏览器浏览器可以不用等待主线程的返回,直接合成新的帧。

document.body.addEventListener('touchstart', event => {if (event.target === area) {event.preventDefault()}}, {passive: true});

获取事件对象

主线程或者和合成器线程的输入事件后,首先会运行 hit test 来获取事件对象。 Hit test 利用渲染过程中构建的绘制记录数据来找到触发时间的元素。

结尾

通过这个系列的文章,我们了解了浏览器的内部工作。如果你从没有想过为什么 DevTools 推荐你在事件处理中加入 {passive:true},或者你不明白为什么要在