在前端开发中, 我们有时候会选择使用translate
来改变元素的位置, 而不是使用传统的定位方式(如top
, left
, right
, bottom
), 主要是因为 性能 方面的考虑。
具体来说, translate
是通过 CSS中的transform
属性实现的, 它操作的是元素的渲染层, 而不是布局层。
ps: 这里的
渲染层
和布局层
是浏览器渲染原理相关的内容
这样一来, 浏览器就不会因为位置的改变而重新计算布局, 也就是触发重排(reflow), 从而提高渲染性能。
扩展知识
延伸几个知识点:
1. Reflow 与 Repaint:
- Reflow (重排): 是指浏览器在DOM树发生变化时重新计算元素的位置和几何形状。当使用定位属性(如
top
,left
)改变元素位置时, 就会触发 Reflow, 这在页面元素复杂时会非常消耗性能。 - Repaint (重绘): 是指元素的外观发生变化时 (如背景颜色, 边框等), 需要重新绘制这些元素, 但不会改变DOM树, 也就是不会涉及重新计算布局(Reflow)。相对来说, Repaint 的性能开销就小了很多。
2.Transform - Translate:
translate
是CSSTransform
属性的一部分, 通过矩阵变换 (matrix transformations) 来操作元素的视觉位置。 这个过程是在合成层 (compositing layer) 完成的, 不会影响文档的布局结构, 所以不会触发 Reflow, 只会触发 Repaint 。
3.硬件加速:
- 使用
translate
通常能够借助 GPU 加速, 而传统的定位方式则主要依赖于 CPU。在渲染大量图形和动画时, GPU 的效率是显著优于 CPU 的, 能够带来更流畅的视觉效果。
4.性能优化的常见实践:
- 在设计动画和频繁调整位置的场景下, 优先考虑使用
transform:translate()
, 而不是top
或left
。 - 合理利用
will-change
属性, 告知浏览器即将发生的一些变化(如transform
或opacity
), 预先做一些优化处理, 提高动画的流畅度。
5.实际应用中的权衡:
- 尽管
translate
在性能上具有优势, 但也不是所有情况下都适用。例如,对于特定布局需求或固定定位 (fixed position)的情景, 传统的定位方式依然不可或缺。因此, 我们需要根据具体需求和性能考量作出合理选择。
进阶扩展.
浏览器渲染页面流程:
步骤 | 简要说明 |
---|---|
1.解析HTML | 解析完会得到DOM树和CSSOM树 |
2.样式计算 | 遍历得到的DOM树,根据样式优先级规则为树中的每个节点计算出它最终的样式,得到一颗带有样式的DOM树 |
3.布局(flow) | 依次遍历DOM树的每一个节点, 计算每个节点的几何信息, 得到布局树 |
4.分层 | 分层的好处在于, 将来某一个层改变后, 仅会对该层进行后续处理,从而提升效率。而滚动条, 堆叠上下文, transform, opacity 等样式都会或多或少的影响分层结果, 也可以通过will-change 属性更大程度地影响分层结果 |
5.绘制(paint) | 为每个层单独产生绘制指令集, 用于描述这一层的内容该如何 ‘画’ 出来 |
6.分块 | 前面5个步骤主要是工作在渲染主线程中, 完成绘制后, 主线程会将每个图层的绘制信息提交给合成线程, 剩余工作将由合成线程完成。合成线程首先对每个图层进行分块, 将其划分为更多的小区域, 再从线程池中调动多个线程来完成分块工作 |
7.光栅化 | 合成线程会将块信息交给GPU进程,以极高的速度完成光栅化。而GPU进程会调动多个线程来完成光栅化, 并且优先处理靠近视口区域的块 |
8.画 | 合成线程拿到每个层,每个块的位图后,生成一个个 指引(quad) 信息, 然后将quad提交给GPU进程, 由GPU进程产生系统调用, 提交给GPU硬件,完成最终的屏幕成像。 |