Reputation: 559
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 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;
}
}
Upvotes: 2
Views: 4891
Reputation: 1659
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
fixed
.translate()
instead of a transition on position
.translateZ(0);
or css will-change.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 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 */
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:
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
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)
Upvotes: 9