
Flipboard releases React Canvas - jordwalke
https://github.com/flipboard/react-canvas
======
greggman
If rendering UI to a canvas fits your needs then by all means do it.

Just be aware that when it comes time to localize to other languages it starts
getting hard to support things like CJK where in order to properly work
there's an Input Method Editor
([http://i.imgur.com/JmmYwyi.gif](http://i.imgur.com/JmmYwyi.gif)) that needs
to be able to read the text. There's also cut/copy/paste which users can't do
from text on a canvas. There's also "define" which is built into OSX and iOS
(others?) letting the user select a word and look up its definition in the
dictionary. Finally I'm sure there are accessibility issues. And don't forget
right to left like Arabic.
([https://www.flickr.com/photos/u-e/2680759761/](https://www.flickr.com/photos/u-e/2680759761/))

UI in a game (the most common place to render a UI yourself) usually doesn't
care about these things. I'd hazard a guess though that most apps do. I know I
get really annoyed when I can't copy small pieces of text from a native app.
For example copying a link to a browser, copying a phone number to my phone,
copying an address to maps, etc.

In general DOM makes all of these just work.

~~~
mjjohnston
React Canvas author here. I outlined some of the reasons why it is not always
the right answer: [http://engineering.flipboard.com/2015/02/mobile-
web/#Practic...](http://engineering.flipboard.com/2015/02/mobile-
web/#PracticalApplications) On Flipboard we use DOM where appropriate for text
input and areas of the application where performance is less critical.

And to your point about accessibility: [https://github.com/flipboard/react-
canvas#accessibility](https://github.com/flipboard/react-canvas#accessibility)

You are correct that the DOM just works. But we need a better option on the
web in order to achieve the kinds of experiences that people have come to
expect from native applications. The hope is that by pushing the browser
beyond its limits that we can make progress in this area.

~~~
greggman
Please don't take this wrong. I think what you're doing is great. I like perf
too. I'm just kind of thinking outloud.

For example copy/paste and "define" require you to support selecting text on
your canvas and then telling the OS about it when the user picks "copy" or
"define". Otherwise you get the bad behavior that 99.99% of all native apps
have which is that they don't support selecting anything except in editable
textareas so if they display an address I can't copy it into maps.

You could argue the browser should add APIs so you can provide what the user
has selected to the OS but, it means every developer has to be perfect.
Developers who get it wrong end up making apps that don't follow any OS
conventions, don't handle the edge cases, don't handle things when running in
other languages, etc etc etc.

To take it to an extreme, maybe the browser should just be a rectangle of
pixels and JavaScript. No DOM whatsoever. Imagine we had that world. There'd
be no search engines and every page would have a totally unique UI. Some pages
you'd use the keyboard to move a cursor to select something. Others would use
the mouse. Still others might use a joystick. Some would require IJKL instead
of the cursor keys. None of them would have native OS widgets. They'd all use
a different font system. Most would probably only support ASCII and maybe ANSI
at best.

Instead we have HTML and a DOM and most of these issues are solved and that
uniformity has some arguable benefits.

I'm not saying stop your work. I'm just saying I'm there are trade offs. I
think an argument can be made either way. Maybe rather than going back to a
rect of pixels we should also be lobbying for ways to make the DOM better so
we can keep the good parts (universality?) and still do better?

~~~
buymorechuck
Understood. We just happened to have unconventional constraints that suggested
an unconventional solution. There are many ways to lobby for improvements for
things (especially Web standards) and perhaps with us showing the limitations
of the DOM, we can influence change for the better.

------
artursapek
I'm building a complicated canvas app[1] for visualizing Bitcoin markets. I
resorted to building my own framework on top of canvas, exactly for
performance reasons. It's fast, but as a framework I was never too happy with
it because it's a little half-baked.

More recently I found and fell in love with React for other frontend work, and
use it exclusively now for any view-related work. I might have to go back and
rewrite the ugliest parts of my code with this, it looks awesome. Kudos to
Flipboard for open-sourcing it.

[1] [https://cryptowat.ch](https://cryptowat.ch)

~~~
nkohari
Very cool app. I'm going to pass it around to friends who are more into
cryptocurrencies than me. :)

Sorry to hijack this thread, but I have a question: you seem to have been
successful in stopping left/right swipe from navigating back and forward. The
app I'm working on supports horizontal scrolling, but it can be a bit
confusing if you mean to scroll and accidentally navigate.

I've tried a few things and looked around for answers, but so far the
solutions I've found haven't worked out. Can I ask what your secret is? :)

~~~
artursapek

        document.querySelector('canvas').addEventListener('mousewheel', function (e) {
          e.preventDefault();
        });

~~~
nkohari
If it really is this simple, I'm going to kick myself repeatedly. Thanks. :)

------
danabramov
Oh my, it is beautiful on the inside. Check out the source.

They're totally showing off the power of React component model even when it
doesn't render directly to DOM tree: [https://github.com/Flipboard/react-
canvas/blob/master/lib/Su...](https://github.com/Flipboard/react-
canvas/blob/master/lib/Surface.js)

It's about describing nested side effects in time, really.

~~~
vowelless
I have generally done systems and backend work, so usually C/C++/Go/Python.
React is making me extremely excited to do some frontend work!

Is React a good introduction to the land of frontend programming? Or do I
first need to familiarize myself with vanilla JS and go bottom up to React?

~~~
supercoder
There's no need to go deep diving on learning JavaScript.

As you're using a high level framework, you're interacting with that more than
the details of JavaScript. So in essence you're learning 'React' not
'JavaScript'.

So just start building in React and the JS will come along naturally.

~~~
driverdan
That's not really true. You really need to understand JS to work with React,
especially since you need to combine it with other libs since it's only the
view layer.

------
vidarh
A stronger indictment of the DOM than finding it necessary to combine a CSS
parser written in Javascript, a virtual DOM and a canvas based renderer
because it is _faster_ than updating the DOM would be difficult to come up
with...

It looks like amazing work, but it's quite depressing that it's necessary.

~~~
walterbell
Does mobile browser DOM rendering use GPU hardware acceleration?

~~~
stoikerty
Yes they can. If you are interested here is how the rendering works.

The rendering happens in batches, the first render is always an expensive
operation and includes both "paint" & "layout".

\- The "layout"-operation recalculates the tree of visible elements.

\- The "paint"-operation paints the element and is commonly done using a
software rasterizer.

Every subsequent render happens if an DOM-element triggers a layout or a paint
(or both). A re-paint occurs when changes are made to an elements skin that
changes visibility, but do not affect its layout. Examples of this include
outline, visibility, or background color.

When you use GPU-accelerated CSS properties such as opacity, translate, rotate
& scale, both layout- and paint-operations are not executed. The GPU handles
the changes for those properties. This is how famo.us wants to achieve its
"60fps".

React by itself can cause expensive operations too if you trigger a CSS
property that is not GPU-accelerated. In the process of rendering, a DOM-
element can be destroyed and recreated when your state or model changes. So be
vary of third-party React-components that promise "fluid" or "fast" speeds.
IMO animation is still a research-topic for React. Their manual currently
lists a method for basic CSS animations and transitions, but it's projects
like React Canvas that make React a worthwhile contender for performant
animations.

[http://facebook.github.io/react/docs/animation.html](http://facebook.github.io/react/docs/animation.html)

Mobile browsers are no different to Desktop browsers, almost every smartphone
has a GPU of some sort. So you have 2 main-bottlenecks with every device. The
first is the CPU (& RAM), the next one is the GPU (& the GPU-RAM).

What is GPU-accelerated and why:

[http://www.html5rocks.com/en/tutorials/speed/high-
performanc...](http://www.html5rocks.com/en/tutorials/speed/high-performance-
animations/)

How Reflows and Repaints cause slow javascript:

[http://www.stubbornella.org/content/2009/03/27/reflows-
repai...](http://www.stubbornella.org/content/2009/03/27/reflows-repaints-css-
performance-making-your-javascript-slow/)

------
dkarapetyan
New job description for front-end web developers: 5+ years of designing game
engines and optimizing rendering pipelines.

If the joke is lost please go read about the similarities between react and
immediate mode rendering systems.

~~~
JoshMilo
Honest question, would studying immediate mode rendering systems improve my
understanding of React's system of doing things? If so, do you have a resource
I could use?

~~~
stoikerty
There is a video that describes "Immediate-Mode Graphical User Interfaces"
really well, see:
[https://twitter.com/stoikerty/status/467047333453381632](https://twitter.com/stoikerty/status/467047333453381632)

There is also a lengthy and insightful blog-post about the subject where I
found the video: [http://jlongster.com/Removing-User-Interface-
Complexity,-or-...](http://jlongster.com/Removing-User-Interface-
Complexity,-or-Why-React-is-Awesome)

~~~
jt2190
Video is here: [http://mollyrocket.com/861](http://mollyrocket.com/861)

------
peteorpeter
Here's an interesting take on the "hybrid" app idea:

\- React Canvas is your application layer

\- HTML canvas is your common rendering layer

\- Browsers are your web runtime

\- Ejecta[0] is your iOS runtime

\- (I don't know a native android canvas runtime)

[0] [http://impactjs.com/ejecta](http://impactjs.com/ejecta) \--> renders with
WebGL

~~~
cpr
React Native can be the core of your iOS/Androis runtime.

------
arcticgeek
It's funny to watch the world very slowly reinvent Adobe Flex.

~~~
wallflower
Flex was ahead of its time with Spark.

It was behind its times with mxmlc. mxmlc made it painfully clear, even with
incremental compile, that you were building a client-server application in a
web age.

Once you wanted to build custom UIs, you lost the "WYSIWYG" GUI rapid
development environment that was the whole selling point that Adobe came in
with.

The data synchronization system worked but it was opaque and how (at the time)
they made their money.

Flex lost to the open web.

------
danabramov
LOL, didn't expect it to work with React Hot Loader practically out of the box
(except for <Text> for some reason): [https://github.com/Flipboard/react-
canvas/pull/3/files](https://github.com/Flipboard/react-canvas/pull/3/files)

The fun part is tweaking text layout algorithm and letting Hot Loader pick up
changes when replacing components. Without browser refreshing, of course.

------
amelius
Last time I checked, measuring font sizes using the canvas was horribly slow.
So, I wonder how they perform measurements necessary for automatic line-
wrapping, et cetera. Are they doing these measurements fully in javascript?

> Custom fonts are not currently supported but will be added in a future
> version.

Ok, that is a pity. I wonder if it has something to do with the complexity of
implementing measureText fully in javascript.

~~~
mjjohnston
Custom fonts are supported on flipboard.com using the same rendering engine.
It was just a matter of time to extract the Flipboard specific bits out. This
is coming soon.

~~~
amelius
I was also wondering how you embed video. And what if an element in the
virtual DOM (e.g., a popup box) overlaps with the video?

------
drhayes9
What are the accessibility implications of drawing all controls of a web app
to the canvas using React? Are there ARIA annotations available for React
already?

~~~
spicyj
I don't know the specifics of how canvas accessibility does or doesn't work,
but React definitely supports adding ARIA attributes to any tags it renders.

~~~
drhayes9
That's one of the problems with rendering UIs on canvas: it doesn't work with
a11y. And since it's not rendering tags, there's nowhere to hang the ARIA
attributes.

~~~
tmzt
I wonder if an invisbile SVG layer would work for that purpose, or translate
positioned invisible DOM as a fallback.

------
marknadal
holy flipboard, did you see they re-implemented a subset of CSS into JS?
[https://github.com/facebook/css-layout](https://github.com/facebook/css-
layout) I was literally thinking about doing something similar the other day
for an experimental/learning project.

React is taking over the web, and I'm excited for it - coming from a person
who is incredibly cynical about frameworks. React is proving itself as a
powerful library, not an assumption driven framework.

~~~
ghayes
This was specifically referenced in the React Native announcement video. [0]

[0]
[http://youtu.be/7rDsRXj9-cU?t=16m35s](http://youtu.be/7rDsRXj9-cU?t=16m35s)

~~~
m_mueller
That's an impressive segment, thanks for linking.

------
aaronyo
Big fan of React. For others using it, why use JSX instead of just doing
everything in js?

In other words, why is HTML like this:

    
    
      <Group style={styles.group}>
              <Image style={styles.image} src='http://...' />
              <Text style={styles.text}>
                Lorem ipsum...
              </Text>
            </Group>
    

Preferable to something like this (which can easily be done with some helper
methods wrapping the verbose React DOM methods):

    
    
      $group({styles: style.group},
        $image({styles: image, src: 'http://...'}),
        $text({styles: style.text},
           'Lorem ipsum...'));
    

No pre processing step required, and of course it's natural to imbed js in,
er..., js.

What am I missing? Why keep the HTML part in all this?

~~~
insin
The XML-like syntax is just less work, mentally and physically: no need for
commas between props, the props object and children, no need to carefully
manage all those commas when editing, adding, deleting, moving and removing
stuff later on, plus the closing tag syntax makes nesting nicer by providing
context via the tag name; all of which adds up to make it more pleasant to
work with.

The second approach is what I was doing in various flavours for years prior to
JSX. I ended up having to adopt comma-first to stay sane in larger/deeper
templates, ( e.g.
[https://gist.github.com/insin/8e72bed793772d82ca8d](https://gist.github.com/insin/8e72bed793772d82ca8d)
). The first thing I did when I saw JSX was start to write a React.DOM
emitting version of my then-usual JSON-ML type stuff, but then I tried it
and... never going back.

~~~
aaronyo
Thanks for sharing the examples -- really appreciated.

I'm not convinced that HTML is preferable to other representations of the DOM,
particularly for representing UI's and applications (rather than documents).
The clojure script wrappers for React I've seen seem to believe, for example,
that lisp is better at representing the DOM than HTML and I tend to agree.
Especially since any configured IDE should be pointing out missed commas and
have rainbow parens.

One thing that is different between your examples and the DOM I've been
creating with React is that I tend to make custom tags, and I don't end up
with tons of repetitive looking stuff. Your last example is quite readable to
my eyes, and would be even more so if perhaps decomposed into some helper
functions and, of course, if loops were used and the DOM was populated from
some data structure.

------
mmgutz
Is it me or are these React frameworks heading towards the ideas in XAML and
MXML?

------
philnash
Out of the box browser features that have been removed/destroyed by the quest
for 60fps:

* Copy/paste (holding on an article gives the options to email or report)

* Pinch to zoom

* Double tap to zoom (opens links instead)

* iOS swipe forwards and backwards (renders the page swipe animation twice, at 60fps I guess)

* iOS Reader View (go on, try it, I laughed)

And most importantly

* Any sort of accessibility

60fps doesn't matter to someone who can't see the screen.

60fps doesn't matter to someone who relies on assistive technologies to surf
the web.

60fps doesn't really matter.

~~~
rimantas
Exactly. This is a horrible misuse of the canvas element, alas, the moronic
"war against native" destroyed all the good we had achieved ten years ago. I
think then we had the golden age of web standards, progressive enhancement,
graceful degradation, accessibility, and what not. Now we just have a race who
can rape poor HTML/CSS/JS further.

~~~
porker
And yet that's what people pay money for/perceive value in.

Disillusioned web zealot here.

------
polskibus
This is a great project indeed. However, as many here have already pointed
out, there are many limitations to this approach, SEO and lack of ctrl+f for
example.

Which reminds me of flash. Most flash controls had similar drawbacks. I think
web development shouldn't repeat that mistake (again).

It also reminds me that Google Docs took similar approach. As far as I
remember they use a lot of canvas with a bit of DOM intertwined where
necessary.

------
devongovett
This is great. Can't wait for the WebGL version ;-)

Also, it would be really cool to run everything except rendering in a worker
thread and send rendering commands to the UI thread, like react-native does.

------
cnp
My god this is so fucking awesome! Great work guys and gals. Shows precisely
what a good, wide-ranging idea _means in practice_.

------
efields
I'm guessing [http://flipboard.com/explore](http://flipboard.com/explore)
should be a good demo (in mobile safari, upper-right link off the home page),
but it's just infinitely loading for me.

Posting b/c someone from Flipboard is probably monitoring this thread ;-)

~~~
abm91
Fix pushed ;-)

~~~
egeozcan
After 20 minutes, I still see this error:
[http://i.imgur.com/AdfJNkO.png](http://i.imgur.com/AdfJNkO.png)

Tested with Chrome/FF/IE (all latest) with the same result. Hope it helps.

------
megaman821
This looks really neat. How does this compare to Famo.us, which also claims at
have smooth animations at 60 fps?

~~~
woah
Famo uses the DOM, by encoding matrix transforms to strings and sticking them
into the attributes of DOM nodes.

~~~
lefnire
How about in terms of adoption, momentum, team, performance, etc? Any insights
/ predictions on how Famo.us might stack up _against_ react-canvas?

------
ZenoArrow
Looks really good. My only real question would be about something drab but
practical: SEO.

As the components are rendered to canvas, would the metadata that usually
feeds SEO be harder to generate? Is that something you could fix through use
of the parallel DOM (it's mentioned briefly on the page)?

~~~
danabramov
See this note: [https://github.com/flipboard/react-
canvas#accessibility](https://github.com/flipboard/react-canvas#accessibility)

------
elwell
> There is experimental support for using css-layout to style React Canvas
> components.

Just an experiment, but that could be very powerful. A lot of canvas-eligible
projects are done in the dom because CSS makes it easier that messing with
hardcoding all the style in js functions.

------
forrestthewoods
So one of my friends says that a potential issue is accessibility compliancy.
And that due to lack of compliancy Flipboard may find themselves in a lawsuit.
I know next to nothing about this type of thing. Anyone have thoughts on the
issue?

~~~
nevir
Lawsuit seems unlikely, but it is certainly hostile to screen readers (though,
it's quite possible to create a set of hidden DOM nodes that expose the
structure of the page to screen readers. See google docs)

------
danpeddle
It's a shame that so many custom android roms either do not or have only very
limited support for hardware acceleration in the browser. I do not know what
percentage of users would fall into this category, but worth keeping in mind.

------
jchrisa
Is there a live demo I can run?

~~~
buymorechuck
Just go to [https://flipboard.com](https://flipboard.com) on your mobile
phone!

~~~
fortes
Congrats on the release Charles!

~~~
buymorechuck
Thanks Filipe! :-)

------
archagon
Oh man, it's a small thing, I _love_ how well the back button works. Feels
totally like a native iOS app. (Though not so much if you use the swipe from
left gesture, sadly.)

------
staircasebug
Amazing and buttery smooth on my Android/Chrome, but as of now, there are big
accessibility hurdles to overcome with Canvas and that's concerning.

------
woah
\- Will this work inside of iOS's JavaScriptCore? \- Could this use grid style
sheets as its styling engine?

------
picardo
This is so beautiful! I can see this being used for building canvas based web
applications as well!

------
burnstek
At first blush, the mental model reminds me of ASP.NET WebForms.

~~~
aboodman
err, WebForms is the exact opposite. WebForms is about taking something
stateless (HTML) and making is stateful. React takes something stateful (the
DOM) and makes it stateless.

------
dandare
Am I the only one who sees the parallel with Flash?

------
nusratty
Loving it.

------
thebiglebrewski
Cooooool!

