Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incremental rendering #57

Open
jgaskins opened this issue Sep 17, 2016 · 2 comments
Open

Incremental rendering #57

jgaskins opened this issue Sep 17, 2016 · 2 comments

Comments

@jgaskins
Copy link
Member

Currently, Clearwater's render process is an atomic process — it goes from state A to state B in a single pass. Most of the time, this is fine, but one drawback is that if you go from almost nothing to a giant vdom structure, the browser may need to create or delete thousands of elements in one go, which can take a long time, potentially blocking the UI.

Suggestions

What might be nice is that once the diff reaches a certain size, we go ahead and apply that patch and resume operation on the following animation frame. This would limit the amount of time we pause for rendering, even if it takes longer overall.

In many apps, a long pause is much worse than a dozen short pauses. For example, if I render a list of 1000 items, an incremental render might get enough of them on the screen in the first render that the user may not even realize it didn't happen all at once.

This may need to happen within the virtual-DOM engine itself in order to encapsulate it entirely from a Clearwater app's code. Currently, #52 helps, but requires massive diffs to be incrementalized at the app level rather than at the vdom level.

Caveats

This does create a bit of async issues not entirely unlike what happens in threads. For example, if I navigate to a page with a lot of data on it, but then an update comes in over a websocket, we may want that websocket update to wait until after the navigation render finishes.

Because of this and the fact that it does end up taking longer overall (and use more CPU time, leading to more battery drain on mobile devices), if we can support this, we may want to make it an opt-in feature.

/cc @johnsusi @jegt

@johnsusi
Copy link
Contributor

johnsusi commented Sep 21, 2016

This sounds like a good feature. We are seeing some app freezing on large renders. Nothing to serious though.

How would you handle a fresh render that occurs while doing the incremental ones? Queue it up until it's done? never mind, I see you already brought that up in 'caveats' :)

@jgaskins
Copy link
Member Author

We are seeing some app freezing on large renders. Nothing to serious though.

Yeah, I haven't seen any truly painful pauses in a realistic Clearwater app that I see every day in apps like Facebook and Twitter, but mostly I'm just wondering if it's possible to do incremental renders in a way that's completely opaque to app code. This may be a hard problem for a few reasons:

  • measuring the size of the diff is weird when the diff is a tree
    • you can't tell from the outside how large a tree structure is from the outside
  • if one node in a diff marks deletion of an entire subtree of thousands of elements, is that still going to pause?
  • do we have to generate intermediate states?
    • since we just render current app state, this would defeat the purpose
  • the only way I can think of to do it without intermediate states is to walk down the tree and apply diffs to small subtrees first, then walk up
    • this requires knowing where each element is rendered, which is not currently tracked.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants