kaisermann / svelte-loadable

Dynamically load a svelte component
MIT License
322 stars 13 forks source link

Loading never displayed? #30

Open maximedupre opened 4 years ago

maximedupre commented 4 years ago

Hello!

I'm using svelte-loadable in conjunction with svelte-routing. I'm having an issue where there is a ~1 second delay when changing route before my component is displayed. I was thinking that lazy-loading my component with svelte-loadable would at least allow me to display a loading bar while the component is being loaded, but that does not seem to be the case.

If I hardcode a large delay like shown in your example page (https://github.com/kaisermann/svelte-loadable/blob/master/example/src/App.svelte), then the loading slot is displayed. But if I don't, none is shown. I've also set the delay prop to 0 while making both tests.

Is this because there is actually no delay for the loading of my component and that the problem I am experiencing is that there is too much processing in my component, which blocks the DOM for a second? I would be surprised if this is the case, because on the initial loading of the page the component appears right away. Which is why I think I'm doing something wrong with svelte-loadable, or maybe there is some sort of a bug.

Let me know if you have any insight on what could be causing this issue on the svelte-loadable side.

Cheers!

Edit # 1

To make it work, I have to add the unloader prop: <Loadable loader={HomeLoader} delay=0 unloader>. Without the unloader prop, the loading slot will not be displayed if I navigate back to this page, because the loading has been cached. However, there is still a 1sec delay before the component is displayed, even if the loading has been cached. Weirdly enough, the loading slot never appears on the initial page render, but appears every time the page is accessed with changing route (if the unloader prop is specified). So I unload the the loader, just to show the loading slot. And since the component loads so fast that it doesn't display the loading slot (yet there is still a 1 second delay before component is displayed), I need to artificially delay the loader just to display the loading slot:

const HomeLoader = register({
    loader: () => {
        return new Promise((resolve, reject) =>
            setTimeout(() => resolve(import('./home/Home.svelte'))),
        )
    },
    resolve: () => 'Home',
})

This makes the loading slot display, because I have set the delay prop to 0. And there is still a 1 second delay before my component is rendered, so the loading slot stays there until the component is displayed, which gives the illusion of loading...

kaisermann commented 4 years ago

Hey @maximedupre đź‘‹ Firstly, thanks for your detailed issue. Would you be able to provide a repro repository? It would help a lot to debug your situation.

maximedupre commented 4 years ago

Hi! Thanks for the quick response :).

I'm afraid that creating a repro repository would take more time than I have. I currently have something that is working or at least creating the illusion of the expected behaviour.

Here are more details that might help. I have two routes - "Home" and "About". Each route renders the component that has the same name inside a Loadable. Component "About" has almost nothing in it and renders instantaneously when navigated to. Component "Home" has lots of synchronous processing, many loops on big JSON files and some calculations. If I remove the processing from "Home", it also loads instantaneously. If I "lazy-load" the processing by putting it inside a setTimeout(() => ..., 0), the component also appears pretty quickly. But if I just leave the calculation as is, there is a 1 second delay.

The delay does seem to be caused by the synchronous operations affecting the main thread. The component loads instantaneously, but then does processing, which causes the 1s delay.

I'm not sure there's anything you can do about it. What do you think?

frederikhors commented 2 years ago

@maximedupre are you using it correctly?

https://github.com/kaisermann/svelte-loadable/blob/58f940419ab3bac3625d923ec783e4e8b301572e/example/src/App.svelte#L35-L39