Question

I've got a page that is playing an HTML5 video in a loop. As you scroll down the page, jQuery adds a class to the nav element. CSS then applies a transition to the left property of th. In Firefox it's working well enough, but Chrome stutters the animation and fails to complete it unless you continue scrolling.

I'm aware there are lots of performance issues with Chrome and HTML5 video. Like this But I haven't found a great solution.

Removing the background video causes smooth animations in Chrome. But, it's not a terribly heavy video (360p, ~1MB) I'm wondering if there is some better way to apply the class or perform the animation than I'm doing that might help Chrome with it's performance.

Here is a link to the in-progress site (It's mostly un-styled, so please don't hate :)

My Project

My HTML

<!-- Left Bar Menu -->
<div class="leftbar scrollHandle">
</div>

<!-- Contains Header Video on Loop -->
<div class="videocontainer">
<video class="videobackground" poster="{{ "assets/video/poster.jpg" | asset_url }}" autoplay="true" loop="true">
    <source type="video/mp4" src="{{ "assets/video/360.mp4" }}" />
    <source type="video/webm" src="{{ "assets/video/360.webm" }}" />
</video>
</div>

My Javascript:

var containerPosition = $( ".container" ).offset();

$( window ).scroll(function() {
if ( $( window ).scrollTop() > containerPosition.top ) {
    $( ".scrollHandle" ).addClass( "show" );
} else {
    $( ".scrollHandle" ).removeClass( "show" )
};
});

My CSS:

.leftbar {
position: fixed;
top: 0;
left: -$leftbarwidth;
transition: left 500ms;
z-index: 2;
width: $leftbarwidth;
height: 100%;
background-color: $grey;
&.show {
    left: 0;
    transition: left 500ms;
}
}
Was it helpful?

Solution

The entire screen is painting on every scroll.

This is caused (in your case) by having fixed elements on your page. A fixed element will cause a paint on every scroll because the fixed element stays in place and the content underneath moves causing the browser to have to repaint the screen in order to display the content properly.

Painting

In the painting stage, the render tree is traversed and the renderer's "paint()" method is called to display content on the screen. Painting uses the UI infrastructure component.
source

There are a few things you can do:

  1. Keep your video contained to your div and in the top part of the page by making the container not fixed.
  2. Use less fixed element if you can.
  3. Use css transforms translate() instead of a transition on position.
  4. Promote fixed elements to their own layer with translateZ(0); or css will-change

code with performance in mind

.leftbar {
    position: fixed;
    top: 0;
    left: -$leftbarwidth;
    z-index: 2;
    width: $leftbarwidth;
    height: 100%;
    background-color: $grey;
    
    /* for performance improvements: */
    -webkit-transition: -webkit-transform 0.5s ease;
    -webkit-transform: translateZ(0); /* promotes to a layer */
    &.show {
        -webkit-transform: translate3d($leftbarwidth, 0, 0);
    }
}

Promoting elements to layers

Promoting elements to their own layers will kick in hardware accelaration instead of using the CPU, if an fixed element has its own layer it will also not repaint the screen on every scroll.

-webkit-transform: translateZ(0); /* promotes to a layer */

Performance before and after.

I've change the code live on the site in the developer tools in chrome, after some small css changes we go from <30 to 60fps, heres the charts:

Before:

before

After:

after

You go from <30fps to a steady 60fps after losing some fixed elments, containing the video to its div, promoting layers and using translate() instead of position: left on transitions.

Keep in mind that you don't want to put everything on a layer, since using this too much will also affect your performance. So use in moderation

Closing notes

I'm aware there are lots of performance issues with Chrome and HTML5 video...

I do not agree with you on this, if you code your site with performance in mind you will have better or great performance, even if there are native performance issues (which i don't think html5/chrome have. correct me if i'm wrong)

Links for further reading:

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top