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

Woes with SSR and Promises #3853

Closed
arggh opened this issue Nov 5, 2019 · 7 comments
Closed

Woes with SSR and Promises #3853

arggh opened this issue Nov 5, 2019 · 7 comments

Comments

@arggh
Copy link
Contributor

arggh commented Nov 5, 2019

I'm having trouble setting up SSR in a Svelte project that utilizes dynamic imports. I'm bundling the app with Rollup, producing a single JS file with dynamic imports inlined.

Best described with code:

<script>
	const params = {};
	const go = () => import('./views/PageHome.svelte');
</script>

{#await go()}
	Loading...
{:then comp}
	<svelte:component this={comp.default} {params} />
{/await}

...rendering this on the server will yield

{ html: '\n\t\tLoading...\n\t', css: { code: '', map: null }, head: '' }

Similarly, getting rid of the {#await ...} block and just setting the route directly like so...

<script>
	const params = {};
	let Route;

	import('./views/PageHome.svelte').then(comp => Route = comp.default);
</script>

<svelte:component this={Route} {params} />

...will yield:

{ html: '', css: { code: '', map: null }, head: '' }

The above code is compiled into this:

const App = create_ssr_component(($$result, $$props, $$bindings, $$slots) => {
	const params = {};
	let Route;

	Promise.resolve().then(function () { return PageHome$1; }).then(comp => Route = comp.default);

	return `${validate_component(((Route) || missing_component), 'svelte:component').$$render($$result, { params: params }, {}, {})}`;
});

The issue of course is the promise here.

It's pretty common to have an app that uses route based code-splitting. How does one, with Svelte, handle server-side rendering in that case? Extract routing outside of the Svelte app, and just render the specific Svelte page components directly?

Are there any good solutions to combining SSR and code-splitting and if so, should they be documented?

@arggh
Copy link
Contributor Author

arggh commented Nov 5, 2019

I suppose this is related: #958

@arggh arggh mentioned this issue Nov 5, 2019
@CaptainN
Copy link

CaptainN commented Nov 5, 2019

In svelte-loadable we worked around this problem by requiring the user to "register" loadables (dynamic imports) ahead of time. Internally, we keep a list of the registered loadables and can decide whether to do the loading, and display the "loading" slot, or to immediately use the loadable, if it has already been loaded.

You can also see a version of this working in my meteor based starter.

@arggh
Copy link
Contributor Author

arggh commented Nov 5, 2019

Thanks for chiming in @CaptainN , svelte-loadable solves my issue.

Closing this issue since #958 exists and is open.

@arggh arggh closed this as completed Nov 5, 2019
@CaptainN
Copy link

CaptainN commented Nov 5, 2019

I do wonder if there is a way Svelte could be adjusted to render resolved promises immediately instead of waiting a minimum of one tick. It could be a nice cheap performance win.

@AlbertMarashi
Copy link

@CaptainN it would fix a lot of problems regarding ssr & lazy/dynamic loading

@Conduitry
Copy link
Member

Even with an already-resolved promise, there is no way to get its value synchronously.

@CaptainN
Copy link

Even with an already-resolved promise, there is no way to get its value synchronously.

Not through the promise, but there are ways to work around that. I set up svelte-loadable that way. It registers the "loaders" so that there is a state handler that works outside of the promises. A pattern like that might not work in every case, I only mention it as an example of how to get around that problem.

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

4 participants