浏览器渲染与css动画

319 阅读5分钟

浏览器渲染

一、过程

1、根据HTML构建HTML树(DOM)

树形结构,HTML文档中所有内容都是节点

2、根据CSS构建CSS树(CSSOM)

3、将两棵树合并成一棵渲染树(render tree)

合成渲染树大体做了以下工作:
  1. 从 DOM 树的根节点开始遍历每个可见节点。
  2. 对于每个可见节点,为其找到适配的 CSSOM 规则并应用它们。
  3. 将每个节点(包括内容和样式)组建成渲染树。

某些节点不需要渲染,如meta、script,会被忽略。

某些节点通过css隐藏也会被忽略,如使用了display: none的节点。(区别于visibility: hidden

4、Layout布局(文档流、盒模型、计算大小和位置)

布局流程的输出是一个“盒模型”,它会精确地捕获每个元素在视口内的确切位置和尺寸:所有相对测量值都转换为屏幕上的绝对像素。

5、Paint绘制(把边框颜色、文字暗色、阴影等画出来)

根据background, border,color等样式和HTML内容,将Layout布局生成的区域填充为最终将显示在屏幕上的像素。

6、Compose合成(根据层叠关系展示画面)

因为css中有层叠上下文概念,把所有层级合成为一层显示在页面中。

关于渲染

1、渲染过程

主要渲染过程如下图所示:

2、三种更新方式

查看不同属性触发的更新方式参考此网站

  1. JS / CSS > 样式 > 布局 > 绘制 > 合成

修改元素的“layout”属性,也就是改变了元素的几何属性(例如宽度、高度、左侧或顶部位置等),那么浏览器将必须检查所有其他元素,然后“自动重排”页面。任何受影响的部分都需要重新绘制,而且最终绘制的元素需进行合成。 如div.remove()移除元素,其他元素需要重新布局(relayout)。relayout则必定触发repaint。

  1. JS / CSS > 样式 > 绘制 > 合成

修改“paint only”属性(例如背景图片、文字颜色或阴影等),即不会影响页面布局的属性,则浏览器会跳过布局,但仍将执行绘制。

  1. JS / CSS > 样式 > 合成

更改一个既不要布局也不要绘制的属性,则浏览器将跳到只执行合成。如只改变transform。

3、关于性能

提高网页性能,就是要降低"重排"和"重绘"的频率和成本,尽量少触发重新渲染。

一般的规则是:

样式表越简单,重排和重绘就越快。 重排和重绘的DOM元素层级越高,成本就越高。 table元素的重排和重绘成本,要高于div元素。

css动画优化

  1. JS优化 使用requestAnimationFrame代替setTimeout或setInterval
  2. CSS优化 使用will-change或translate

CSS动画的两种实现方式

两种实现方式:transition和animation

一、transition

transition表示过渡,可实现元素在不同状态之间切换的过渡效果动画,常应用于不同伪类的切换,如:active、:hover,或js实现的变化。

1、语法

transition: 属性名 时长 过渡方式 延迟

例子

transition: left 2s linear 1s;

过渡方式默认为ease,默认无延迟,可直接使用属性名与时长

可以用逗号分隔两个不同的属性

transition: left 1s, top 2s;

属性名可使用all来代表所有属性 过渡方式默认是ease(逐渐慢放),另外还有linear(匀速)、ease-in(加速)、ease-out(减速)、cubic-bezier函数(可通过此网站来自定义)。

2、transform常用属性功能

transform一般都需要配合transition过渡使用。

各种方式组合使用:

transform: translate(20px, 20px) scale(1.5) rotate(10deg, 10deg) skew(10deg, 10deg);
  • translate 位移

    translateX(20px); /*X轴上位移20px*/
    translateX(50%); /*X轴上位移宽度的50%*/
    translateY(); /*同上*/
    translate(20px, 20px); /*同时在X轴与Y轴上位移*/
    translateZ(); /*Z轴位移需要父容器有perspective属性*/
    translate3d(x,y,z);
    

    trick

    translate(-50%, -50%);/*可实现绝对定位元素的居中*/
    
  • scale 缩放

    scale(1.5); /*放大至1.5倍*/
    scaleX(x); /*X轴上缩放*/
    scaleY(y); /*Y轴上缩放*/
    scale(x,y); /*上述两者合并*/
    

    trap

    • 容易出现模糊
    • border宽度也会受到影响
  • rotate 旋转

    一般用于制作旋转loading

    rotate(45deg); /*绕着某点旋转,默认为中心点center center,可通过transform-origin设置旋转点*/
    rotateX(45deg); /*绕着X轴旋转*/
    rotateY(45deg); /*绕着Y轴旋转*/ 
    rotateZ(45deg); /*绕着Z轴旋转,平面图形Z轴垂直于屏幕*/
    rotate3d(x,y,z,deg); /* x,y,z确定一个轴的矢量,最后一个参数为绕着该轴旋转的角度 */
    
  • skew 倾斜

    skewX(deg); /* 图形向X轴方向倾斜,参数为Y轴向X轴正方向倾斜的角度*/
    skewY(deg); /* 图形向Y轴方向倾斜,参数为X轴向Y轴正方向倾斜的角度 */
    skew(x,y); /* 为以上两者的合并 */
    

二、animation

animation用于实现较复杂的动画。步骤为声明关键帧,为元素添加动画属性。

1、声明关键帧

两种方式:from to、百分数

  • from to
    @keyframes slidein{
        from{
            transform: translate(0%);
        }
        to{
            transform: translate(100%);
        }
    }
    
  • 百分数
    0%{ top: 0; left: 0;}
    30%{ top: 50px; }
    100% { top: 100px; left: 100%; }
    

2、animation语法

animation: 时长 | 过渡方式 | 延迟 | 次数 | 方向 | 填充模式 | 是否暂停 | 动画名;

  • 时长:animation-duration, 动画持续时间
  • 过渡方式:animation-timing-function,如linear、ease-in等。
  • 延迟:animation-delay
  • 次数:animation-iteration-count,可为小数,infinite表示无限循环播放动画。
  • 方向:animation-direction,默认为normal(重置至起点),alternate(来回)、reverse(反向)、alternate-reverse(反向开始,来回)
  • 填充模式:animation-fill-mode,默认为none,其他值有forwards(结束时取用执行期间最后一个关键帧)、backwards(应用至目标的第一个关键帧)、both(开始backwards+结尾forwards,其中delay阶段显示第一帧,参考此网站)。
  • 是否暂停:animation-play-state,取值有running、paused,可实现动画的暂停与重播
  • 动画名:animation-name,为@keyframes xxx所指定的动画名。