简体   繁体   English

浏览器中的引擎 - 它们如何交互?

[英]Engines in Browser - How do they interact?

I've been trying to learn more under the hood when it comes to Web Development, specifically JavaScript, and how the different engines interact with the JavaScript engine. 我一直在努力学习更多关于Web开发的知识,特别是JavaScript,以及不同的引擎如何与JavaScript引擎交互。 For example, I know that the Rendering Engine is interacting, HTTP Requests, etc. I was just wondering, when the JavaScript Engine has to send data to another engine, such as the rendering engine, how much more computing has the JavaScript engine done by the time that data gets there? 例如,我知道渲染引擎正在进行交互,HTTP请求等等。我只是想知道,当JavaScript引擎必须将数据发送到另一个引擎(例如渲染引擎)时,JavaScript引擎完成了多少计算。数据到达的时间?

The Web is a standardised platform running on the application layer of the Internet Protocol Suite . Web是在Internet协议套件的应用层上运行的标准化平台。

It is a hypermedia system consisting of a protocol (HTTP), a markup language, a styling language (CSS) and a browser API (the Web API). 它是一个超媒体系统,由协议(HTTP),标记语言,样式语言(CSS)和浏览器API(Web API)组成。

The Web was a development upon earlier hypermedia systems like HyperCard and uses a similar single-threaded, event-oriented rendering process. Web是早期超媒体系统(如HyperCard)的开发,它使用类似的单线程,面向事件的渲染过程。

The crux of your question is "how do the various parts of the browser interact to render a web page?" 您的问题的关键是“浏览器的各个部分如何交互以呈现网页?”

The answer is a mixture of vendor-specific implementation and standardised behaviour defined by the standards bodies W3C and WHATWG. 答案是由供应商特定实施和标准机构W3C和WHATWG定义的标准化行为的混合。

The rendering process at a high level might be something like this: 高级渲染过程可能是这样的:

The inbound message is exposed to the browser application by the operating system's networking substem (which in turn received the stream over the TCP IPS transport-layer) as a stream of bytes encoded using UTF-8. 入站消息由操作系统的网络子系统(通过TCP IPS传输层接收流)作为使用UTF-8编码的字节流向浏览器应用程序公开。

Thus the networking subsystem of the browser receives an inbound UTF-8 encoded octet stream. 因此,浏览器的网络子系统接收入站UTF-8编码的八位字节流。

The browser will likely process the inbound stream of bytes on a thread or process other than that coordinating the rendering of the UI to avoid locking up the browser. 浏览器可能会处理除协调UI呈现之外的线程或进程上的入站字节流,以避免锁定浏览器。

The browser understands the text-based HTTP protocol Tim Berners-Lee invented in 1989, and interprets the inbound bytes as an HTTP message. 浏览器理解Tim Berners-Lee在1989年发明的基于文本的HTTP协议 ,并将入站字节解释为HTTP消息。

The body of the message will correspond to the markup of the page. 消息正文将对应于页面的标记。 Once the page markup has been received it will be handed to a thread for rendering. 一旦收到页面标记,它将被交给线程进行渲染。

Starting at the top of the markup the browser rendering process will begin parsing according to an algorithm defined by the W3C/ WHATWG . 从标记的顶部开始,浏览器呈现过程将根据W3C / WHATWG定义的算法开始解析。

When JavaScript is encountered, it will typically be run immediately, but there are complicated rules about exactly what happens when. 当遇到JavaScript时,它通常会立即运行,但是关于确切发生什么时会有复杂的规则。

When references to resources (eg. images, scripts, stylesheets) are encountered, requests for their download will be made. 当遇到对资源(例如图像,脚本,样式表)的引用时,将进行下载请求。 Some will block the rendering process, some will not. 有些会阻止渲染过程,有些则不会。

When a piece of JavaScript is encountered, its evaluation will usually block the user interface. 遇到一段JavaScript时,其评估通常会阻止用户界面。 This is because the Web was designed to have a single thread of execution controlling the rendering of a page, and JavaScript is part of that process. 这是因为Web被设计为具有控制页面呈现的单个执行线程,并且JavaScript是该过程的一部分。 As far as I know, multi-threaded user interface rendering systems are unusual because of their complexity (although I could be wrong on this). 据我所知,多线程用户界面渲染系统因其复杂性而异常(尽管我可能错了)。

So the browser will extract the JavaScript from the markup (or a linked script resource), and hand it to the JavaScript engine for evaluation. 因此,浏览器将从标记(或链接的脚本资源)中提取JavaScript,并将其交给JavaScript引擎进行评估。 The JavaScript runtime is an application that enables the evaluation of a stack-based language. JavaScript运行时是一个能够评估基于堆栈的语言的应用程序。 It has a stack and a heap and logic for converting JavaScript script into a form understood by the CPU. 它有一个堆栈和一个堆和逻辑,用于将JavaScript脚本转换为CPU理解的形式。

The stack has zero or more stack frames on it. 堆栈上有零个或多个堆栈帧。 In JavaScript stack frames are called execution contexts. 在JavaScript中,堆栈帧称为执行上下文。 An execution context is like a bookmark in a book, it helps the runtime keep track of where it is in the execution of the script. 执行上下文就像书中的书签,它有助于运行时跟踪脚本执行的位置。 Only when the stack is empty of execution contexts can the browser continue with its rendering work - so yes, running JavaScript typically blocks rendering. 只有当堆栈没有执行上下文时,浏览器才能继续进行渲染工作 - 所以是的,运行JavaScript通常会阻止渲染。

Communication between the various browser subsystems (network, JavaScript runtime, rendering) will occur via the heap allocated to the browser process, or if the browser is multi-process, by inter-process communication mechanisms exposed by the particular operating system being used (eg. named pipes). 各种浏览器子系统(网络,JavaScript运行时,呈现)之间的通信将通过分配给浏览器进程的堆进行,或者如果浏览器是多进程的,则通过正在使用的特定操作系统公开的进程间通信机制进行(例如, 。命名管道)。

Once enough (according to the W3C specification) of the markup (HTML) and styles (CSS) and enough of the script (JavaScript) has been evaluated, rendering can begin. 一旦评估(HTML)和样式(CSS)足够(根据W3C规范)和足够的脚本(JavaScript),就可以开始渲染。

Rendering is a vendor-specific process, but most browsers will be similar at a high level. 渲染是特定于供应商的过程,但大多数浏览器在高级别上都是类似的。 Each HTML element is processed in turn. 每个HTML元素依次处理。 Chrome uses the following sequence for every element on the page: Chrome对页面上的每个元素使用以下序列

  1. The JavaScript that applies to the element is evaluated. 将评估应用于该元素的JavaScript。
  2. The CSS styles that apply to the element are evaluated. 将评估应用于元素的CSS样式。
  3. The element is laid-out on the page accordingly. 该元素相应地布置在页面上。
  4. The element is painted into a bitmap (colored pixels). 该元素被绘制成位图(彩色像素)。
  5. The element is composited. 该元素是合成的。 It's final appearance it calculated according to the impact of the different layers of other elements on the page. 它是根据页面上其他元素的不同层的影响计算的最终外观。

This process might be repeated more than once on any given element, depending on the contents of the page and changes introduced dynamically by scripts. 对于任何给定元素,此过程可能会重复多次,具体取决于页面内容和脚本动态引入的更改。

Computers are normally able to perform billions of calculations every second. 计算机通常能够每秒执行数十亿次计算。 However, the rendering thread only updates 60 times normally (refresh rate/VSync), and network requests are much slower. 但是,渲染线程仅正常更新60次(刷新率/ VSync),并且网络请求要慢得多。 Offloading them to thread is cheaper compared to being blocked by waiting. 与等待阻止相比,将它们卸载到线程更便宜。

An additional reason to offload drawing is to make the interface look snappy: even if something is running long in the JS thread, an offloaded rendering thread will still be responsive as normal. 卸载绘图的另一个原因是使界面看起来很快:即使在JS线程中运行的东西很长,卸载的渲染线程仍然会正常响应。

Very roughly, this is how it goes: 非常粗略,这就是它的方式:

  • The browser gets the HTML page (or HTML data what was sent to it). 浏览器获取HTML页面(或发送给它的HTML数据)。
  • Browser begins to interpret and process the page 浏览器开始解释和处理页面
  • In the head section, if it sees any external linked files, such as JavaScript & CSS files, it initiates a load request immediately. head部分中,如果它看到任何外部链接文件,例如JavaScript和CSS文件,它会立即启动加载请求。
  • If there is any JavaScript, either in the HTML, or in a linked file, the JavaScript is executed immediately , unless it takes advantage of the newer async option. 如果在HTML或链接文件中存在任何JavaScript,则会立即执行JavaScript,除非它利用了较新的async选项。 This is why JavaScript normally includes an event handler for when the document has finished loading. 这就是JavaScript通常包含文档加载完成时的事件处理程序的原因。
  • The rest goes on … 其余的继续......

Taking a break, note that the head stuff is processed as it is received, not later. 休息一下,请注意head东西会在收到时处理,而不是以后处理。

  • The body content is processed, from top to bottom. body内容从上到下进行处理。
  • While this is happening the DOM (Document Object Model — a sort of map of the contents) is created. 在发生这种情况时,会创建DOM(文档对象模型 - 一种内容映射)。
  • HTML visible content is rendered. 呈现HTML可见内容。
  • Any additional external data, such as images will initiate their own download requests. 任何其他外部数据(如图像)都会发起自己的下载请求。 This content is loaded in parallel, rather than waiting . 此内容并行加载,而不是等待 This is why badly designed HTML often leads to redrawing after images have been loaded. 这就是设计糟糕的HTML经常导致在加载图像后重绘的原因。
  • The CSS, which is loaded by now, is applied at the same time. 现在加载的CSS同时应用。

That's it for static content. 这就是静态内容。 There is one more stage, if you have JavaScript which changes content: 如果你有改变内容的JavaScript,还有一个阶段:

  • JavaScript can change the content of the Document at any time. JavaScript可以随时更改Document的内容。
  • Often, but not always, changing the content can trigger a redraw. 通常,但并非总是如此,更改内容可以触发重绘。 This will be needed if the change affects the layout. 如果更改影响布局,则需要这样做。
  • JavaScript can also change individual CSS styles of HTML elements. JavaScript还可以更改HTML元素的各个CSS样式。 Again, this may trigger a redraw. 同样,这可能会触发重绘。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM