浏览器渲染
一、过程
1、根据HTML构建HTML树(DOM)
2、根据CSS构建CSS树(CSSOM)
3、将两棵树合并成一棵渲染树(render tree)
- 从 DOM 树的根节点开始遍历每个可见节点。
- 对于每个可见节点,为其找到适配的 CSSOM 规则并应用它们。
- 将每个节点(包括内容和样式)组建成渲染树。
某些节点不需要渲染,如meta、script,会被忽略。
某些节点通过css隐藏也会被忽略,如使用了display: none的节点。(区别于visibility: hidden)
4、Layout布局(文档流、盒模型、计算大小和位置)
布局流程的输出是一个“盒模型”,它会精确地捕获每个元素在视口内的确切位置和尺寸:所有相对测量值都转换为屏幕上的绝对像素。
5、Paint绘制(把边框颜色、文字暗色、阴影等画出来)
根据background, border,color等样式和HTML内容,将Layout布局生成的区域填充为最终将显示在屏幕上的像素。
6、Compose合成(根据层叠关系展示画面)
因为css中有层叠上下文概念,把所有层级合成为一层显示在页面中。
关于渲染
1、渲染过程
主要渲染过程如下图所示:
2、三种更新方式
查看不同属性触发的更新方式参考此网站。
- JS / CSS > 样式 > 布局 > 绘制 > 合成
修改元素的“layout”属性,也就是改变了元素的几何属性(例如宽度、高度、左侧或顶部位置等),那么浏览器将必须检查所有其他元素,然后“自动重排”页面。任何受影响的部分都需要重新绘制,而且最终绘制的元素需进行合成。 如div.remove()移除元素,其他元素需要重新布局(relayout)。relayout则必定触发repaint。
- JS / CSS > 样式 > 绘制 > 合成
修改“paint only”属性(例如背景图片、文字颜色或阴影等),即不会影响页面布局的属性,则浏览器会跳过布局,但仍将执行绘制。
- JS / CSS > 样式 > 合成
更改一个既不要布局也不要绘制的属性,则浏览器将跳到只执行合成。如只改变transform。
3、关于性能
提高网页性能,就是要降低"重排"和"重绘"的频率和成本,尽量少触发重新渲染。
一般的规则是:
样式表越简单,重排和重绘就越快。 重排和重绘的DOM元素层级越高,成本就越高。 table元素的重排和重绘成本,要高于div元素。
css动画优化
- JS优化 使用requestAnimationFrame代替setTimeout或setInterval
- 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所指定的动画名。