Flipboard / react-canvas

High performance <canvas> rendering for React components
BSD 3-Clause "New" or "Revised" License
13.18k stars 919 forks source link

Announcing React-RETINA (<canvas> for React v15 & also Preact compatible, and supports variable sized ListView) #160

Open xphung opened 7 years ago

xphung commented 7 years ago

This library is an alternative Canvas implementation for React v15 (which react-canvas has not yet been updated to use). It is also compatible with Preact.

https://github.com/xphung/react-retina

Features:

  1. Gallery component supports variable sized pages (whereas react-canvas ListView is limited to fixed size pages)
  2. React-RETINA only uses standard/public React APIs.
  3. The React Retina design avoids numerous React v15 anti-patterns (which React Canvas/React ART are guilty of using). There are no mixins, string Refs, or even Contexts. It does not use non standard lifecycle methods.
  4. The React RETINA component library source code is much easier to understand as a result and is leaner and cleaner.
  5. The View base component is extremely lightweight and specialised components (Image, Text, etc) are built on top of View via a custom draw callback. This is very flexible and allows virtually any drawable shape or component to be built on top of View.
  6. The React RETINA Backing Store implementation is simpler and cleaner to use - instead of requiring specialised hooks/lifecycle to manage invalidation and repaints, just assign a unique ID to the useBackingStore property to make the View the cache a repaint. Simply assign a new ID whenever an invalidation and repaint into Backing Store is required ... no need for a special Javascript calls or API to invalidate cache data!
  7. Keyboard events are supported!!
fredguest commented 7 years ago

@xphung is this meant to be a production ready alternative to react-canvas, and if so do you plan to add documentation and an installable npm package?

xphung commented 7 years ago

Hi fredguest, React-RETINA is the more lightweight & efficient (in terms of code size and simplicity) than React-Canvas. It also supports v15 of React whereas React-Canvas is still limited obsolete versions. The tight code base is much easier to test, understand, debug and modify and in fact, my preference is users directly read the source code instead of relying on too much documentation.

My target & testing for it has been Chrome and OS X WKWebKit only, and it makes no attempt whatsoever to support quirky older browsers, and there are no production-ready guarantees. On browsers that do support React-RETINA, my testing to date indicates it is higher performance than React-Canvas, as React-RETINA intentionally leaves out some costly features like arbitrary Z-indexes and text metrics.

For example, to support arbitrary z-indices, React-Canvas creates an array, reverses it, and sorts it ... it does this repeatedly for every single layer (including all child layers in the sub-tree) for all non-cached Canvas redraws. There may be hundreds of child-layers (eg. every single text and image component has it's own layer). My approach instead has been to traverse the layer tree in 'vDOM' order, and fix the z-depth to child > parent & nth child > nth-1 child. Given 'vDOM' order is arbitrary and x/y/width/height of any layer can be set to overlap as much or as little as any other layer, there is very little additional flexibility to be gained by the arbitary z-index approach of React-Canvas.

The other example is it's support for Preact, which at approx ~10KB is a higher performance and faster loading alternative to React v15.... I hope these examples shows why I believe there is a place for a tighter, lightweight approach than that taken in React-Canvas + React.

fredguest commented 7 years ago

It sounds very interesting, I'd like to try it out but it's a bit messy to import at the moment. Are you planning to publish it to https://www.npmjs.com/ so people can simply npm install react-retina?

xphung commented 7 years ago

My priority at this stage is getting v1.1 out, before publishing it more widely Will keep you posted on when v1.1 is out and may consider packaging it to npm then...

xphung commented 7 years ago

Currently, v1.0 is available as a "traditional" Githubissues.

  • Githubissues is a development platform for aggregating issues.