1、简单了解浏览器是如何渲染页面和加载页面
浏览器就是通过HTTP 协议与服务器进行通信,取到数据之后进行渲染的过程,如图:
这图是园友的看着挺符合我思路就直接拿来用了,从服务器端返回的是HTML代码,浏览器渲染、加载也是从这里开始;
浏览器有不同的厂商,所以内部肯定会有不同的处理方式,所以这里只是记录一些简单的,况且本篇文章属于基础范畴;
1.1 渲染过程大概如下:
1、浏览器解析html源码,然后创建一个 DOM树(无样式)。在DOM树中,每一个HTML标签都有一个对应的节点,并且每一个文本也都会有一个对应的文本节点,DOM树的根节点就是 documentElement,对应的是html标签。
2、浏览器解析CSS代码,计算出最终的样式数据。对CSS代码中非法的语法她会直接忽略掉(可以通过调试发现),解析CSS的时候会按照如下顺序来定义优先级:浏览器默认设置<外链样式<内联样式<html中的style<improtant。
3、构建出DOM树,并且计算出样式数据后,下一步就是构建一个渲染树(rendering tree)。渲染树和DOM树有点像,但是是有区别的。DOM树完全和html标签一一对应,但是渲染树会忽略掉不需要渲染的元素,比如head、display:none的元素等。而且一大段文本中的每一个行在渲染树中都是独立的一个节点,渲染树中的每一个节点都存储有对应的css样式。
4、一旦渲染树创建好了,浏览器就可以根据渲染树直接把页面绘制到屏幕上。
备注:也许渲染树是与DOM树同时构建的;
1.2一个渲染过程的例子
例如有下面这样一段HTML代码:
<html>
<head>
<title>Beautiful page</title>
</head>
<body>
<p>
Once upon a time there was
a looong paragraph...
</p>
<div style="display: none">
Secret message
</div>
<div><img src="..." /></div>
...
</body>
</html>
那么DOM树是完全和HTML标签一一对应的,如下所示:
documentElement (html)
head
title
body
p
[text node]
div
[text node]
div
img
...
而渲染树就不同了,她只有哪些需要绘制出来的元素,所以head 以及被隐藏的div都不会出现在渲染树中。
root (RenderView)
body
p
line 1
line 2
line 3
...
div
img
...
1.3 重绘和重排(repaints and reflows)
每个页面至少在初始化的时候会有一次重排操作。任何对渲染树的修改都有可能会导致下面两种操作:
页面重排
就是渲染树的一部分必须要更新,并且节点的尺寸发生了变化,这就会触发重排操作。
页面重绘
部分节点需要更新,但是没有改变他的集合形状,比如改变了背景颜色,这就会触发重绘。
什么情况下会触发重绘或重排
加或删除DOM节点
设置 display: none;(重排并重绘) 或者 visibility: hidden(只有重排)
移动页面中的元素
增加或者修改样式
改变窗口大小,滚动页面等
2、浏览器解析Css(Css 关键字查询)
浏览器CSS匹配不是从左到右进行查找,而是从右到左进行查找。比如 DIV#divBox p span.red{color:red;},浏览器的查找顺序如下:先查找 html 中所有 class=’red’ 的 span 元素,找到后,再查找其父辈元素中是否有p元素,再判断p的父元素中是否有 id 为 divBox 的 div 元素,如果都存在,则 CSS 匹配上。浏览器从右到左进行查找的好处是为了尽早过滤掉一些无关的样式规则和元素。Firefox 称这种查找方式为 keyselector(关键字查询),所谓的关键字就是样式规则中最后(最右边)的规则,上面的 key 就是 span.red。
3、总结
1、要进一步了解的话需要看HTTP以及浏览器是如何工作的;
2、为什么要先有Dom树而不是直接渲染到界面,我想可能跟缓存、以及安全机制等有关(通过DOM 树来检查是否能生成一个树);
3、Dom数是与HTML对应,渲染树数Dom的可视化树;
推荐书籍:高性能javascript
参考 http://www.jianshu.com/p/e141d1543143