How to optimize an image sequence in Chrome?


Tags: jquery,css,jquery-ui,google-chrome,background-size

Problem :

On a website, I have a slider (I'm using jQuery UI's slider) that is used to control an image sequence. The images are displayed full screen in the background of the page (I'm using background-size: cover). On my development PC, it's working perfectly but when I try it on less powerful computers, it's laggy.

The way I do my sequence is quite simple. Here's some of my code to give a general idea of what I'm doing. (I think that code is not essential for my question, but I added it anyway... Feel free to skip ahead!)

HTML:

<div id="animation">
    <div class="frame frame0"></div>
    <div class="frame frame1"></div>
    <div class="frame frame2"></div>
    [...]
    <div class="frame frame20"></div>
</div>

CSS:

#animation {
    height: 100%;
    position: relative;
    width: 100%;
}
#animation div.frame {
    background-position: center center;
    background-size: cover;
    bottom: 0;
    left: 0;
    position: absolute;
    right: 0;
    top: 0;
    z-index: 1;
}
#animation div.frame.active { z-index: 2; }
#animation div.frame0 { background-image: url(frame0.jpg); }
#animation div.frame1 { background-image: url(frame1.jpg); }
[...]
#animation div.frame20 { background-image: url(frame20.jpg); }

jQuery:

var $frames = $('#animation').find('div.frame');
$('#slider').slider({
    value: 1,
    min: 1,
    max: 21,
    step: 1,
    slide: function(event, ui){
        $frames.removeClass('active').filter(':eq(' + (ui.value - 1) + ')').addClass('active');
    }
});

By testing different things, I managed to isolate what it causing performance issues in Chrome. The culprit is background-size: cover. As soon as I remove the background-size attribute and use the images default size, I have close to no lag.

When I use background-size: cover and my images are about the same size as my Chrome window, the performance is better. But the larger the images are stretched (or compressed) relative to the original image size, the more lag I get.

The only lead I have so far to optimize this is to have different image sizes and use JavaScript to load the sequence in the size that is closer to the browser window and hope that it won't be laggy. And this mean that I may have to reload another image kit if the user resizes the browser window.

Any idea how I could optimize the image sequence in Chrome to get better performance?



Solution :

I did a test today using a canvas instead of a list of HTML elements for each frame. It results in a very good performance in Chrome. The downside of the the canvas solution is that it's not working in IE8 but for this project, we have a lot more users on Chrome than on IE8 so I can live with that.

This helped me with the canvas drawing: Frame by frame animation in HTML5 with canvas

And the rest was to simply modify the canvas on the slider change instead of adding and removing the active class.

var arrFrames = [];
for(var i = 0; i < 21; i++){
    arrFrames[i] = new Image();
    arrFrames[i].onload = function() { /* check that all images are loaded before allowing the animation on the slider */ }
    arrFrames[i].src = 'frame' + i + '.jpg';
}

$('#slider').slider({
    value: 0,
    min: 0,
    max: 20,
    step: 1,
    slide: function(event, ui){
        /* Calculate image size and ratio */
        ctx.clearRect(0, 0, iCanvasWidth, iCanvasHeight);
        ctx.drawImage(arrFrames[ui.value], 0, 0, iWidth, iHeight);
    }
});

I didn't put all variable definitions in the code to keep it short and clean, but the variable names should be clear enough to understand what value they have.

One important thing I realized: don't forget to set width and height for the canvas in javascript. Setting it only in CSS will only stretch it.


    CSS Howto..

    How to change font size of the first option tag in a dropdown menu (select)?

    CSS style not showing on print preview

    How do I create bookmarklet to overlay html/div layer and CSS from external file

    How CSS property “opacity” renders in browsers (IE, Chrome, Firefox, Opera)?

    How to Vertically Center Images on a Line?

    How to use text-overflow properly to format text?

    How to add & show 4d image in web site with css

    How can I mimic Leaflet.Draw tooltip style with a different tooltip plugin?

    How to set two elements on the same line using CSS

    How to Rotate Text and have it's Parent Div act Dynamically

    How to Modify the StrongLoop's LoopBack Explorer CSS

    How to make content fill space inside
    tag in html?

    Parsing erb within erb in a view. How to add CSS class?

    How to make menu bar with nested submenu css

    How can i make a div to slide in from right side to left?

    How to achieve this header with html and css?

    how fix bug with white lines between the cells of the table in IE11

    In GWT, how can I override DisclosurePanel's CSS using or ClientBundle

    How can you print a page that has been altered by javascript?

    how to set transform for div without effect on background image?

    How to load an image with css using Django

    How to fix hover on transparent photo

    How to set width of all elements in a table column with CSS

    CSS - How to align drop-down sub menu to the parent's right?

    How to select the second th into the thead of a table having a specific ID using CSS?

    How to toggle css visibility with Javascript

    How to use CSS to create the left - right alignment so the left div does not push the right div

    How to centering a form

    CSS Background Color Not Showing

    How to make css smaller?