This is a Livecoding Recap – an almost-weekly post about interesting things discovered while livecoding. It’s shorter than 500 words, and there are pictures! You can follow my channel here. New content almost every Sunday at 2pm PDT. There’s live chat. Come hang out. ?

This Sunday was all about rendering React components with canvas and smoothly animating 10k+ circles.

We did it! Well, the canvas part. The smooth animation part … not so much. Turns out that part’s hard.

It all started with some tedious coding to update the React particles experiment to D3 v4. Some idiot (me) had had the bright idea of changing that and not finishing the transition.

With the release candidate version of D3v4, importing the entire library no longer works. From now on, you have to do something like import { randomNormal } from 'd3' to get specific bits and pieces. This is tedious, but it produces smaller bundles in the end. All in all, it’s better this way.

Our slow implementation was back. \o/

View post on

Then we turned to react-konva, “a JavaScript library for drawing complex canvas graphics using React.” In theory, we should be able to render our particles using HTML5 canvas without changing our code too much.

It’s based on the Konva library, which looks like a sort of D3 for canvas. It gives you a bunch of useful abstractions to make 2d graphicsing easier.

To my surprise, the conversion was simple.

We had to change our main render method to use a Konva Stage instead of an <svg> node:

<Stage width={this.props.svgWidth} height={this.props.svgHeight}>
       <Particles particles={this.props.particles} />

We also wrapped it in a big <div> to help D3 detect the mouse events we need for particle generation. Yes, we could have moved away from D3 for those, but it was already coded up, so why change?

We had to change the Particles render method to use Konva’s Circle component.

   { =>
      <Circle radius="1.8" x={particle.x} y={particle.y} key={} fill="black" />

Things Just Worked™. Kind of. Our animation looked less than smooth, even with just 200 particles. With a few thousand, it was comically bad.

View post on

Not cool, React. Not cool. Canvas is supposed to be super fast! Maybe this is a bit faster than the SVG approach? It’s hard to tell.

We did some profiling and discovered that calculating a new frame takes only 7 milliseconds. Flushing those changes to React components … heh … that took anywhere from 200ms to 980ms.



The culprit seems to be a function called updateChildren deep in the bowels of React.

We’ll find a workaround on Sunday the 10th of July. There are several promising venues to explore, anything from using better Konva components (FastLayer is a thing) to avoiding prop updates as the driver of our animation. Somehow. We’ll figure it out.

See you next time.

PS: the edited and improved versions of these videos are becoming a video course. Readers of the engineer package of React+d3js ES6 get the video course for free when it’s ready.

Learned something new? Want to become a better engineer? 💌

Join 9,400+ people just like you already improving their skills.

Here's how it works 👇

Leave your email and I'll send you an Interactive Modern JavaScript Cheatsheet 📖 right away. After that you'll get a thoughtfully written email every week about React, JavaScript,  and lessons learned in my 20 years of writing code for companies ranging from tiny startups to Fortune5 behemoths.

Man, I love your way of writing these newsletters. Often very relatable and funny perspectives about the mundane struggles of a dev. Lightens up my day. ~ Kostas

PS: You should also follow me on twitter 👉 here.
It's where I go to shoot the shit about programming.