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

preload #1015

Closed
Rich-Harris opened this issue Dec 12, 2017 · 8 comments
Closed

preload #1015

Rich-Harris opened this issue Dec 12, 2017 · 8 comments

Comments

@Rich-Harris
Copy link
Member

Another takeaway from the Sapper Hacker News experiment — we need a conventional way to preload data, to avoid flashes of unfetched content on initial render and on route changes.

Next.js has getInitialProps. I propose we add a preload property to components, which would be added as a static property to the constructor.

<!-- routes/post/[slug].html -->

<h1>{{post.title}}</h1>
{{{post.html}}}

<script>
  export default {
    preload({ params }) {
      return fetch(`/api/post/${params.slug}`)
        .then(r => r.json())
        .then(post => ({ post }));
    }
  };
</script>

On the server, this could be used like so:

const data = Object.assign(
  Component.preload ?
    await Component.preload({ params, query, client: false }) :
    {},
  { params, query }
);

const { html, title } = Component.render(data);

The data would also be sent to the client with the initial payload, so preloading wouldn't need to happen again upon hydration.

On the client, on route changes, preloading would happen before the previous component was torn down and the new one rendered in its place.

Any thoughts? (I realise the question implies a level of familiarity with Sapper, which doesn't really exist yet, but hopefully you get the idea.)

@tivac
Copy link
Contributor

tivac commented Dec 12, 2017

I like parts of this. But this bit has me worried:

On the client, on route changes, preloading would happen before the previous component was torn down and the new one rendered in its place.

This is going to make for a really laggy-seeming user experience if preloading takes > 100ms. I'd probably avoid this & instead make sure that my components can draw in a skeletal state while waiting for data to reload.

@Rich-Harris
Copy link
Member Author

Yep, agree there's a risk there. Am mainly thinking of a) the first load, and b) cases where you've already prefetched the stuff you need, so it's more about avoiding a flickery route change than waiting for stuff to come over the network.

In theory the lag could be prevented by conditionally (the condition being 'we're in a browser') returning a flag that tells the component it needs to go away and fetch some stuff, or with clever use of Promise.race. But I guess the real answer is to have really good support for easily preloading stuff. Could even bake in something like Premonish and target all the <a> tags with valid URLs.

Rich-Harris added a commit that referenced this issue Dec 13, 2017
@paulocoghi
Copy link
Contributor

This is interesting!

Until then, I was thinking of solving this problem using a local nosql database (probably minimongo) so data is always available (and the app will also work offline, which is a plus).

The idea was to use local queries and, in parallel, a backend request. The local data will be placed instantly (because its already there) and, as soon as the backend responds, update it accordingly.

--

Now, with preload, it may be possible to use both solutions to get even better user experience.

@weepy
Copy link

weepy commented Jul 16, 2019

Is there a way to handle this with Svelte 3 ?

@Conduitry
Copy link
Member

@weepy
Copy link

weepy commented Jul 16, 2019

So you need to use Sapper to avoid flashes of unfetched content ?

@Conduitry
Copy link
Member

Or any other mechanism for not instantiating a component until you have all of the data it needs. Sapper is one way of doing that. This issue was never about handling this in Svelte itself.

@weepy
Copy link

weepy commented Jul 16, 2019 via email

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

5 participants