<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> </body> </html>
一个简单的html页面如上所示。css
DOM有两个概念:html
DOM解析:就是把你所写的各类html标签,生成一个DOM TREE,能够认为就是生成了一个最原始的页面,一点样式都没有,毫无CSS修饰。web
DOM渲染:浏览器会把自己默认的样式+用户本身写得样式整合到一块儿,造成一个CSS TREE,而DOM渲染就是指DOM TREE 和 CSS TREE 结合到一块儿,生成一个Render TREE,呈现出一个带有样式的页面。浏览器
1)浏览器会解析三个东西:多线程
一个是HTML/SVG/XHTML,事实上,Webkit有三个C++的类对应这三类文档。解析这三种文件会产生一个DOM Tree。
CSS,解析CSS会产生CSS规则树。
Javascript,脚本,主要是经过DOM API和CSSOM API来操做DOM Tree和CSS Rule Tree.
2)解析完成后,浏览器引擎会经过DOM Tree 和 CSS Rule Tree 来构造 Rendering Tree。注意:异步
Rendering Tree 渲染树并不等同于DOM树,由于一些像Header或display:none的东西就不必放在渲染树中了。
CSS 的 Rule Tree主要是为了完成匹配并把CSS Rule附加上Rendering Tree上的每一个Element。也就是DOM结点。也就是所谓的Frame。
而后,计算每一个Frame(也就是每一个Element)的位置,这又叫layout和reflow过程。
3)最后经过调用操做系统Native GUI的API绘制。async
js 是单线程,可是浏览器是多线程的。布局
浏览器会有不一样的线程,好比说优化
上面的几个线程,在同一个瞬间,只有一个线程起做用,也就是互斥的。好比说浏览器在执行GUI 渲染线程呢,那么其余的4个进程,都处于挂起的状态,在队列里面呆着。
DOM的渲染对应的就是GUI渲染进程;JS的执行对应的就是JS线程;因此,DOM的渲染与JS代码的运行,在同一瞬间只能有一个执行!ui
阻塞XXX是指让XXX暂停了。好比JS的执行阻塞DOM解析,就是
DOM解析 --> JS执行(此时DOM解析暂停) --> JS执行完毕 --> DOM继续解析
先看它俩之间的关系,也就是分析CSS的加载对DOM的解析和渲染的影响。
很明显,DOM本身在那解析DOM TREE 和 css样式有啥关系啊,因此css不影响DOM解析。
也很明显,DOM渲染就是要生成样式呢,确定和css有关系啊,因此css影响DOM渲染。
结论:
JS(加载和执行) 都会阻塞 DOM 的解析,由于JS中可能会对DOM进行操做,可能改变DOM的结构,因此JS的加载和执行是会阻塞DOM解析的。
JS(加载和执行) 都会阻塞 DOM 的渲染,同上面同样,由于JS中可能对样式进行操做。
注: html中每遇到< script >标签,页面就会从新渲染一次,由于要保证标签中的JS代码拿到的都是最新的样式。
结论:
在线程那里说了,CSS的加载会阻塞JS的执行,由于CSS的渲染GUI线程和JS运行线程互斥。
可是CSS不会阻塞JS的加载(浏览器能够预先扫描并下载)
注1:
注2:
结论:
Note: 简单提一句,请注意 visibility: hidden 与 display: none 是不同的。前者隐藏元素,但元素仍占据着布局空间(即将其渲染成一个空框),然后者 (display: none) 将元素从渲染树中彻底移除,元素既不可见,也不是布局的组成部分。
下面简要概述了浏览器完成的步骤:
优化关键渲染路径_就是指最大限度缩短执行上述第 1 步至第 5 步耗费的总时间
https://developers.google.com...