Why isn't my CSS3 animation smooth in Google Chrome (but very smooth on other browsers)?

43.6k Views Asked by At

MY ENVIRONMENT (WHERE I GET THE LAG):

Mac OSX El Capitan 10.11.2 on Chrome Version 50.0.2661.102 (64-bit)

CODEPEN:

http://codepen.io/vieron/pen/hnEev


ANIMATION:

enter image description here


SITUATION:

I googled this a lot without finding anything that works for me. I know this questions has been asked before.

The CSS3 animation is smooth on my Mac when I open the website with Safari and Firefox, but not with Chrome!

Strangely enough, the original CodePen is smooth on Chrome.


PROBLEM:

Something in my code is causing the animation to be choppy only on Chrome. What is it and how can I fix it ?


WHAT I LOOKED AT:

I need my positioning to be relative to adapt to different screen sizes.


CODE:

HTML

<div class="marquee">
    <ul>
        <li>
            <a href="https://developer.apple.com/swift/"><img class="marquee-itm" src="Vendors/Images/Apple_Swift_Logo.png" /></a>
            <a href="https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html"><img class="marquee-itm" src="Vendors/Images/Objective-c-logo.png" /></a>
            <a href="https://developer.apple.com/swift/"><img class="marquee-itm" src="Vendors/Images/Apple_Swift_Logo.png" /></a>
            <a href="https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html"><img class="marquee-itm" src="Vendors/Images/Objective-c-logo.png" /></a> 
            <a href="https://developer.apple.com/swift/"><img class="marquee-itm" src="Vendors/Images/Apple_Swift_Logo.png" /></a>
            <a href="https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html"><img class="marquee-itm" src="Vendors/Images/Objective-c-logo.png" /></a> 
            <a href="https://developer.apple.com/swift/"><img class="marquee-itm" src="Vendors/Images/Apple_Swift_Logo.png" /></a>
            <a href="https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html"><img class="marquee-itm" src="Vendors/Images/Objective-c-logo.png" /></a>
        </li>
        <li>
            <a href="https://developer.apple.com/swift/"><img class="marquee-itm" src="Vendors/Images/Apple_Swift_Logo.png" /></a>
            <a href="https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html"><img class="marquee-itm" src="Vendors/Images/Objective-c-logo.png" /></a>
            <a href="https://developer.apple.com/swift/"><img class="marquee-itm" src="Vendors/Images/Apple_Swift_Logo.png" /></a>
            <a href="https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html"><img class="marquee-itm" src="Vendors/Images/Objective-c-logo.png" /></a> 
            <a href="https://developer.apple.com/swift/"><img class="marquee-itm" src="Vendors/Images/Apple_Swift_Logo.png" /></a>
            <a href="https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html"><img class="marquee-itm" src="Vendors/Images/Objective-c-logo.png" /></a> 
            <a href="https://developer.apple.com/swift/"><img class="marquee-itm" src="Vendors/Images/Apple_Swift_Logo.png" /></a>
            <a href="https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html"><img class="marquee-itm" src="Vendors/Images/Objective-c-logo.png" /></a> 
        </li>
        <li>
            <a href="https://developer.apple.com/swift/"><img class="marquee-itm" src="Vendors/Images/Apple_Swift_Logo.png" /></a>
            <a href="https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html"><img class="marquee-itm" src="Vendors/Images/Objective-c-logo.png" /></a>
            <a href="https://developer.apple.com/swift/"><img class="marquee-itm" src="Vendors/Images/Apple_Swift_Logo.png" /></a>
            <a href="https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html"><img class="marquee-itm" src="Vendors/Images/Objective-c-logo.png" /></a> 
            <a href="https://developer.apple.com/swift/"><img class="marquee-itm" src="Vendors/Images/Apple_Swift_Logo.png" /></a>
            <a href="https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html"><img class="marquee-itm" src="Vendors/Images/Objective-c-logo.png" /></a> 
            <a href="https://developer.apple.com/swift/"><img class="marquee-itm" src="Vendors/Images/Apple_Swift_Logo.png" /></a>
            <a href="https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/ProgrammingWithObjectiveC/Introduction/Introduction.html"><img class="marquee-itm" src="Vendors/Images/Objective-c-logo.png" /></a> 
        </li>
    </ul>
</div>

CSS

* {
  margin: 0;
  padding: 0;
}
@-webkit-keyframes loop {
  0% {
    -moz-transform: translateX(0);
    -ms-transform: translateX(0);
    -webkit-transform: translateX(0);
    transform: translateX(0);
  }
  100% {
    -moz-transform: translateX(-66.6%);
    -ms-transform: translateX(-66.6%);
    -webkit-transform: translateX(-66.6%);
    transform: translateX(-66.6%);
  }
}
@-moz-keyframes loop {
  0% {
    -moz-transform: translateX(0);
    -ms-transform: translateX(0);
    -webkit-transform: translateX(0);
    transform: translateX(0);
  }
  100% {
    -moz-transform: translateX(-66.6%);
    -ms-transform: translateX(-66.6%);
    -webkit-transform: translateX(-66.6%);
    transform: translateX(-66.6%);
  }
}
@-ms-keyframes loop {
  0% {
    -moz-transform: translateX(0);
    -ms-transform: translateX(0);
    -webkit-transform: translateX(0);
    transform: translateX(0);
  }
  100% {
    -moz-transform: translateX(-66.6%);
    -ms-transform: translateX(-66.6%);
    -webkit-transform: translateX(-66.6%);
    transform: translateX(-66.6%);
  }
}
@keyframes loop {
  0% {
    -moz-transform: translateX(0);
    -ms-transform: translateX(0);
    -webkit-transform: translateX(0);
    transform: translateX(0);
  }
  100% {
    -moz-transform: translateX(-66.6%);
    -ms-transform: translateX(-66.6%);
    -webkit-transform: translateX(-66.6%);
    transform: translateX(-66.6%);
  }
}
.cssanimations .marquee {
  position: relative;
  width: 90%;
  margin: auto;
  overflow: hidden;
}
.cssanimations .marquee > ul {
  list-style: none;
  position: relative;
  z-index: 1;
  top: 0;
  left: 0;
  width: 300% !important;
  height: 80px;
  -webkit-animation-play-state: running;
  -moz-animation-play-state: running;
  -o-animation-play-state: running;
  animation-play-state: running;
  -moz-transform: translate3d(0, 0, 0);
  -ms-transform: translate3d(0, 0, 0);
  -webkit-transform: translate3d(0, 0, 0);
  transform: translate3d(0, 0, 0);
  -webkit-animation: loop 20s linear infinite;
  -moz-animation: loop 20s linear infinite;
  -o-animation: loop 20s linear infinite;
  animation: loop 20s linear infinite;
}
.cssanimations .marquee > ul > li {
  white-space: normal;
  position: relative;
  text-align: justify;
  text-justify: distribute-all-lines;
  line-height: 0;
  letter-spacing: -0.31em;
  float: left;
  width: 33.333333%;
  overflow: hidden;
  height: 80px;
}
.cssanimations .marquee > ul > li:before {
  content: '';
  position: relative;
  height: 100%;
  width: 0;
}
.cssanimations .marquee > ul > li:before,
.cssanimations .marquee > ul > li > * {
  vertical-align: middle;
  display: inline-block;
}
.cssanimations .marquee > ul > li:after {
  content: '.';
  display: inline-block;
  height: 0 !important;
  width: 100%;
  overflow: hidden !important;
  visibility: hidden;
  font-size: 0;
  word-spacing: 100%;
}
.cssanimations .marquee > ul > li > * {
  display: inline-block;
  vertical-align: middle;
  text-align: left;
  line-height: 1;
  letter-spacing: 0;
}
.cssanimations .marquee > ul > li img {
  margin: 0 1.6%;
}


.marquee ul li a{
    display: inline-block; 
    height: 80%;
}

.marquee ul li a img {
    max-height: 100%;
}

JS LINKS IN THE HTML

<script src="Vendors/js/modernizr.js" type="text/javascript"></script>
<script src='http://cdnjs.cloudflare.com/ajax/libs/jquery/2.1.3/jquery.min.js'></script>

IMPORTANT N.B.:

Only thing I added to the CodePen:

.marquee ul li a{
    display: inline-block; 
    height: 80%;
}

.marquee ul li a img {
    max-height: 100%;
}

Removing this doesn't solve the issue.


EDIT 1:

Google Chrome Profiler (option 1):

enter image description here

Google Chrome Profiler (option 2 (Snapshot)):

enter image description here

EDIT 2:

CSS3 transition not smooth in Chrome

I seem to have just found a strange behaviour in my animation. It "grows" (gets larger) every time I move out of sight and back on it by scrolling.

This behaviour seems to be what is described in the answer to the question above. But specifying a fixed width like suggested didn't fix the lag.

EDIT 3:

Google Timeline (after removing gravity.js):

enter image description here

EDIT 4:

This is weird. After commenting and uncommenting some lines (basically going back to what the code was when there was lag), the animation performance became better. Not as smooth as in Safari or Firefox, but still smoother.

EDIT 5:

I found the "culprit".

I am using another codepen in my website's header :

https://codepen.io/saransh/pen/BKJun

<link href='http://fonts.googleapis.com/css?family=Lato:300,400,700' rel='stylesheet' type='text/css'>
#stars
#stars2
#stars3
#title
  %span
    PURE CSS
  %br
  %span
    PARALLAX PIXEL STARS

Removing it makes the other animation smooth.


NONETHELESS:

This doesn't explain why everything is smooth in Firefox and Safari but not in Chrome.

Is Chrome less powerful ?

I filed a report to Chrome and hope they will answer here but there is no guarantee.

If someone can get an answer from Google / Chrome on this, I award him/her the bounty.


UPDATE 6:

Tried on the Opera browser. Exactly the same lag ! Now we know it's a problem with the BLINK rendering engine !

8

There are 8 best solutions below

1
On BEST ANSWER

I found the "culprit".

I am using another codepen in my website's header :

https://codepen.io/saransh/pen/BKJun

<link href='http://fonts.googleapis.com/css?family=Lato:300,400,700' rel='stylesheet' type='text/css'>
#stars
#stars2
#stars3
#title
  %span
    PURE CSS
  %br
  %span
    PARALLAX PIXEL STARS

Removing it makes the other animation smooth.


NONETHELESS:

This doesn't explain why everything is smooth in Firefox and Safari but not in Chrome.

Is Chrome less powerful ?

I filed a report to Chrome and hope they will answer here but there is no guarantee.

If someone can get an answer from Google / Chrome on this, I award him/her the bounty.

UPDATE 6:

Tried on the Opera browser. Exactly the same lag ! Now we know it's a problem with the BLINK rendering engine !

1
On

I recently updated my Nvidia GPU driver and animations in Chrome became choppy, even though hardware acceleration was turned on.

What worked for me was reactivating hardware acceleration.

Google Chrome > Settings > Advanced > System > Use hardware acceleration when available

To reactivate the broken link, I turned off hardware acceleration, relaunched the browser. Here I noticed that animations were just at choppy as before. Then I turned on hardware acceleration again, relaunched the browser and hardware acceleration had been obviously reactivated once again as animations were now super smooth.

I assume updating the graphics driver broke Chrome's link to hardware acceleration and it simply needed to be reactivated.

0
On

I had exactly the same problem with my Linux pc with NViDIA card. After setting to NVIDIA on demand and rebooting it was solved. Strange thing is that the it is set again to performance mode. I guess the problem was with the card setting and not chrome.

1
On

SOLUTION:

Use absolute positioning with @media for different screen sizes.


EXPLANATION:

It works for all other browsers and not Chrome so whatever you do will be specifically for Chrome.

This gives you 3 options:

  • (1) get Google to fix Chrome or

  • (2) use a solution that will work with Chrome or

  • (3) accept it will not be smooth with Chrome.


TL;DR:

You know absolute positioning will work.

1
On

Chrome supports hardware acceleration when rendering, improving performance for css3 animations. You can trigger hardware acceleration by applying translateZ(0), rotateZ(360deg) or similar which tricks Chrome into it.

Once you're using hardware acceleration by applying the trick above (or if you were already using it, but the cited code sample was incomplete and/or a third party library was taking care of it for you), you can further improve performance by applying, with prefixes as needed:

backface-visibility: hidden;
perspective: 1000;

This also helps address some issues when the GPU is integrated and/or being throttled (think power-saving mode), and its performance degrades. This would explain issues with parallax performance on a macbook! ¯\_(ツ)_/¯

0
On

To make animations better you can use will-change property of CSS. This property hints the browser that the element is going to change.

https://developer.mozilla.org/en/docs/Web/CSS/will-change

You can read here more about will-change.

0
On

I know this is old, but if anyone should still stumble accross this post.

I also had the problem that my animations were smooth in Safari on iOS, but choppy in Google Chrome on iOS.

I fixed it with these lines of code:

@media screen and
  (prefers-reduced-motion: reduce), 
  (update: slow) {
  * {
    animation-duration: 0.001ms !important;
    animation-iteration-count: 1 !important; /* Hat tip Nick/cssremedy (https://css-tricks.com/revisiting-prefers-reduced-motion-the-reduced-motion-media-query/#comment-1700170) */
    transition-duration: 0.001ms !important;
  }
}

I got the code from here.

0
On

Try to disable your Chrome extensions (it had been the issue for me)

go to Chrome\Manage Extensions switch the toggle button to disable them, if it worked fine, then try to enable one by one, to know which exactly caused the problem.