浏览器渲染原理 (一)在网址中输入一个网站后面都作了什么

人法地,地法天,天法道,道法天然。javascript

浏览器渲染原理 (一)在网址中输入一个网站后面都作了什么css

浏览器渲染原理 (二)css、javascript、dom 阻塞关系html

浏览器渲染原理 (三) repaint(重绘)和 reflow(回流)详解html5

若是想看更深刻的原理,能够看:java

别人翻译的外国友人的渲染原理node

浏览器是怎么渲染 html 的

关键渲染路径(Critical Rendering Path)是指与当前用户操做有关的内容。例如用户刚刚打开一个页面,首屏的显示就是当前用户操做相关的内容,具体就是浏览器收到HTML、CSS 和 JavaScript 等资源并对其进行处理从而渲染出 Web 页面。 以下图所示渲染流程: web

bowser-render
当咱们在浏览器中输入一个网址的时候,他是怎么请求资源,而且把咱们的页面绘制出来的,大概能够分为六步,其中又能够细分,下面我大概说一个 6 大步骤:

  1. 浏览器首先经过 HTTP 协议或者 HTTPS 协议,向服务器请求页面,固然这个其中也可能有缓存什么的;
  2. 把请求回来的HTML 代码通过解析,构建成 DOM 树;
  3. 计算 DOM 树上的 CSS 属性,生成 CSSOM 树(CSS Object Model)
  4. DOM 树CSSOM 树合并成一个渲染树(rendering tree)
  5. 渲染树的每一个元素包含的内容都是计算过的,它被称之为布局 layout。浏览器使用一种流式处理的方法,只须要一次 pass 绘制操做就能够布局全部的元素;
  6. 将渲染树的各个节点绘制到屏幕上,这一步被称为绘制 painting
  7. 按照合理的顺序合并图层而后显示到屏幕上 Composite(渲染层合并)

第一步请求资源

在咱们在浏览器中输入完网址的时候,浏览器其实会先作如下几小步:浏览器

  1. DNS 查询(就是把当前域名解析成为 ip 地址)
  2. TCP 链接
  3. HTTP 请求响应
  4. 服务器返回数据

第二步构建 DOM 树

在构建 DOM 树的时候又能够分为几小步:缓存

  1. 字符流经过状态机解析成为 词 token
  2. token => prase => DOM 树

构建 DOM 的过程是:从父到子,从先到后,一个一个节点构造,DOM 树结构和 HTML 标签一一对应。服务器

第三步 CSSOM 模型构建

在计算 css 规则的时候,咱们会在已经构建好的元素上,去检查它匹配到了哪些规则,再根据规则的优先级,作覆盖和调整。而且 CSSOM 主要是DOM 结构上的盒的描述,他基本上是依附于 DOM 树的。 CSS 计算是把 CSS 规则应用到 DOM 树上,为 DOM 结构添加显示相关属性过程。 CSSOM 是有 rule 部分和 view 部分的,rule 部分是在 dom 开始以前就构件完成的,而 view 部分是跟着 dom 同步构建的。

第四步构建渲染树(Rendr tree construction)

经过 DOM 树CSS 规则树,浏览器就能够经过它两构建渲染树了。 渲染树DOM 元素相对应的,但并不是一一对应。非可视化的 DOM 元素不会插入呈现树中,例如“head”元素。若是元素的 display 属性值为“none”,那么也不会显示在呈现树中(可是 visibility 属性值为“hidden”的元素仍会显示)。

第五步渲染树布局(layout of the render tree)

呈现器在建立完成并添加到呈现树时,并不包含位置和大小信息。计算这些值的过程称为布局重排。 布局阶段会从渲染树更新节点开始遍历,因为渲染树的每一个节点都是一个 Render Object 对象,包含宽高,位置,背景色等样式信息。浏览器中渲染这个过程,就是把每个元素对应的盒变成位图,再把位图合成一个大的位图。 布局又分为全局布局和增量布局,详情请看

第六步渲染树绘制(Painting the render tree)

在绘制阶段,系统会遍历呈现树,并调用呈现器的“paint”方法,将呈现器的内容显示在屏幕上。绘制工做是使用用户界面基础组件完成的。 绘制又分为全局绘制增量绘制,而且绘制的属性也会有先后之分,详情请看

compositor layer 合成渲染层

渲染过程把元素变成位图,合成把一部分位图变成合成层,最终的绘制过程把合成层显示到屏幕上。 对于 transform/opacity 这两种变换,浏览器不会用 repaint/reflow 处理,而是在已经渲染的元素基础上进行附加工做。 他的渲染流程为下图所示:

compositor
js 改变样式,样式只触发合成属性,不触发 repaint/reflow.附原文连接 stick-to-compositor-only-properties-and-manage-layer-count

阻塞渲染:CSS、JavaScript、DOM

谈论资源的阻塞时,咱们要清楚,现代浏览器老是并行加载资源。例如,当 HTML 解析器(HTML Parser)被脚本阻塞时,解析器虽然会中止构建 DOM,但仍会识别该脚本后面的资源,并进行预加载。 同时,因为下面两点:

  1. 默认状况下,CSS 被视为阻塞渲染的资源,这意味着浏览器将不会渲染任何已处理的内容,直至CSSOM 构建完毕
  2. JavaScript 不只能够读取和修改 DOM 属性,还能够读取和修改 CSSOM 属性,所以 CSS 解析script 的执行互斥。
  3. 存在阻塞的 CSS 资源时,浏览器会延迟 JavaScript 的执行和 DOM 构建

正是因为以上这些缘由,script 标签的位置很重要咱们在实际开发中应该尽可能坚持如下两个原则: 在引入顺序上,CSS 资源先于 JavaScript 资源。 JavaScript 应尽可能少的去影响 DOM 的构建。 想理清楚 CSS、JavaScript、DOM 之间的相互阻塞关系

改变阻塞模式

咱们熟知的javascript标签上deferasync属性,还有可能不太熟知的link标签上的preload属性。

在介绍 async 和 defer 以前咱们要先看了解两个概念,loadDOMContentLoaded的执行时机

load 和 DOMContentLoaded

load Load 事件触发表明页面中的 DOM,CSS,JS,图片已经所有加载完毕。 DOMContentLoaded DOMContentLoaded 事件触发表明初始的 HTML 被彻底加载和解析,不须要等待 CSS,JS,图片加载。

首先是 async 和 defer

async 和 defer 他们对于内联脚本无做用(即没有 src 属性的脚本) async 该布尔属性指示浏览器是否在容许的状况下异步执行该脚本。async 与 defer 的区别在于,若是已经加载好,就会开始执行——不管此刻是 HTML 解析阶段仍是 DOMContentLoaded 触发以后。须要注意的是,这种方式加载的 JavaScript 依然会阻塞 load 事件。换句话说,async-script 可能在 DOMContentLoaded 触发以前或以后执行,但必定在 load 触发以前执行。而且多个 async-script 的执行顺序是不肯定的。

defer defer 属性表示延迟执行引入的 JavaScript,即这段 JavaScript 加载时 HTML 并未中止解析,这两个过程是并行的。整个 document 解析完毕且 defer-script 也加载完成以后(这两件事情的顺序无关),会执行全部由 defer-script 加载的 JavaScript 代码,而后触发 DOMContentLoaded 事件。

defer 与相比普通 script,有两点区别:载入 JavaScript 文件时不阻塞 HTML 的解析,执行阶段被放到 HTML 标签解析完成以后。

preload 和 prerender

preload

<link> 元素的 rel 属性的属性值preload可以让你在你的HTML页面<head>元素内部书写一些声明式的资源获取请求,能够指明哪些资源是在页面加载完成后即刻须要的。对于这种即刻须要的资源,你可能但愿在页面加载的生命周期的早期阶段就开始获取,在浏览器的主渲染机制介入前就进行预加载。这一机制使得资源能够更早的获得加载并可用,且更不易阻塞页面的初步渲染,进而提高性能。 预加载能够必定程度上下降首屏的加载时间,由于能够将一些不影响首屏但重要的文件延后加载,惟一缺点就是兼容性很差.

prerender 能够经过预渲染将下载的文件预先在后台渲染,可使用如下代码开启预渲染 预渲染虽然能够提升页面的加载速度,可是要确保该页面百分百会被用户在以后打开,不然就白白浪费资源去渲染

总结

这个里面基本上了解了浏览器的渲染过程,可是有不少细节没有套路好比说咱们都知道浏览器是单线程的,ui 线程javascript 线程是怎么协调的,还有一个比较重要的是重绘和回流(重排)

参考

浏览器的渲染:过程与原理

浏览器渲染原理与过程

HTML、script元素用于嵌入或引用可执行脚本。

浏览器的工做原理:新式网络浏览器幕后揭秘

重绘,回流和合成,了解基本浏览器绘制帮你优化页面性能

相关文章
相关标签/搜索