Coder Social home page Coder Social logo

react-raf-batching's Introduction

react-raf-batching

NOTE: this repo was intended as an example and is kept here for historical purposes. Please don't use it in a real project!

A batching strategy for React that's more like a game. This may make your apps more performant but harder to test.

react-raf-batching's People

Contributors

petehunt avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-raf-batching's Issues

Upgrade to v0.10.0

As far as I can tell it works with v0.10.0, just need to update the package.json to avoid npm complaints.

Does not work well with a few corner cases

I actually like that this strategy enforces async setState because it's more deterministic than default strategy in this aspect. Just like Promises resolve on next tick so there's just one code path and not two.

We've been using this strategy in production with some success but I'm filing this to warn about a few caveats I found:

  • Safari on iOS is really restrictive about playing media in response to clicks. If you have something like <NativeAudio isPlaying> that wraps HTML5 <audio> and toggle isPlaying in response to a click, RAF batching will delay your call until next frame, and iOS Safari will block it. The solution (if you don't want to give up on RAF batching) is to simply call ReactUpdates.flushBatchedUpdates() after setState in click handler.
  • Chrome is very aggressive about not calling animation frames when tab is inactive. This is fine for animations but it looks very weird if some UI update (e.g. AJAX load success) only gets triggered when users switches back to the app. Internally we changed strategy like this:
// Based on https://github.com/petehunt/react-raf-batching
// but also triggers `tick` regularly if tab is inactive.

'use strict';

var ReactUpdates = require('react/lib/ReactUpdates'),
    now = require('react/lib/performanceNow');

var FORCE_TICK_INTERVAL = 1000,
    FORCE_TICK_THRESHOLD = 100,
    lastTick;

function tick() {
  ReactUpdates.flushBatchedUpdates();
  window.requestAnimationFrame(tick);

  lastTick = now();
}

function forceTick() {
  if (now() - lastTick > FORCE_TICK_THRESHOLD) {
    tick();
  }
}

var ReactRAFBatchingStrategy = {
  isBatchingUpdates: true,

  /**
   * Call the provided function in a context within which calls to `setState`
   * and friends are batched such that components aren't updated unnecessarily.
   */
  batchedUpdates: function(callback, a, b) {
    callback(a, b);
  }
};

tick();
setInterval(forceTick, FORCE_TICK_INTERVAL);

module.exports = ReactRAFBatchingStrategy;

Otherwise it works well for us and we never had problems with controlled inputs that some people were reporting.

Document limitations

In its current state, this strategy doesn't work out of the box.

If the root component has a state, and you manage to update it X times before the next frame, you might lose updates:

Frame 1
this.setState({ todos: this.state.todos.concat(newTodo) });
this.setState({ todos: this.state.todos.concat(newTodo) });
this.setState({ todos: this.state.todos.concat(newTodo) });
Frame 2 -> The todos only has a length of 1.

The state object is not updated synchronously.

is this a bug with batched updates?

How does this work?

I understand you require this somewhere and override the core batching strategy... but how?

Behave better in Node

When we run this package in a Node environment, where requestAnimationFrame is not defined, we fall back to the setTimeout-based strategy. Is that the best option? What about something like process.nextTick?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.