I am slightly confused about the merits of ssr and code splitting and and code splitting done solely on the client.
My thoughts are that server rendering the page first will lead to a better experience without all the javascript having to be parsed and then server rendered.
I am confused how code splitting fits into the ssr model, is it that ssr renders the first hit and then code splitting is done thereafter on the client?
React.Lazy makes a point of saying react.client is all done on the client. How would it differ from code splitting on the server. Is that if you go to a specific route then you retrieve that chunk for the first render?
I understand React.Lazy is all done on the clientside and they have made a real point of saying that. How would it differ if it was done on the server.
Is there any real benefit to ssr with code splitting. Does it not just add complexity?
lazy and Suspense? It's a library built on top of React. lazy. It takes care of asynchronously loading components as well as supports the SSR rendering of components.
Bundling is great, but as your app grows, your bundle will grow too. Especially if you are including large third-party libraries. You need to keep an eye on the code you are including in your bundle so that you don't accidentally make it so large that your app takes a long time to load.
Suspense enable you to perform route-based code-splitting without using an external package. You can simply convert the route components of your app to lazy components and wrap all the routes with a Suspense component.
js is one of the most popular frameworks to set up SSR for a React application and Express is a great option for creating the HTTP server.
Depending on your usecase you may use only SSR, only code-splitting or combine both as needed.
Better SEO since search bots have markup to work with (and not necessarily dependent on executing javascript) for indexing.
Faster initial render since markup is sent from the server, the browser doesn't has to wait on executing the javascript to render it. (Although the markup will still lack interactivity till react is hydrated client side).
Deliver critical CSS first. The critical CSS for the initial page render can be in-lined, better UX since the loaded markup will already have styles ready.
Simpler route splitting. SSR imo makes it simpler to reason about route splitting your application. For example, you may have different pages for /about
and /home
which you can route split to reduce bundle size (and preload other routes on client side if needed).
It might not be necessary to server render your entire page. For example, consider your homepage (which you wish to server render) includes a Chat
component so users can directly ask you questions.
If this component is big you may decide to not server render it so the user can get the most important bits of the page first. This would reduce your initial page load by code splitting this component in your homepage component.
When the browser has parsed the markup it would load your Chat
component after the main bundle. This way you could identify and keep your bundle sizes in check.
This is a perfectly fine way to build your application imo if you are not interested in the benefits of SSR.
For example, if your application is a user dashboard for authenticated users, it might be better to not worry about SSR at all and just code split your application. Also note that server rendering your application will take more time to send response on server (instead of plain REST APIs) since the markup has to be generated.
Coming to your questions:
I am confused how code splitting fits into the ssr model, is it that ssr renders the first hit and then code splitting is done thereafter on the client?
Yes, kinda. The browser receives the initial load from server, after that client takes care of loading the necessary bits. Now, you may decide to preload your components server side and send everything as well (please check react-loadable
which I mention at the end of this answer).
How would it differ from code splitting on the server. Is that if you go to a specific route then you retrieve that chunk for the first render?
lazy
is just a cleaner API with support for Suspense
for code-splitting. Ideally, when loading a route for the first time you would server render the initial markup and then let the client take care of loading next bits and routing. Imo Next.js does this really well.
How would it differ if it was done on the server.
You may preload all your components or only the necessary bits. Please check the Combining code splitting your components and SSR section.
Is there any real benefit to ssr with code splitting. Does it not just add complexity?
Everything has its own trade-off here imo. As I mention in the Only using code splitting section, its perfectly fine to just use code-splitting if your use case doesn't require the merits of SSR.
Note
Currently
lazy
(in React v16.6.1) doesn't support SSR completely. You might want to check outreact-loadable
to handle the cases where you wish to preload components server side.
Server-side rendering
When the page is requested, the server processes the request and builds the final HTML page which is then delivered to the client.
This approach favors SEO matter pages since the final content is available in the first request, therefore search engines are able to index it.
Code-splitting
If your entire website uses too many resources at different load times, code-splitting is the go-to technique for performance optimization. Instead of having all the resources load with the first request, you delay the loading until the resource is needed.
Implementing both together
Given the case that you have a website with lots of resources and you want to render the entire page requested before handling it to the client, you might want to implement both of this techniques.
React.lazy()
React.lazy() was implemented in React v16.6.0 as a new method of using the Suspense component to do code-splitting.
Note
This feature is not yet available for server-side rendering.
Suspense support will be added in a later release.
To sum up
Suspense + React.lazy() doesn't yet support server-side rendering.
Server-side rendering + code splitting allows for the client to get the requested rendered page without extra resources that aren't needed at the moment.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With