“-webkit-transform: translate3d(0,0,0);” 究竟是做什么用的?适用于整个页面吗?

100
“-webkit-transform: translate3d(0,0,0);” 是什么意思?它会有性能问题吗?我应该把它应用于整个页面还是单独的元素?它似乎可以显著改善滚动事件。谢谢您的讲解!

4
答案所缺失的内容是:实际上它将元素在x、y和z轴上都平移了0像素。 ;) - insertusernamehere
它还会对字体渲染产生影响,尤其在大字号上更为明显。否则,平滑的边缘会再次出现锯齿状。可能是浏览器或操作系统特定的问题,在Windows 7上使用Chrome 33时观察到这一现象。 - patrickj
1
@patrickj 我也开始注意到在Windows 7上的Chrome 33(33.0.1750.117m)中,使用translate3d(0,0,0)会出现略微不同的行为。它使我的一个元素变得不可见,所以我将其删除了。 - David Sherret
3
将来参考:will-change 属性还会将 HTML 元素分离成自己的一层。详见 https://developer.mozilla.org/en-US/docs/Web/CSS/will-change。 will-change 属性将取代 -webkit-transform:translate3d(0,0,0) 的 hack。 - Jason Lydon
不要使用 * CSS 选择器,否则我的所有链接都会变为不活动状态 :) - stefan
透视 CSS 在 Safari 中会影响性能,而我的是在滚动层中。 - yeahdixon
6个回答

128

-webkit-transform: translate3d(0,0,0); 可以让一些设备运行其硬件加速。

可以在这里找到更多信息 Here

原生应用程序可以访问设备的图形处理单元(GPU)来实现高效的像素渲染。另一方面,Web 应用程序运行在浏览器的上下文中,大部分(如果不是全部)渲染由软件完成,导致转换所需的计算能力较低。但 Web 已经在赶超,大多数浏览器供应商现在通过特定的 CSS 规则提供了图形硬件加速。

使用 -webkit-transform: translate3d(0,0,0); 可以激活 GPU 以进行 CSS 转换,使其更加平滑(帧率更高)。

注意: translate3d(0,0,0) 在您看到的内容方面没有任何作用。它只是一种强制硬件加速的技术,将对象移动 0 像素在 x、y 和 z 轴上。


另一种选择是 -webkit-transform: translateZ(0)。如果由于转换而在 Chrome 和 Safari 上出现闪烁,请尝试使用 -webkit-backface-visibility: hidden-webkit-perspective: 1000。有关更多信息,请参阅此文章


我不确定在缓存纹理上应用矩阵变换是否真的会带来改进。当内容从缓存纹理移动到帧缓冲区时,变换会提高复杂操作的性能,但对于普通绘画事件没有任何好处。它既不会造成任何伤害,也没有任何好处。如果我错了,请纠正我? - Mathew Kurian
我认为即使是普通的绘画也会加速...其中一个图层创建标准是“3D或透视变换CSS属性”。 - Yotam Omer
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - Ethan
1
@Ethan 是的,根据这篇文章,两者都可以使用。我只知道3D变换,但显然在大多数浏览器中translateZ也能起到同样的效果。 - Yotam Omer
translate3d(0,0,0)translateZ(0)会导致位置固定的问题。 -webkit-font-smoothing: antialiased;是另一种利用3D加速而不会产生这些问题的方法,但它只在Safari中有效。 - Watchmaker
显示剩余3条评论

12

我没有看到任何一个解释这个的答案。许多转换可以通过计算每个 div 及其选项并使用复杂的验证集来完成。但是,如果您使用 3D 函数,则您拥有的每个 2D 元素都被视为 3D 元素,我们可以对这些元素进行矩阵变换(在运行时)。然而,大多数元素“从技术上讲”已经具有硬件加速,因为它们都使用 GPU。但是,3D 转换直接作用于每个这些 2D 渲染版本(或 div 的缓存版本)和它们上面的矩阵变换(这些变换是向量化和并行化 FP 数学)。

需要注意的是,3D 转换仅对缓存的 2D div 上的特性进行更改(换句话说,div 已经是渲染图像了)。因此,诸如更改边框宽度和颜色之类的事情不再“ 3D ”地模糊地说。如果您考虑一下,更改边框宽度需要重新渲染 div 并将其重新缓存,以便可以应用 3D 转换。

希望这讲得通,如果您有更多问题,请告诉我。

回答您的问题,translate3d: 0x 0y 0z 不会发生任何事情,因为变换直接作用于运行 div 的顶点进入 GPU 着色器时形成的纹理。此着色器资源现在已缓存,并且绘制到帧缓冲区时将应用矩阵。所以,基本上没有从中获得任何好处。

这就是浏览器内部的工作原理。

步骤1:解析输入

<div style = "position:absolute;left:0;right:0;bottom:0;top:0;"></div>

步骤2:开发复合层

CompositeLayer compLayer = new CompositeLayer();
compLayer.setPosition(0, 0, 0, 0);
compLayer.setPositioning(ABSOLUTE); // Note. this is psuedocode. The actual code
Pipeline.add(compLayer, zIndex); // would be significantly more complex.

步骤三:渲染复合图层

for (CompositeLayer compLayer : allCompositeLayers){

     // Create and set cacheTexture as active target
     Texture2D cacheTexture = new Texture2D();
     cacheTexture.setActive();

     // Draw to cachedTexture
     Pipeline.renderVertices(compLayer.getVertices());
     Pipeline.setTexture(compLayer.getBackground());
     Pipeline.drawIndexed(compLayer.getVertexCount());

     // Set the framebuffer as active target
     frameBuffer.setActive();

     // Render to framebuffer from texture and **applying transformMatrix**
     Pipeline.renderFromCache(cacheTexture, transformMatrix);
}

6

在MobileSafary(iOS 5)中滚动存在一个漏洞,导致滚动容器中出现输入元素的副本。

对每个子元素使用translate3d可以解决这个奇怪的漏洞。以下是我使用的CSS示例,它帮我解决了问题。

.scrolling-container {
    overflow: auto;
    -webkit-overflow-scrolling: touch;
}

.scrolling-container .child-element {
    position: relative;
    -webkit-transform: translate3d(0,0,0);
}

5

Translate3D 强制启用硬件加速。CSS 动画、变换和过渡不会自动使用GPU 加速,而是从浏览器较慢的软件渲染引擎执行。为了使用 GPU,我们使用 translate3d。

目前,像 Chrome、FireFox、Safari、IE9+ 和最新版本的 Opera 浏览器都带有硬件加速功能,只有在它们发现一个 DOM 元素可以受益于此时才会使用它。


5

请注意,这会创建一个堆叠上下文(加上其他答案所说的内容),因此它确实可能会影响您看到的内容,例如使某些东西在不应该出现时出现在覆盖层上方。


0

我正在使用mathlive和tiptap,在我的情况下,这行代码在编辑公式时导致了意外的滚动到页面顶部。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接