Comments (10)
But why does the browser even render the html page before it even has the whole picture, elements on the end of the document could change the whole page?
The whole concept of streaming is so that the browser can immediately show the page as early as possible. Streaming utilizes that fact and then sends the lazier chunks after it. Solid's async SSR is the complete opposite of this: it waits for everything before sending the entire HTML.
from solid-start.
It works as intended: the resource is called, triggering a Suspense boundary, where the resolving UI is streamed after the initial page load.
The only reason useAssets
didn't work is because it's a server-only API and is never meant to be used isomorphically. And if we consider the SSR setting, the useAssets
is called only after the fact that the initial html has been sent.
However, a probable solution here is to add deferStream: true
to createResource
, essentially turning it into a blocking resource rather than a streaming resource.
from solid-start.
Thanks for your answer, I understand that useAssets is only server-only, but that's quite inconvenient when useAssets doesn't work for ssr that is streamed. Is there a solution to this? Btw. what is actually streamed, the hydratable html or only the data?
And why doesn't useAssets
work on the working
page of my example, which should be completely rendered on the server without suspending:
<For each={data()}>
{(coffee) => {
useAssets(() => (
<style>
{`
#coffee-${coffee.id} {
width: 200px
}
`}
</style>
));
return <CoffeeItem coffee={coffee} />;
}}
</For>
But when it is a streaming resource why is the result directly in the initial response?
from solid-start.
Thanks for your answer, I understand that useAssets is only server-only, but that's quite inconvenient when useAssets doesn't work for ssr that is streamed. Is there a solution to this?
Like I mentioned, you add deferStream: true
to the resource that you want to "await" before sending the initial HTML.
const [data] = createResource(fetchData, {
deferStream: true,
});
return (
<Suspense>
<h1>{data()}</h1>
</Suspense>
);
Btw. what is actually streamed, the hydratable html or only the data?
SSR sends first the initial HTML. If any Suspense boundary is triggered and the resource that triggered it is a streaming resource, the initial HTML only includes the fallback
UI. When the resource resolves, the data is streamed to the client, alongside the "success" UI of the Suspense (this is the template
element you are seeing).
And why doesn't useAssets work on the working page of my example, which should be completely rendered on the server without suspending:
If you're referring to the snippet combined with createResource
, it still won't work, as it behaves in a similar way as your original repro. Point is once the resource resolves and Suspense tries to render the success UI, the initial HTML has already been sent, so there's no way to insert the new styles.
from solid-start.
When the resource resolves, the data is streamed to the client, alongside the "success" UI of the Suspense (this is the template element you are seeing).
Uhh ok that makes sense. But the point I wanted to make is that when the "success" UI is rendered on the server how should I be able to add styles inside the "success" UI, when I can't use useAssets
, because the initial html is already sent and on the other hand the "success" UI is rendered on the server so I don't have access to the client.
Additionally what I don't understand is why not already inline the template when the "success" page is already available? I mean I can clearly see that in the template that is contained in the initial html the data is already filled in. I don't know if that was excatly the behaviour, but I would love to see a hybrid solution. So that all data that is responed before the initial html is sent is instantly inlined so that the user never sees the loading fallback and if the data fetching takes longer than ssr than we dynamically switch to streaming.
I cannot imagine that this is so difficult, because as pointed out the template
where everything is there is included in the initial html. So clearly there must be some logic that optimizes that and adds the template immeditely without requireing to stream it. It just doesn't inline it.
Or is there a catch i didn't think of yet?
If you're referring to the snippet combined with createResource, it still won't work,
No I actually was referring to the snippet without createResource, which should in theory work, but it unfortunately doesn't
from solid-start.
Additionally what I don't understand is why not already inline the template when the "success" page is already available?
The thing is, it isn't. The same concept applies to how this doesn't work:
let example = 'Loading';
Promise.resolve().then(() => {
example = 'Success';
});
console.log(example); // Loading
I mean I can clearly see that in the template that is contained in the initial html the data is already filled in. I don't know if that was excatly the behaviour, but I would love to see a hybrid solution
Browsers can batch chunks but the server doesn't know this and cannot make this kind of assumption.
I don't know if that was excatly the behaviour, but I would love to see a hybrid solution. So that all data that is responed before the initial html is sent is instantly inlined so that the user never sees the loading fallback and if the data fetching takes longer than ssr than we dynamically switch to streaming.
Which is what I recommended: deferStream: true
from solid-start.
Ok so tell me if I understood that correctly. Streaming means that the solid server renders everything until it hits a suspend boundary and immediately sends this to the browser, but it doesn't close the response stream. Instead it waits for all those resources and each time one finishes it renders it and emits a template in the response stream.
But why does the browser even render the html page before it even has the whole picture, elements on the end of the document could change the whole page?
Nevertheless, I know now what I want. I want a threshold that I can specify. Per default all resources should be evaluated deferred unless they take longer than the specified threshold (lets call it 300ms), after that period of time the server finishes rendering the rest and streaming the remaining resources when they have finished. This combines both worlds and optimizes layout shift and time to first byte.
Last but not least, I still need an alternative to useAssets
so that we can push styles when streaming, this is a must have if we want to support streaming, because some conditional styles cannot be known ahead of time. Do you have any idea how I could solve that. With that knowledge I would make a pr to suid
so that it also supports server side streaming or how this is called.
from solid-start.
Thanks for your detailed explanation. But what about useAssets
in streaming mode?
from solid-start.
If you want the 0.3.10 async default you can just pass it in to createHandler. We default to streaming now but you can have the previous behavior.
createHandler(() => <StartServer />, { mode: "async" })
Streaming we've been using SolidMeta to do the split between assets that come from useAssets
and adding them on the page in the client. We are looking at isomorphic handlers for assets that work seamlessly with streaming in Solid core. @lxsmnsyc has opened some PRs that I'm yet to review.
from solid-start.
Ahh thanks for your info, the thing with the async
mode I have also already found out, but thanks for making it clear.
I will close the issue now, because everything is clear now and this has been more a discussion than an issue.
Have a nice day, @lxsmnsyc and @ryansolid
from solid-start.
Related Issues (20)
- [Bug?]: client only doesn't work anymore for `props.children` HOT 6
- [Bug?]: Catch-all that starts with number after ellipsis in filename causes hydration errors in nested paths on dev HOT 1
- [Bug?]: Latest Vinxi (>= 0.3.11) causes layout shifts in dev HOT 4
- [Feature?]: Error Handling with solid-router HOT 8
- [Bug?]: Vite server config is being ignored HOT 4
- [Bug?]: Namespaces are completely stripped out of code HOT 4
- [Bug?]: error while importing module, related to `.` in path-name HOT 1
- [Bug?]: createHandler context only called once, renders nonce useless HOT 1
- [Bug?]: Client Only component displayed in app.tsx causes hydration errors HOT 1
- [Bug?]: No value attribute on CSR, but present in SSR HOT 5
- [Bug?]: Typescript error in tsconfig.json for new projects created with pnpm. HOT 1
- Redirect doesn't early exit component when loading from browser address bar HOT 3
- [Bug?]: Frequently generate app.config.timestamp_.js files when i change app.config.js file HOT 1
- [Bug?]: Flakey Hydration Error Key 0-0-0-0-0-0-0-5 HOT 4
- [Bug?]: API routes in file based Route Groups don't work in RC0 HOT 5
- [Bug?]: Extend Solid config causes TS Errors HOT 2
- [Bug?]: Dev server fails to start when installing with new pnpm lockfiles HOT 3
- [Bug?]: The example in the docs doesn't seam to work. HOT 14
- [Bug?]: Issues with API/component routes in routes with parameters in RC1 HOT 3
- [Bug?]: RouteDefinition throw redirect not working 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 solid-start.