1

以前に似たような質問をしたところによると、Javascript はシングル スレッドであるため、setTimeout などのメソッドが考慮される可能性がありますが、プログレッシブな結果が得られないようです。私のタスクには DOM 操作が含まれているため、信頼できませんHTML5 Web ワーカーについて

ここでの問題は、リサンプリングなどの統計操作のために大きなデータセットをプロットすることです。これには、データセット全体を取り込み、ビンの数、スケールなどのグラフのさまざまなパラメーターを計算する一般的な注意事項で、d3 ライブラリを使用します。長いループを回避する 1 つの方法は、データセットを小さなチャンクに分割することですが、ボトルネックであるパラメーターの計算のために、データセット全体を一度に渡す必要があります。

私が言及していることの良い例は、github リポジトリ (例: https://github.com/mbostock/d3/graphs/contributors )のグラフを生成するために使用されていることです。集中的なタスクであるにもかかわらず、ブラウザで。同様の行で作業する方法についての手がかりはありますか?

4

1 に答える 1

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);
于 2012-11-09T19:33:09.090 に答える