【问题标题】:Why CSS transition lags in mobile Chrome?为什么 CSS 过渡在移动 Chrome 中滞后?
【发布时间】:2017-02-27 15:02:06
【问题描述】:

在开发 CSS 图像缩放功能时,我在移动 Chrome 中遇到了性能问题。

说明: 如果我尝试通过将 CSS transform 属性直接添加到图像来缩放图像,一切正常。 60fps (JSFiddle) 的缩放过渡像黄油一样平滑。

<img src="http://placehold.it/1000x1500" style="transform:matrix(2, 0, 0, 2, 0, 0);" />

问题:但是如果我将图像包装在 div 容器中并尝试转换容器,则过渡非常滞后 (JSFiddle)。过渡以很大的延迟开始并且并不顺利。 这似乎是唯一的移动 Chrome 问题,因为它不会在其他浏览器(如 Android 上的 Firefox)中发生,仅在我的移动设备 (Nexus 5) 和其他一些 Android 设备上发生。

<div style="transform:matrix(2, 0, 0, 2, 0, 0);">
    <img src="http://placehold.it/1000x1500" />
</div>

有人知道 CSS 或 HTML 结构有什么问题吗?

【问题讨论】:

  • 我想我已经找到了问题所在。这似乎是一个一般的 Chrome 问题,而不仅仅是移动 Chrome 问题。如果您检查此example,您会发现缩放(尤其是缩小)不仅仅是移动 Chrome 中的延迟。如果有一个大图像并且它的一部分不在视口中,则浏览器在其内部光栅化缓存中没有整个图像。所以图像会在必要时进行处理。

标签: html css google-chrome css-transitions


【解决方案1】:

使用 JavaScript 设置类名,但让 CSS 完全处理过渡并触发 GPU 加速。

我建议使用onclick HTML 事件属性来设置两个函数的触发器,zoomInzoomOut

HTML

    <div id="zoom-container">
      <img src="http://placehold.it/1000x1500" />
    </div>

    <div id="zoom-toolbar">
      <button id="zoom-in" onclick="zoomIn()">Zoom in</button>
      <button id="zoom-out" onclick="zoomOut()">Zoom out</button>
    </div>

您现在有两个函数,用于设置所需的 CSS 类名。

JavaScript

    function zoomIn() {
      var element = document.getElementById("zoom-container");
      element.className = 'zoomed-in';
    };

    function zoomOut() {
      var element = document.getElementById("zoom-container");
      element.className = 'zoomed-out';
    };

为了实现所需的动画,CSS 现在也可以简单得多。

CSS

    #zoom-toolbar {
      position: absolute;
      top: 0;
    }

    #zoom-container.zoomed-out {
      transition: transform 0.3s ease-in-out;
      transform: matrix(0.2, 0, 0, 0.2, 0, 0);
    }

    #zoom-container.zoomed-in {
      transition: transform 0.3s ease-in-out;
      transform: matrix(2, 0, 0, 2, 0, 0);
    }

从那里,您可以引入额外的 CSS 并测试后续更改是否中断。

我创建了一个CodePen example 来演示。

一篇关于平滑 CSS 过渡的好文章是here

【讨论】:

  • 使用类来转换事物是个好主意,但我不能使用它。该示例只是具有动态缩放级别的更大项目的开始。所以需要通过javascript添加变换矩阵。
  • 啊,我明白了。我建议修改您的问题和赏金 cmets 以反映此要求。
  • 只是为了测试您的想法是否可以提高转换性能,我更新了我的example script。但它甚至是滞后的。但与此同时,我发现了一些新东西(请参阅我最初问题下方的评论)。
  • @Johann Desktop Chrome 对我来说似乎很流畅,但在 Chrome 和 Firefox 移动版中滞后很明显。我怀疑图像大小/重量正在影响变换。尝试更小甚至更大的图像的案例...
【解决方案2】:

Greensock 插件是迄今为止我所见过的性能最好的插件。前段时间我进行了深入研究和一些测试,它是迄今为止最好的动画元素插件之一。

它轻巧、快速且易于使用。

性能怎么样?自己看吧:https://www.greensock.com/js/speed.html

这是您使用 gsap 库的示例:

var content = document.getElementById('zoom-container').children[0];

document.getElementById('zoom-in').addEventListener('click',
  function zoomIn() {
  TweenLite.to(content, 1.5, {scale:1});
  }, false);

document.getElementById('zoom-out').addEventListener('click',
  function zoomOut() {
  	TweenLite.to(content, 1.5, {scale:0.2});
  }, false);
* {
  margin: 0;
  padding: 0;
}

img {
  display: inline-block;
}

html,
body {
  height: 100%;
  width: 100%;
}
#zoom-container div {
  position: relative;
  /*some prefix*/-transform-origin: 0 0;
  transform-origin: 0 0;
}
#zoom-toolbar {
  position: absolute;
  top: 0;
  left: 0;
  
}

.zommIn {
  
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/gsap/1.19.0/TweenMax.min.js"></script>

  <div id="zoom-container" style="height:100%; width:100%;">
    <div>
      <img src="http://placehold.it/1000x1500" />
    </div>
  </div>

  <div id="zoom-toolbar">
    <button id="zoom-in">Zoom in</button>
    <button id="zoom-out">Zoom out</button>
  </div>

【讨论】:

  • 嗨,我创建了一个fiddle 来在移动 Chrome 上测试它。我可以看到 CSS 过渡和插件过渡之间的区别。使用该插件,过渡的结尾看起来更好,但总的来说似乎更加颠簸。不幸的是,它并不顺利。
【解决方案3】:

http://jsfiddle.net/wsgfz/5/

  **Transformations seem to work better than transitions in Chrome. Try this:**
        The flickering effect one quick mouse in/out should be gone too now.  

【讨论】:

  • 如果我错了,请纠正我,但我认为我需要一个过渡来为转换设置动画。而且你还在你的小提琴中使用了一个过渡。您使用背景图像缩放 div。我可以使用您小提琴中的哪个部分来改善我的转型过渡?请随时更新我的​​小提琴。
【解决方案4】:

你可以

  • 尝试将will-change: transform 放在容器元素上。
  • 制作容器元素position: relative 和图像position: absoulte 并完全填充容器。浏览器每帧的计算量可能会更少。

【讨论】:

【解决方案5】:

我在 chrome 中试用了您的代码,转换肯定滞后。 是的,您的代码有问题,坦率地说,这很简单。 只需在第一次转换后再次编写转换,但在其开头添加前缀 -webkit-

请注意,-webkit- 仅适用于 Android、Google 和 Safari。
-moz- 适用于 Mozilla Firefox。
-o- 适用于 Opera。
-ms- 适用于 Internet Explorer

【讨论】:

  • 您好,感谢您的回复。我检查了您的改进(请参阅jsfiddle.net/sd4f2cdj/2),但没有任何改变。我很确定 Chrome 支持无前缀的 transitiontransform 属性已经有一段时间了。
  • 抱歉。我的意思是变换
  • 感谢您的更新。你检查过我的小提琴吗?不幸的是,我添加了 transform 前缀但没有成功。
猜你喜欢
  • 1970-01-01
  • 2020-07-16
  • 2018-08-29
  • 1970-01-01
  • 2021-11-27
  • 1970-01-01
  • 1970-01-01
  • 2014-08-01
  • 2021-09-23
相关资源
最近更新 更多