Loading non-essential data behind the scenes in Svelte

The Svelte team recently announced streaming promises. Essentially this means it is possible to load “non-essential” data in the background without delaying the rendering of the page.

And, as with most Svelte-things, it’s hugely useful but also simple to use.

At The Outlier we use the WordPress REST API for a lot of our projects, and we often need to retrieve hundreds of posts via the API. But pulling 100 posts at the same time can slow things down noticeably. Typically we write a series of fetch requests to pull the data in smaller blocks and then piece them together once the data is ready. It works but it’s not always pretty. Svelte’s new streaming promises are far simpler and more elegant.

The best part is that the streamed promises are initiated by a page’s load function but the load function doesn’t wait for the promise to be resolved before it returns the important data.

In the example below, we have two fetch requests. One pulls the first 10 posts from an API. The second one pulls 100 posts. The key is that the load function returns the first 10 as soon as they are received so the page can be rendered. The other 100 results are returned as a promise.

The load function in the +page.server.js file will only wait for the data to be returned by the getTenPosts() fetch function before returning and will return a promise for the data being fetched by the getRemainingPosts().

export async function load({ fetch }) {

return {
   posts: getTenPosts(),
   streamed: {
	otherPosts: getRemainingPosts()
	}
   }

}

In the +page.svelte file we retrieve the data and then wait for the streamed.otherPosts promise to be resolved :

<script>
// retrieve the posts and the promise
export let data

// wait for the promise to resolve
Promise.resolve(data.streamed.otherPosts)
   .then((posts) => {
       // the 100 posts data from the promise
       console.log(posts)
   }
</script>

If you don’t want to wait for the promise in the script section of your page an alternative way of retrieving the streamed data is to use a Svelte #await block in your main page.

In +page.svelte:

{#await data.streamed.otherPosts}
...Loading
{:then posts}
    {#each posts as p}
        <div>{post.title}</div>
    {/each}
{/await}

Retrieving the posts this way means we don’t have to wait for all hundred (or more) posts to be retrieved before we start rendering the home page.

It’s a simple but hight-effective technique.

The current official documentation on this is here: Streaming with promises.