开发者

Sparkline rendering is slow and hangs browser

开发者 https://www.devze.com 2022-12-30 23:37 出处:网络
Sparklines are awesome for doing little inline graphs. However, if the container they are in is hidden, you can\'t simply draw them behind the scenes and then show them. You must first display the con

Sparklines are awesome for doing little inline graphs. However, if the container they are in is hidden, you can't simply draw them behind the scenes and then show them. You must first display the container and then call the $.sparkline_display_visible method.

This is ok, except that it's really slow if you have a lot of graphs. I have a little over 200 graphs (and will eventually scale to more) to开发者_开发技巧 render and it takes around 4000ms to render them all, hanging the browser. Does anyone know how to either speed up this process (doubtful) or improve perceived performance by not hanging the browser? I tried to add a timer so each graph would show up one at a time while being rendered, but that still takes a while with 200+ graphs and the effect is a bit distracting to the user.

Thanks


You could have the plugin render the graph for the ones that are visible on load then loop through the hidden ones and have it render those in groups of 10. Will make it so the browser doesn't hang and will "pre-render" the hidden ones before you need them.

var sparklines = $('.inlinesparkline').sparkline();
var hidden = sparklines.parent().filter(':hidden').addClass('needsSparkline');

(function loopy(){
    var objs = hidden.filter(':lt(10)').removeClass('needsSparkline');
    hidden = hidden.filter('.needsSparkline');
    if (objs.length) {
        objs.css({
            'display':'',
            'visibility':'hidden'
        });
        $.sparkline_display_visible();
        objs.css({
            'display':'none',
            'visibility':''
        });
        hidden.length && setTimeout( loopy, 250 );
    }
})();


Solution for not hang browser with rendering sparklines is to call it async (with offset time setting events to queue). See sample:

var sparklinesGantt = new Array();
var sprklGanttCounter = 0;
var sprklBlockQuickShow = 20; // sync elements count
var sprklBlockSofort = 15; // async elemenbts count quick show
var sprklBlockGroesse = 2; // block size for async

var renderGanttSparkline = function(obj) {
    $(obj).css('padding-right','0px').sparkline('html', {
        width: '100px',
        height: '16px',
        type: 'bullet',
        targetWidth: 2,
        performanceColor: '#d3d3d3',
        targetColor: '#ffa500',
        rangeColors: ['#d3d3d3', '#4169e1', '#d3d3d3']
    });
};
var renderGanttSparklineAtom = function() {
    var sprklCounterBlockNext = sprklGanttCounter + sprklBlockGroesse;
    for (var c = sprklGanttCounter;sprklGanttCounter<sprklCounterBlockNext;c++) {
        var obj = sparklinesGantt[sprklGanttCounter];
        sprklGanttCounter++;
        renderGanttSparkline(obj);
    }
    if (sprklGanttCounter < sparklinesGantt.length) {
        setTimeout(renderGanttSparklineAtom, 1);
    }
};
var ganttSparkline = function(id) {
    var selector = ".gantt_sprkl";
    if (id) {
        selector = "#"+id;
    }
    if ($(selector).size() < sprklBlockQuickShow) {
        renderGanttSparkline($(selector));
    } else {
        sparklinesGantt = jQuery.makeArray($(selector));
        sprklGanttCounter = 0;
        while (sprklGanttCounter<sprklBlockSofort) {
            var obj = sparklinesGantt[sprklGanttCounter];
            sprklGanttCounter++;
            renderGanttSparkline(obj);
        }   
        setTimeout(renderGanttSparklineAtom, 1);
    }
};
$(document).ready(function() {
    ganttSparkline();
});

Bye

here is the testing page


You can easily avoid hanging the browser by not doing them all at the same time. It is usually OK to render graphs asynchronously when they come into the viewport.

See http://mleibman.github.com/SlickGrid/examples/example10-async-post-render.html for a working example.

0

精彩评论

暂无评论...
验证码 换一张
取 消