浏览器工做原理 (一) : 浏览器渲染原理 & 浏览器内核

浏览器工做原理

写在前面

本人对浏览器的工做原理的理解尚浅,若有错误欢迎各位大佬指正。javascript

本文章回答了那些问题

  1. 浏览器如何渲染一个页面css

  2. 浏览器有哪些线程,线程之间如何工做的html

为何要学习这些问题

  1. 了解浏览器渲染原理能够帮助咱们优化html、css、js的组织,优化渲染性能java

  2. 了解浏览器进程能够帮助咱们深刻了解异步编程web

浏览器渲染原理

浏览器首先下载html、css、js。 接着解析生成dom tree、rule tree和rendering tree。 再经过layout后渲染页面。ajax

下载

浏览器打开页面以后,会根据页面URL向服务器发送一个请求,服务器响应页面的HTML。
(HTML解析过程当中遇到插入的css、和js会同时发起请求资源。)chrome

解析

html/svg 解析生成 dom tree,css 解析生成 css rule tree, 这二者结合生成rendering(render) tree。编程

渲染树包含多个带有视觉属性(颜色、尺寸等)的矩形, 这些矩形的排列顺序就是它们在屏幕上的显示顺序后端

解析过程当中遇到js标签会下载解析执行浏览器

解析的过程是词法分析和语法分析

layout

渲染树构建完成以后进入layout阶段

layout是指计算每一个DOM元素最终在屏幕上显示的大小和位置。 遍历顺序为从左至右,从上到下

因为web页面的元素布局是相对的, 因此任意元素的位置发生变化,都会引发其余元素位置的变化,这就是reflow

paint

渲染引擎会遍历渲染树,由用户界面后端层将每一个节点绘制出来

按照合理的顺序合并图层而后显示到屏幕上。

浏览器刷新的频率大概是60次/秒, 也就是说刷新一次大概时间为16ms

若是浏览器对每一帧的渲染工做超过了这个时间, 页面的渲染就会出现卡顿的现象。

以上过程是渐进的,并不必定严格按照顺序执行的,为了更快将内容呈如今不屏幕中, 不会等到HTML所有解析完成以后才开始构建渲染树和layout,它会在不断接收和处理其余网络资源的同时,就开始部份内容的解析和渲染

渲染完成以后会触发 ready事件

什么状况下会引发 reflow repaint

当render tree (元素尺寸) 发生变化时则会从新layout 则会所以reflow

浏览器内核

浏览组成

用户界面

浏览器内核: 浏览器引擎(查询操做渲染引擎的接口)、渲染引擎、js引擎、网络(http请求)

数据存储

js引擎 (IE9+: Chakra firefox:monkey chrome:v8)

渲染引擎(firefox:gecko、chrome/safari:webkit)

因此大部分浏览器至少有三个线程:

JS引擎线程、GUI渲染线程、浏览器事件触发线程

除此以外还会有 http请求线程等、计时器线程、EventLoop轮询的处理线程等。

javascript引擎

js引擎是基于事件驱动的, 采用的是单线程运行机制。

由于JS能够操做DOM元素, 从而影响到GUI的渲染结果, 所以JS引擎线程和GUI渲染线程是互斥的。 也就是说
JS引擎处于运行状态时,GUI渲染线程将处于冻结状态。

javascript的单线程

javascript引擎负责解释和执行javascript代码的线程只有一个,称为主线程。js还有其余的线程称为工做线程。

主线程上只执行同步任务。

Web Worker

H5提出了Web Worker标准, 容许js建立多个线程, 可是彻底受父线程控制,且不能够操做DOM

工做进程

浏览器还有还有其余的线程,例如:

处理 ajax 的线程,dom事件线程、定时器线程、读写文件的线程等。这些被称为工做进程

这些线程可能存在于js引擎之中或者以外, 称为工做线程
工做线程的任务完成以后, 会推入到一个任务队列(task queue)

JavaScrpt 的异步编程

js引擎只执行同步任务, 异步任务会有工做线程来执行。

异步过程

当须要进行异步操做(定时器、ajax请求、dom事件注册等), 主线程会发一个异步任务的请求, 相应的工做线程接受请求; 当工做线程完成工做以后, 通知主线程;主线程接收到通知以后, 会执行必定的操做(回调函数)。

事件循环

主线程和工做线程之间的通知机制叫作事件循环。

调用栈 (call stack): 主线程执行时生成的调用栈

任务队列 (task queue): 工做线程完成任务后会把消息推到一个任务队列, 消息就是注册时的回调函数

当调用栈为空时, 主线程会从任务队列里取一条消息并放入当前的调用栈当中执行, 主线程会一直重复这个动做直到消息队列为空。 这个过程就叫作事件循环 (event-loop)。

渲染线程和js线程的互斥

渲染线程和js线程是互斥的, 在js引擎执行时,渲染线程会被挂起。

为何会阻塞

js在浏览器中须要被下载、解释、执行这三部。 html中的script标签是阻塞的, 也就是说顺序下载、解释、执行。

浏览器会在js执行后决定当前文档是否须要进行从新渲染或者重排。
js引擎线程和UI线程是互斥的, 因此js执行时会阻塞页面的渲染。

下载虽然是异步的, 可是执行仍是同步的。 先出现的SCRIPT标签必定是先执行。 即便它是最后一个下载完成。js执行中终端浏览器html解析

相关文章
相关标签/搜索