从之前在类似方面提出的问题,我可以推断,由于Javascript是单线程的,可能会考虑像setTimeout这样的方法,但是我似乎没有得到任何渐进的结果。我的任务涉及DOM操作,所以我可以不依赖于HTML5 Web Workers
这里的问题是绘制统计操作的大数据集,例如Resampling.For我们使用d3库,在一般说明中,它接受整个数据集并计算图表的各种参数,如箱数,围绕冗长循环的一种方法是将数据集分解为更小的块,但仍然必须立即传递整个数据集以计算作为瓶颈的参数。
我所指的一个很好的例子是用于生成github存储库的图形(例如,https://github.com/mbostock/d3/graphs/contributors)。我们可以看到绘图操作尽管是密集的但不会干扰浏览器任务。关于如何处理类似线路的任何线索?
答案 0 :(得分:2)
(我不确定您链接的图表是否适合作为密集型任务,但无论如何)
通过使用超时分解任务,我获得了很好的结果。说你正在做这样的事情:
var largeSelection = d3.selectAll('svg circle')
.data(aReallyLargeDataset);// Expensive Bind Operation
largeSelection.enter()
.append('circle')// Lots of appending
.attr('r', function() { /* expensive calculations */ return ... });
largeSelection// Many refreshes
.attr('cx', function() { /* more expensive calculations */ return ... });
这可能需要浏览器1秒渲染(很长一段时间,考虑到在此任务期间所有内容都将被冻结)。你可以通过这样分解来改善它:
setTimeout(function() {
var largeSelection = d3.selectAll('svg circle')
.data(aReallyLargeDataset);// Expensive Bind Operation
setTimeout(function() {
largeSelection.enter()
.append('circle')// Lots of appending
.attr('r', function() { /* expensive calculations */ return ... });
setTimeout(function() {
largeSelection// Many refreshes
.attr('cx', function() { /* more expensive calculations */ return ... });
}, 100);
}, 100);
}, 100);
对于令人讨厌的筑巢和超时感到抱歉。您可以以更具可读性/可扩展性的方式重构/抽象它。在任何情况下,以这种方式分解任务使浏览器有机会“呼吸”并更新DOM,从而从用户的角度来看,应用程序看起来并不“卡住”。
如果仍然感觉迟钝,你可以进一步分解:
var entering = largeSelection.enter()
.append('circle');// Lots of appending
setTimeout(function() {
entering.attr('r', function() { /* expensive calculations */ return ... });
}, 100);