Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why CSS transition lags in mobile Chrome?

During my work on a CSS image zooming feature I encountered a performance problem in mobile Chrome.

Description: If I try to scale images by adding the CSS transform property directly to the image everything works well. The zooming transition is smooth like butter with 60fps (JSFiddle).

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

The Problem: But if I wrap the image in a div container and try to transform the container the transition is very laggy (JSFiddle). The transition starts with a big delay and isn't smooth. It seems to be a mobile Chrome only problem because it doesn't happen in other browsers like Firefox on Android, just on my mobile device (Nexus 5) and some other Android devices.

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

Does someone know whats wrong with the CSS or HTML structure?

like image 677
Johann Avatar asked Oct 18 '16 11:10

Johann


People also ask

Does CSS animation affect performance?

TL;DR # Take care that your animations don't cause performance issues; ensure that you know the impact of animating a given CSS property. Animating properties that change the geometry of the page (layout) or cause painting are particularly expensive. Where you can, stick to changing transforms and opacity.

Which delay CSS property is used for transition effect?

The transition-delay property specifies when the transition effect will start. The transition-delay value is defined in seconds (s) or milliseconds (ms).

What triggers CSS transition?

Triggering transitions You can trigger CSS transitions directly with pseudo classes like :hover (activates when the mouse goes over an element), :focus (activates when a user tabs onto an element, or when a user clicks into an input element), or :active (activates when user clicks on the element).

What is CSS transition used for?

CSS transitions provide a way to control animation speed when changing CSS properties. Instead of having property changes take effect immediately, you can cause the changes in a property to take place over a period of time.


2 Answers

Greensock plugin is by far the best in terms of performance I've seen. Some time ago I make a deep study and some tests, and it's been by far, one of the best plugins to animate elements.

It's lightweight, fast and easy to use.

What about performance? Take a look on your own: https://www.greensock.com/js/speed.html

Here's your example using gsap library:

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>
like image 167
Jordi Flores Avatar answered Oct 04 '22 14:10

Jordi Flores


Use JavaScript to set classnames, but let CSS completely handle the transitions and trigger GPU acceleration.

I would suggest using the onclick HTML event attribute, to set triggers for two functions, zoomIn and zoomOut.

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>

You now have two functions, that set desired CSS classnames.

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';
    };

To achieve the desired animation, the CSS can now be much simpler as well.

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);
    }

From there, you can introduce additional CSS and test whether subsequent changes are breaking.

I've created a CodePen example to demonstrate.

A good article on smooth CSS transitions is here.

like image 38
jacefarm Avatar answered Oct 04 '22 15:10

jacefarm