-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Description
Describe the problem
Having a single load function which loads all of the data for a page means that you cannot reload part of the pages contents. If the user performs an action that invalidates part but not all of the page one has to reload the route which will fetch all of the data for the page. This means that the app will make more database and storage calls than necessary. If the props returned by the load function are not primitive values svelte will also re-render pretty much the entire page even if only a single only component needs updating. Because even if the returned props have equal values svelte is only able to check equality for primitive values.
This means that to get partial updates in pages we have to duplicate the load logic in event handlers in the page. The partial updates however will not be available to users with no Javascript so the developer is forced to handle that case separately. It would be much better if load
only made the fetches that it needed to based on its inputs.
Describe the proposed solution
Instead of the load function returning a props
object with a value specified for each component prop the load function should instead return a props
object with a store specified for each component prop. This would also require that objects passed into the load function are stores.
Consider the following example load function in my proposed 'store style' for a hypothetical (and somewhat contrived) social network example where the user navigates between posts but and the user's profile information is displayed in the top corner of each page.
export const load = ({ request, stuff, url, session, status, error, params, fetch }) => {
const post = derived([params], async ([$params], set) => {
const postResponse = await fetch(`posts/${params.postId}.json`);
const postData = await postResponse.json();
set(postData);
});
const userProfile = derived([session], async ([$session], set) => {
const userProfileResponse = await fetch(`userProfile.json?sessionId${$session.sessionId}`);
const userProfileData = await userProfileResponse.json();
set(postData);
});
return {
props: { post, userProfile }
}
}
Every time the user navigates to a different post the params
store is updated causing the new post data to be fetched using the new postId
. Any components that depend on the post
prop will then be updated. However because the session
has not changed the user profile does not need to be refetched. And since the userProfile
store does not get updated any components that only depend on the userProfile
prop don't need to be updated.
Alternatives considered
No response
Importance
would make my life easier
Additional Information
No response
Edit: Fixed some errors in my writing. I was a bit tired when I wrote this.