Comments (9)
In fiddling about with SSR, I've come to the conclusion that there are two ways that I would approach it:
- Add a toHTML to all of the generated components, and just use the same code for both server and client rendering.
- Add a second generator that just works with strings and have a flag to generate server/string producing code.
I like the second approach a lot more, as it jives with the "don't add unnecessary stuff to the generated code" philosophy that svelte seems to be built around. There are some challenges that would have to be overcome, like building two different flavours, client and server, of each module, publishing them, and then using the correct flavour for the correct environment. I suppose it could be as simple as exporting the client flavour as default, the server flavour as special named export, and letting the server rendering process pull the server flavour when rendering. Tree-shaking could take care of the excess flavours anywhere a bundler is being used. Does that seem reasonable, or have I wandered too far into left field?
I don't think progressive enhancement is all that difficult once SSR is done, as it seems it's just a matter of adding a helper to create nodes rather than using document.createElement and friends directly. The helper would check for the enhance flag, and if present, would look for a suitable existing node to reuse before creating one. The enhance flag check could be limited to the root node, which would gather up the contents of the target element and pass them along the render chain, triggering automatic use of the existing DOM as children rendered. Of course, the presence of a helper kinda depends on the outcome of #9. Bonus: the helper refs would minify much better than document methods, which are >20b per node.
from svelte.
Definitely option 2 π
Whereas in Ractive, a component in node has the full API so that you can set
data etc, I was thinking it'd be nice and easy to just expose a render(data) -> html
method β i.e. components would be totally stateless.
The two parts I've been struggling with a bit:
- Nested components βΒ could be solved with a
require.extensions
hook, though I always feel like I'm doing something wrong when I muck around with that. Alternative is to intercept imported components some other way, which seems quite brittle - Lifecycle hooks β there isn't an
oninit
like in Ractive (there could be, but it's been a source of confusion in the past so initially I just added two lifecycle hooks, render and teardown) so there wouldn't be any place for setup work to happen. Might not be an issue if components are stateless though
The compiler can generate CommonJS files (rewriting import
declarations as appropriate), so it should be relatively straightforward to get components working in Node as long as they don't have any browser-only dependencies. Hmm, think I'll spin up a svelte-ssr
repo and start hacking.
I have some thoughts re #9, will leave them there. Definitely excited for us to solve the hydration problem.
from svelte.
I've not yet looked into how nested components work, but I kinda assumed they'd be late binding. When the parser runs across a camel-cased element, it calls it a component. Then when the generator needs to render a component, it pops in code to find the component constructor from up the hierarchy in some sort of registry (new SomeComponent({ components: { Foo, Bar }, ... })
), though maybe just on the parent. I'm probably a ways off though, because I don't know how you'd meld that with a single-file component structure.
Is there a way to contribute code to the component constructor? If there is, and the component is constructed with whatever its params are, then I'd say there's really no need for an onint
.
from svelte.
I kinda assumed they'd be late binding
The trouble is they're imported:
<script>
import Widget from './Widget.html'
export default {
components: { Widget }
};
</script>
So any compilation has to happen before (or during) the import. I wondered about doing the same thing Ractive does βΒ <link rel='svelte' href='...'>
but the static analysis win you get from using import
and declaring the dependency in components
is definitely worth something. (So many times I've left links to unused Ractive components in my apps because my linter didn't yell at me!)
Is there a way to contribute code to the component constructor?
If there was it'd be called oninit
π I'm tempted to roll with just render and teardown (especially makes sense if components are stateless on the server) and see how far we get... there's something appealing about only having two unambiguous hooks.
from svelte.
In SEO, I think it doesn't work quite well with contents in Javascript?
from svelte.
I know this is veering away from SSR, but in terms of the late binding components mentioned - I've been using the concept extensively in Ractive and it's been a huge win.
Some of the benefits / use cases of late binding and a component registry:
- hot reloading could become swapping the component instance in the registry and re-rendering
- dynamic registration of components and so there's an integration point for plugin/component libraries to expose UI kits
I guess the downside is that you don't know the entire component tree at compile time but, unless that's a big win, I think a standardised component registration point and the flexibility of dynamically swapping in and out components at runtime are two big pluses.
Oh, and thanks @Rich-Harris and @evs-chris for the incredible work on Ractive (and also now Svelte) - it's awesome stuff - hat's off to you guys for building things that are so incredibly powerful and yet super simple at the same time. Thanks! π
from svelte.
@simond-14 thanks!
Knowing the component tree at compile time definitely does have advantages. Apart from the fact that you don't need a registry (which has to be managed at runtime somehow βΒ which could easily cause problems if you have e.g. multiple apps on the page, potentially compiled with different versions), it makes everything that much more explicit when your dependencies are clearly expressed β the compiler can give useful errors, and it opens up possibilities like app-level static analysis (for catching missing/badly-typed data, unused CSS selectors, etc etc) and extracting app styles into a single .css
file.
I've never implemented hot reloading before βΒ hopefully a fixed component tree isn't a showstopper for that...
Anyway: came here to say that server-side rendering is now implemented in https://github.com/sveltejs/svelte-ssr. As mentioned in https://github.com/sveltejs/svelte-ssr/issues/4 I think it makes sense to merge it into this repo, unless anyone talks me out of it.
from svelte.
Hey any update on this? Was trying out SSR and something a little funky happened when I loaded my webpage:
I guess for now I'll remove existing DOM nodes.
from svelte.
This can be closed, as SSR and hydration are both supported
from svelte.
Related Issues (20)
- on:event on Component should produce a warning/error HOT 2
- Cannot use $state in static member variable HOT 2
- Variables not marked as $state will be re-rendered HOT 1
- Partial `@html` HOT 2
- false positive a11y warning for buttons and links without text but with image alt attribute HOT 3
- Runes: cannot optionally `bind:` to a component's prop if not exported HOT 1
- Svelte 5 unused $state memory leak HOT 5
- Svelte does not support import maps HOT 3
- Strange type error when using ComponentProps HOT 2
- Svelte stripping classes HOT 11
- Returning a promise on `get` from a user-defined proxy that's put in context throws an error on `getContext` HOT 1
- src attribute of script in svelte:head is undefined unless any other element is present HOT 2
- Unlike Svelte 4, the current rc version of Svelte 5 executes children actions after parent actions HOT 2
- Nesting selectors inside `:global` selectors are disregarded HOT 3
- REPL: Add ability to add files of different formats HOT 2
- Nested atrule in unused selector results in broken CSS output
- [Svelte 5] Optinal snippets in pair tags does not work with {#if}{/if} HOT 6
- svelte 5: anonymous function declaration broken
- `:has(...)` contents are not scoped HOT 1
- Add bind:scrollWidth & bind:scrollHeight properties HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
π Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. πππ
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google β€οΈ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from svelte.