What can cause Sapper to perform slowly?

179 Views Asked by At

I am porting my Next.js site to Sapper for performance reasons, but my Sapper is performing very bad. Long load times (around 15 seconds for a page, if not served from cache). My API is very fast, so it can't be the issue.
I use Vercel hosting. But both there, and on my machine, the render times are about 15 seconds.
Since I'm new to Sapper, I suspect I might be doing something the wrong way. One thing I don't feel comfortable with, is that I pass global site settings (menu structure etc) from server.js in the function named "session". However this isn't something like a session object that contains user-specific data. It was the only way I found to achieve a global store in Sapper (accessible by both _layout.svelte and route pages) - if this is dirty, I hope someone can tell me another way.
And the other thing that concerns me is that I subscribe to the session in many different components - in order for them to have access to the global store.

Below is my current setup, summarized.

I fetch the site globals inside server.js, and pass them into the session. This was the only way I could find to enable me to access a global store from both _layout.svelte and my routes ([...slug]).svelte. I also add the stale-while-revalidate header, for Vercel's caching

const server = polka()
    .use(
        compression({ threshold: 0 }),

        (req, res, next) => {
            res.setHeader(
                "Cache-Control",
                "s-maxage=1, stale-while-revalidate"
            );
            next();
        },
        sirv("static", { dev }),
        sapper.middleware({
            session: async ({ headers }) => {
                const request = await fetch(
                    `https://MY_BACKEND/globals`
                );
                const { app } = await request.json();
                return {
                    app,
                    origin: `https://${headers.host}`
                };
            }
        })
    );

_layout.svelte

<script>
  import { stores } from "@sapper/app";
  const { session } = stores();
  let mainMenu = [];
  session.subscribe(({app}) => {
    mainMenu = app.mainMenu;    
  });
</script>

[...slug].svelte

<script context="module">
    export async function preload({ params },{ app }) {
        const page = await this.fetch(`${params.slug.join('/')}.json`).then(r=>r.json());

        ...some processing which uses the 'app' globals, and the page...

        return {...}
    }
</script>

Inside components that need access to the global store (these can be many)

<script>
      import { stores } from "@sapper/app";
        let something = '';
        const { session } = stores();
        session.subscribe(({app}) => {
          something = app.something
        });
</script>
0

There are 0 best solutions below