Sapper: Show a loading indicator for slow pages

Created on 4 Jun 2020  路  3Comments  路  Source: sveltejs/sapper

Is your feature request related to a problem? Please describe.
Even though Sapper is very fast, the preload function might call a slow API when fetching data. Since Sapper uses ajax to simulate page loads, the browser won鈥檛 show a loading indicator. To the user it looks like nothing is happening.

Describe the solution you'd like
When a page is taking a while to load, I'd like Sapper to show a (customizable) loading indicator. One way to do this would be to show it if the preload function returns a Promise.

turbolinks and GitHub (with pjax) both do this.

Describe alternatives you've considered
Instead of returning a Promise, my preload function could return { data: myPromise } and I could render my own loading indicator in the page. But I'd like it to be handled by the framework for me.

How important is this feature to you?
Low-medium. I don't have a real use case for it right now but would love to have it there for when I need it.

Additional context
You can test this out by adding this to the top of preload in src/routes/blog/[slug].svelte:

await new Promise(resolve => setTimeout(resolve, 2000));

Most helpful comment

I just do something like this in my _layout.svelte. This example triggers if preloading lasts longer than 250ms but you can change it around however you like.

<script>
  import { derived } from 'svelte/store';
  const { preloading } = stores();
  const delayedPreloading = derived(preloading, (currentPreloading, set) => {
    setTimeout(() => set(currentPreloading), 250);
  });
</script>

{#if $preloading && $delayedPreloading}
  <!-- Show Loading spinner -->
{/if}

<slot />

All 3 comments

I just do something like this in my _layout.svelte. This example triggers if preloading lasts longer than 250ms but you can change it around however you like.

<script>
  import { derived } from 'svelte/store';
  const { preloading } = stores();
  const delayedPreloading = derived(preloading, (currentPreloading, set) => {
    setTimeout(() => set(currentPreloading), 250);
  });
</script>

{#if $preloading && $delayedPreloading}
  <!-- Show Loading spinner -->
{/if}

<slot />

Yup, indeed you can already use the $preloading store for precisely this.

That鈥檚 great. Thank you.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

UnwrittenFun picture UnwrittenFun  路  4Comments

mylastore picture mylastore  路  3Comments

freedmand picture freedmand  路  4Comments

matt3224 picture matt3224  路  4Comments

nikku picture nikku  路  4Comments