Yomguithereal / baobab

JavaScript & TypeScript persistent and optionally immutable data tree with cursors.
MIT License
3.15k stars 115 forks source link

Feature request: RAF updates. #333

Open DylanPiercey opened 9 years ago

DylanPiercey commented 9 years ago

Often when using baobab (or similar libraries) a ui update follows a state update.

React handles requestAnimationFrame automatically but if you are using a different framework or are doing some imperative stuff that isn't the case.

It would be nice if baobab could emit an "animation" event which would be called on animation frame after an update. Similar to immstructs next-animation-frame.

Yomguithereal commented 9 years ago

Hello @DylanPiercey. Currently, Baobab commits on setTimeout 0 but I guess it would be wise to switch to requestAnimationFrame indeed. If I follow you correctly, you need an event to know when the update of the tree has been committed? Why not use the update event? Do you need something that would work differently if your tree is synchronous or asynchronous?

DylanPiercey commented 9 years ago

@Yomguithereal currently I am using the update event, however AFAIK it is called immediately after a commit which as you said is done with setTimeout 0.

This means that I would have to manually do something like:

var frame = null;

baobab.on("update", function () {
    if (frame) cancelAnimationFrame(frame);
    frame = requestAnimationFrame(function () {
        // work with DOM
        frame = null;
    });
});

// vs

baobab.on("update-frame", function () {
    // work with DOM
});

Since I think this would be a semi common use-case it would be handy to have it built in. Also, I have been doing this with sync commits, but I'm not sure what the implications of sync commits are.

If it helps any I am planning to use baobab with Tusk.

Yomguithereal commented 9 years ago

So, if we go to the bottom of the issue here, the only problem is that Baobab does not use requestAnimationFrame no? What I can do is switch to requestAnimationFrame by default (with a proper fallback for node obvioulsy) but letting the user choose the async method if needed?

DylanPiercey commented 9 years ago

That sounds about right if there isn't any comparability issues. Will this only work if you have async commits?

Yomguithereal commented 9 years ago

There should not be compatibility issues. Node or older browsers would fallback to nextTick or setTimeout.

DylanPiercey commented 9 years ago

@Yomguithereal you could use something like https://github.com/component/raf. Sadly it won't work in node thanks to "window", but would be easily modified.

Yomguithereal commented 9 years ago

Thanks @DylanPiercey. I had some different opinions lately about requestAnimationFrame. It seems a lot of people prefer having their updates on setTimeout 0. I'll probably make this an option then.

Yomguithereal commented 9 years ago

@christianalfoni: with cerebral, what is your update scheme? setTimeout? requestAnimationFrame?

Yomguithereal commented 9 years ago

Sorry for the double question. You answered this one on #337.

DylanPiercey commented 9 years ago

@Yomguithereal is this available in 2.0?

DylanPiercey commented 9 years ago

Also; in node we should fallback to setTimeout of 16ms for consistency if this makes it in.

christianalfoni commented 9 years ago

@Yomguithereal Yeah, animation frame :-)

DylanPiercey commented 9 years ago

So this can be closed?

Yomguithereal commented 9 years ago

Not yet.

aeosynth commented 8 years ago

on node you could use setImmediate or process.nextTick, and document the difference