Рендеринг Sparkline работает медленно и зависает в браузере

Спарклайны отлично подходят для создания небольших встроенных графиков. Однако, если контейнер, в котором они находятся, скрыт, вы не можете просто нарисовать их за кулисами, а затем показать. Вы должны сначала отобразить контейнер, а затем вызвать метод $.sparkline_display_visible.

Это нормально, за исключением того, что это очень медленно, если у вас много графиков. У меня есть чуть более 200 графиков (и в конечном итоге я буду увеличивать их количество) для рендеринга, и для их рендеринга требуется около 4000 мс, что приводит к зависанию браузера. Кто-нибудь знает, как ускорить этот процесс (сомнительно) или улучшить воспринимаемую производительность, не зависая в браузере? Я попытался добавить таймер, чтобы каждый график отображался по одному во время рендеринга, но это все равно занимает некоторое время с более чем 200 графиками, и эффект немного отвлекает пользователя.

Спасибо


person Jason    schedule 18.05.2010    source источник


Ответы (3)


Вы можете заставить плагин отображать график для тех, которые видны при загрузке, а затем перебирать скрытые и отображать их в группах по 10. Это сделает так, чтобы браузер не зависал, и будет «предварительно отображать» скрытые, прежде чем они вам понадобятся.

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 );
    }
})();
person PetersenDidIt    schedule 18.05.2010
comment
да, я тоже думал, что это сработает, за исключением того, что он не может рисовать, если холст скрыт :\ предварительный рендеринг не работает с этим плагином - person Jason; 19.05.2010
comment
jsfiddle.net/HvQ5f — попробуйте код, думаю, вы обнаружите, что он будет работать, если вы удалите display:none и добавьте visibility:hidden во время предварительного рендеринга. - person PetersenDidIt; 19.05.2010
comment
интересно. я определенно дам этому водоворот. - person Jason; 23.06.2010
comment
я дам вам согласие, потому что это действительно работает и действительно помогает. тем не менее, это все еще занимает forEVER, когда у вас есть большое количество графиков и все еще зависает браузер. - person Jason; 29.06.2010

Решение, позволяющее не зависать браузеру с рендерингом спарклайнов, состоит в том, чтобы назвать его асинхронным (со смещением времени, устанавливающим события в очередь). См. образец:

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();
});

до свидания

вот страница тестирования

person Kaster    schedule 07.11.2012

Вы можете легко избежать зависания браузера, не выполняя их все одновременно. Обычно нормально рендерить графики асинхронно, когда они попадают в окно просмотра.

См. http://mleibman.github.com/SlickGrid/examples/example10-async-post-render.html для рабочего примера.

person Tin    schedule 16.12.2010