CSS与浏览器的工做原理

此内容均为借鉴,提炼。编程

现代浏览器一般拥有两个重要的执行线程,这两个线程相互配合来渲染出页面:主线程 与 排版线程浏览器

主线程:

  1. 运行JavaScript
  2. 计算HTML元素的CSS样式
  3. 布局页面
  4. 把页面元素绘制成一个或多个位图
  5. 把这些位图移交给排版线程

排版线程:

  1. 经过GPU渲染位图,并显示在屏幕上
  2. 主线程请求更新位图的可见部分或即将可见的部分
  3. 判断出当前页面处于可见的部分
  4. 判断出即将经过页面滚动而可见的部分
  5. 随着用户滚动页面来移动这些部分(可见部分的和即将可见的部分)

GPU:

  1. 排版线程经过GPU把位图绘制到了屏幕上。
  2. GPU比较擅长于:绘制位图到屏幕、重复的绘制同一个位图、在不一样的位置,以不一样的旋转角度,或者不一样的缩放大小来绘制同一个位图。
  3. GPU相对慢的地方:将位图加载到显存里。

重排与重绘:

浏览器下载完页面中的全部组件——HTML标记、JavaScript、CSS、图片以后会解析生成两个内部数据结构——DOM树渲染树数据结构

  1. DOM树表示页面结构,渲染树表示DOM节点如何显示。
  2. 当DOM的变化影响了元素的几何属性(宽或高),浏览器须要从新计算元素的几何属性,一样其余元素的几何属性和位置也会所以受到影响。浏览器会使渲染树中受到影响的部分失效,并从新构造渲染树。这个过程称为重排。完成重排后,浏览器会从新绘制受影响的部分到屏幕,该过程称为重绘。

    tips:并非全部的DOM变化都会影响几何属性,好比改变一个元素的背景色并不会影响元素的宽和高,这种状况下只会发生重绘。布局

 

引发重排的状况:

很显然,每次重排,必然会致使重绘,那么,重排会在哪些状况下发生?性能

  1. 添加或者删除可见的DOM元素
  2. 元素位置改变
  3. 元素尺寸改变
  4. 元素内容改变(例如:一个文本被另外一个不一样尺寸的图片替代)
  5. 页面渲染初始化(没法避免)
  6. 浏览器窗口尺寸改变

这些都是显而易见的,或许你已经有过这样的体会,不间断地改变浏览器窗口大小,致使UI反应迟钝(某些低版本IE下甚至直接挂掉),如今你可能恍然大悟,没错,正是一次次的重排重绘致使的!动画

 

Transition:

在整个Transition的每一帧中,浏览器都要去从新布局,绘制页面,并把最新的位图对象加载到GPU。

设计决策:

那么,是否这就意味这咱们不要去缓动一个元素的高度?非也,一些状况下,这是你的设计效果的一部分,而且动画效果能够很是快的完成。也许动画的元素是孤立的,不会引发页面其余部分进行从新布局;也许该元素只是单纯的进行重绘,浏览器能够快速的完成;也许该元素很小,浏览器只需将很小的位图对象传递给GPU。
固然了,在不影响你设计的视觉效果的状况下,最好去缓动一个性能较好的CSS属性,如transform,而不是去缓动一个性能较差的CSS属性,如height。举例来讲,假设你的设计中有一个按钮,当点击它的时候会出来一个菜单,试着去缓动菜单的transform属性来显示它而不是缓动它的top或height属性来达到相似的效果。
在动画上特别快的CSS属性包括:spa

  1. CSS transform
  2. CSS opacity
  3. CSS filter

总结

重排和重绘是DOM编程中耗能的主要缘由之一,平时涉及DOM编程时能够参考如下几点:线程

  1. 尽可能不要在布局信息改变时作查询(会致使渲染队列强制刷新)
  2. 同一个DOM的多个属性改变能够写在一块儿(减小DOM访问,同时把强制渲染队列刷新的风险降为0)
  3. 若是要批量添加DOM,能够先让元素脱离文档流,操做完后再带入文档流,这样只会触发一次重排(fragment元素的应用)
  4. 将须要屡次重排的元素,position属性设为absolute或fixed,这样此元素就脱离了文档流,它的变化不会影响到其余元素。例若有动画效果的元素就最好设置为绝对定位。
相关文章
相关标签/搜索