title: D3 js background tab freeze while rendering to canvas
body: <p>I'm facing an issue with D3.js. When rendering data to canvas the tab freezes when it being inactive. It easily become noticeable after several minutes of tab being in a background.</p>
  
  <p>I've created an <a href="https://jsfiddle.net/mercat618/4jv0bqns/61/" rel="noreferrer">example JSFiddle</a> to reproduce the issue, it can be easily be done on local environment as well, source code follows.</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>(() =&gt; {
    // data container script
    $(() =&gt; {
      let $dataContainer = $('.data');
      setInterval(() =&gt; {
        $dataContainer.empty();
        let numbers = [];
        for (let i = 0; i &lt; 10; i++) {
          let randNumber = Math.floor(Math.random() * 100);
          numbers.push(randNumber);
          $dataContainer.append(`&lt;p&gt;${randNumber}&lt;/p&gt;`);
        }
        $(document).trigger('data:updated', [numbers])
      }, 1000);
    });
  
    // actual canvas render
    $(() =&gt; {
      // boring stuff
      let base = d3.select(".viz");
      let chart = base.append("canvas")
        .attr("width", 400)
        .attr("height", 300);
  
      let context = chart.node().getContext("2d");
  
      let detachedContainer = document.createElement("custom");
      let dataContainer = d3.select(detachedContainer);
    
      // d3 stuff and data binding
      let drawCustom = (data) =&gt; {
        let scale = d3.scale.linear()
          .domain(d3.extent(data))
          .range([10, 280]);
  
        let dataBinding = dataContainer.selectAll("custom.rect")
         .data(data, (d) =&gt; { return d; });
  
        dataBinding.enter()
          .append("custom")
          .classed("rect", true)
          .attr("size", 0)
          .attr("x", 11)
          .attr("y", scale)
          .transition()
          .duration(500)
          .attr("size", 8)
          .attr("fillStyle", "red");
  
        dataBinding.exit()
          .transition()
          .duration(500)
          .attr("size", 0)
          .remove()
      }
    
      let drawCanvas = () =&gt; {
        // clear canvas
        context.fillStyle = "#fff";
        context.rect(0,0,chart.attr("width"),chart.attr("height"));
        context.fill();
  
        let elements = dataContainer.selectAll("custom.rect");
        elements.each(function(d) {
          let node = d3.select(this);
  
          context.beginPath();
          context.fillStyle = node.attr("fillStyle");
          context.rect(node.attr("x"), node.attr("y"), node.attr("size"), node.attr("size"));
          context.fill();
          context.closePath();
  
        });
      }
    
      $(document).on('data:updated', (e, numbers) =&gt; {
        drawCustom(numbers);
      });
      
      d3.timer(drawCanvas);
    });
  })();</code></pre>
  <pre class="snippet-code-css lang-css prettyprint-override"><code>.data {
    outline: 1px solid #777777;
    min-width: 10px;
    height: 300px;
    background-color: rgb(238, 238, 238);
    display: inline-block;
    vertical-align: top;
    
  }
  
  p {
    margin: 0.7em;
  }
  
  .viz {
    display: inline-block;
  }
  
  canvas {
    outline: 1px solid #777777;
  }</code></pre>
  <pre class="snippet-code-html lang-html prettyprint-override"><code>&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"&gt;&lt;/script&gt;
  &lt;script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"&gt;&lt;/script&gt;
  &lt;div class="data"&gt;&lt;/div&gt;
  &lt;div class="viz"&gt;&lt;/div&gt;</code></pre>
  </div>
  </div>
  </p>
  
  <p>I want the rendering be seamless. What can be done in this case? I believe it may be something to do with <code>d3.timer</code> function, but may be wrong.</p>