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

Option to skip first render #701

Closed
eliot-akira opened this issue May 20, 2017 · 7 comments
Closed

Option to skip first render #701

eliot-akira opened this issue May 20, 2017 · 7 comments

Comments

@eliot-akira
Copy link

eliot-akira commented May 20, 2017

I have a situation with a client-side router (a fork of React Router v3) which does an initial empty render to match routes - returning null - then a second render that actually renders the app. I'm also server-side rendering - so the DOM is already populated - and when the client renders the first time, there's a flash of empty page caused by route matching, then the app is rendered again.

This is not an issue with Preact, but the only solution I found was to make Preact.render ignore the first render. It required only very minor changes: for render() to pass an initial context to diff()...

export function render(vnode, parent, merge, context = {}) {
  return diff(merge, vnode, context, false, parent, false)
}

Then for diff to ignore rendering if specified:

export function diff(dom, vnode, context, mountAll, parent, componentRoot) {

  if (!vnode && context && context.ignoreFirstRender) {
    delete context.ignoreFirstRender
    return dom
  }

  ...

Would you consider adding such an option to Preact? I know the real solution would be to rewrite the route matching algorithm to not require an initial empty render, but that seemed to be much more complex.

@developit
Copy link
Member

This is called async boot. It's something that's come up before, but your use-case is actually fairly difficult, since preact doesn't know that your second render is the correct render. Imagine if your componentDidMount did setState({ loading: true }) - should preact remove the DOM then?

Don't mean to downplay, just it's really hard for preact to know anything about data fetching and readiness when it's just a view renderer 😇

@eliot-akira
Copy link
Author

eliot-akira commented May 20, 2017

Yes, it's a very specific use case, and probably no one else would find such an option useful - to just ignore the first render - so I can understand it may not be worth the additional complexity to add it to Preact. I suppose I can maintain a fork with this option, or actually fix the issue with the router so that it doesn't need an initial empty render - that's where the real problem is, that is clobbering the DOM..

Well, thank you for considering it. 😄

@developit
Copy link
Member

I think if we could come up with a more generalised way to solve this problem, we might be able to have the best of both worlds. Paul Lewis submitted a PR that implemented lazy component initialization, and that scheduling mechanism might work as a way to enable what you're looking for here - you would simply defer the initial render of your component and never actually commit it, effectively bypassing rendering until your component got the requisite data.

@developit
Copy link
Member

The PR has been sitting unmerged for a while because it's a really tricky thing to do, but it's still on the radar and something I would love to get working:
#409

@eliot-akira
Copy link
Author

That sounds great - I'll take a look at the PR to see how that could work. If there was a way to hook into deeper in component initialization, I imagine it would be possible to defer the actual rendering until route matching is completed.

@developit
Copy link
Member

Yup. It would also enable awesome stuff like waiting to update components until there are some CPU cycles free.

@marvinhagemeister
Copy link
Member

Async rendering is something that's on our minds, but will take a bit of time to get it working. Let's continue the discussion in #862 or #526

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

3 participants