浏览器渲染
浏览器渲染的大概过程:
- 从服务器接受 DOM
- 样式加载和解析,浏览器会解析三个东西:
HTML/SVG/XHTML,解析这三种文件生成一个DOM Tree
CSS,解析CSS会产生CSS规则树
Javascript,脚本主要是通过DOM API和CSSOM API来操作DOM Tree和CSS Rules Tree
- 根据DOM Tree和CSS Rules Tree构造Rendering Tree (Header或隐藏的元素不会放到渲染树中),渲染数映射了DOM结构,渲染树描述了DOM的直观表现形式
- 计算每个要渲染元素的坐标位置叫“布局(layout)”,浏览器通过“流方法”来布局所有元素(table需要多次处理)
- 将布局显示在浏览器窗口或者说调用操作系统Native GUI的API绘制,这个过程叫做“绘制(painting)”
repaint(重绘)
当在页面上修改一些不需要改变定位的样式时候触发(background-color,border-color, color, visibility);
reflow(重排)
当页面上的改变影响了文档内容、结构或者元素定位时,就会发生重排。通常有以下几种情况:
- DOM操作(元素的增删改或者改变元素的顺序)
- 内容的改变,包括 Form 表单中文字的变化。
- 计算或改变 CSS 属性。
- 增加或删除一个样式表。
- 改变class 属性。
- 浏览器窗口的操作(改变大小、滚动窗口)。
- 激活伪类(如:hover状态)。
页面重排很消耗资源,影响速度和体验,position: absolute / fixed 的大小变化只会影响它本身和他的子元素,所以动画元素尽可能的写到absolute / fixed 元素上,而对于position: static 元素定位变化会影响到他后面所有元素的重排。
js 代码会将一些修改缓存起来,然后一次性执行,每次js读取元素属性都会缓存,读取再修改就会造成一次重排,所以,应该把所有修改操作组合到一起,中间不要穿插属性读取的操作,否则会造成额外的重排
有些时候避免重排但有些时候为达到某些动画效果还要强制触发一次重排
引用文章:
- 为什么每个前端开发者都要理解页面的渲染
- 浏览器两三事