Skip to content
Student Login

Livecoding #13: rendering React components with canvas

Last updated: June 2016 👉 livestreamed every last Sunday of the month. Join live or subscribe by email 💌

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/

[embed]http://imgur.com/w7nSJGI

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}>
<layer>
<particles particles={this.props.particles}></particles>
</layer>
</stage>

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.

<group>
{particles.map(particle =>
<circle radius="1.8" x={particle.x} y={particle.y} key={particle.id} fill="black">
)}
</circle></group>

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

[embed]http://imgur.com/X9a7hzp

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.

?

Yikes.

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.

About the Author

Hi, I’m Swizec Teller. I help coders become software engineers.

Story time 👇

React+D3 started as a bet in April 2015. A friend wanted to learn React and challenged me to publish a book. A month later React+D3 launched with 79 pages of hard earned knowledge.

In April 2016 it became React+D3 ES6. 117 pages and growing beyond a single big project it was a huge success. I kept going, started live streaming, and publishing videos on YouTube.

In 2017, after 10 months of work, React + D3v4 became the best book I'd ever written. At 249 pages, many examples, and code to play with it was designed like a step-by-step course. But I felt something was missing.

So in late 2018 I rebuilt the entire thing as React for Data Visualization — a proper video course. Designed for busy people with real lives like you. Over 8 hours of video material, split into chunks no longer than 5 minutes, a bunch of new chapters, and techniques I discovered along the way.

React for Data Visualization is the best way to learn how to build scalable dataviz components your whole team can understand.

Some of my work has been featured in 👇

Created bySwizecwith ❤️