Skip to content
This repository has been archived by the owner on Jan 11, 2023. It is now read-only.

Optimise apps with only one route #444

Open
Rich-Harris opened this issue Sep 19, 2018 · 3 comments
Open

Optimise apps with only one route #444

Rich-Harris opened this issue Sep 19, 2018 · 3 comments

Comments

@Rich-Harris
Copy link
Member

This has been a long term goal...

screen shot 2018-09-19 at 7 29 13 pm

...but Guillermo's tweet has got me thinking about what concrete steps we can take in that direction.

One is to avoid hydrating static routes, and in fact that's one of the oldest issues on this repo: #8

But another, simpler step we can take is to optimise for the (not that uncommon!) case where you only have a single route. In that case, we don't need a router! Which means we don't need sapper/runtime.js.

Ideally the user wouldn't need to think about this. That means that we'd need to change this...

import { init } from 'sapper/runtime.js';
import { manifest } from './manifest/client.js';

init({
  target: document.querySelector('#sapper'),
  manifest
});

...to something like this:

import * as app from './manifest/client.js';

app.init({
  target: document.querySelector('#sapper')
});

In the case where the app is completely static (i.e. no interactivity in the src/routes/index.html component), the manifest file could be as simple as this:

// src/manifest/client.js
export function init(){} // noop

I'm glossing over a few things here. What becomes of goto and prefetchRoutes etc — do they also become part of src/manifest/client.js instead of sapper/runtime.js (and if so, does it still make sense to call it a 'manifest')?

Details aside, this feels like a promising direction that would make it a complete no-brainer to use Sapper for projects of all sizes.

@Rich-Harris
Copy link
Member Author

Was just thinking about #445 in the context of this issue, and it occurred to me that there's a neat approach to all of this: we get rid of the Sapper middleware and sapper/runtime.js.

Instead, that logic goes into the generated files, not unlike the way Svelte dissolves itself into a compiled component.

Here's what I'm thinking:

// app/client.js
-import { init } from 'sapper/runtime.js';
-import { manifest } from './manifest/client.js';
+import * as sapper from './__sapper__/client.js';

sapper.init({
- manifest,
  target: document.querySelector('#sapper')
});
// app/server.js
import sirv from 'sirv';
import polka from 'polka';
-import sapper from 'sapper';
import compression from 'compression';
-import { manifest } from './manifest/server.js';
+import * as sapper from './__sapper__/server.js';

const { PORT, NODE_ENV } = process.env;
const dev = NODE_ENV === 'development';

polka() // You can also use Express
  .use(
    compression({ threshold: 0 }),
    sirv('static', { dev }),
-   sapper({ manifest })
+   sapper.middleware()
  )
  .listen(PORT, err => {
    if (err) console.log('error', err);
  });
// app/service-worker.js
-import { timestamp, assets, shell, routes } from './manifest/service-worker.js';
+import { timestamp, files, shell, routes } from './__sapper__/service-worker.js';

// ...

'Manifest' is an odd name for a collection of files that export functions as well as data, so I'm proposing that it be renamed to __sapper__, which a) is more obviously a directory of generated files that probably shouldn't be checked in to version control, and b) will be the first item in the src directory (I find it weird when manifest is the second or third directory, nestled between e.g. src/components and src/routes).

I find this setup more logical. It's much clearer that src/__sapper__/client.js contains stuff that shouldn't run on the server (unlike sapper/runtime.js), it avoids the weirdness of importing a manifest only to pass it back to the same framework that generated it, and it gives us the ability to pull off neat tricks like making an empty app as shown above.

Any thoughts?

@arxpoetica
Copy link
Member

b) will be the first item in the src directory

Yes please! Sign me up!

@Rich-Harris
Copy link
Member Author

@mrkishi pointed out on Discord that it's odd to have generated files in src at all, and perhaps it should be project/__sapper__ instead of project/src/__sapper__.

This would mean that the project root would contain .sapper and __sapper__ (.sapper is where the output of webpack/Rollup ends up during sapper dev or sapper export). That also doesn't seem ideal. I don't think that __sapper__ should be used for both input and output. Not sure what the solution is.

Rich-Harris added a commit that referenced this issue Oct 1, 2018
move app logic into templates (#444)
@arxpoetica arxpoetica added this to Export in Roadmap Triage Aug 20, 2020
@arxpoetica arxpoetica moved this from Export to SSR, SSG, CSR, etc. in Roadmap Triage Aug 20, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
No open projects
Roadmap Triage
Rendering (SSR, SSG, CSR, etc.)
Development

No branches or pull requests

3 participants