(あなたがリンクしたグラフが集中的なタスクとみなされるかどうかはわかりませんが、関係ありません)
タイムアウトを使用してタスクを分割することで、良い結果が得られました。次のようなことをしているとします。
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);