Спарклайн рендеринг медленный и зависает браузер
Спарклайны отлично подходят для создания маленьких встроенных графиков. Однако, если контейнер, в котором они находятся, скрыт, вы не можете просто нарисовать их за кулисами, а затем показать их. Сначала вы должны отобразить контейнер, а затем вызвать $.sparkline_display_visible
метод.
Это нормально, за исключением того, что это очень медленно, если у вас много графиков. У меня есть чуть более 200 графиков (и, в конечном итоге, они будут масштабированы до большего) для рендеринга, и на их рендеринг уходит около 4000 мс, вешая браузер. Кто-нибудь знает, как ускорить этот процесс (сомнительно) или улучшить воспринимаемую производительность, не вешая браузер? Я попытался добавить таймер, чтобы каждый график отображался по одному во время рендеринга, но это все же занимает некоторое время с 200+ графиками, и эффект немного отвлекает пользователя.
Спасибо
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 );
}
})();
Решение для не зависания браузера с рендерингом спарклайнов заключается в том, чтобы назвать его асинхронным (со смещением времени, устанавливающим события в очередь). Смотрите образец:
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();
});
до свидания
Вы можете легко избежать зависания браузера, не выполняя их все одновременно. Обычно нормально отображать графики асинхронно, когда они попадают в область просмотра.
См. http://mleibman.github.com/SlickGrid/examples/example10-async-post-render.html для рабочего примера.