constLazyText=lazy(()=>({then(cb){cb({default:Text});// this is "sync" thenable},}));constroot=ReactTestRenderer.create(<Suspensefallback={<Texttext="Loading..."/>}><LazyTexttext="Hi"/>// this lazy is not very lazy</Suspense>,
);
importReactfrom'react';constrealLazy=React.lazy;React.lazy=importer=>realLazy(syncImport(importer));React.Suspense=React.Fragment;// :P// ^ React SSR just got fixed :D
Loadable Components is an MIT-licensed open source project. It's an independent project with ongoing development made possible thanks to the support of these awesome backers. If you'd like to join them, please consider:
For "power users" the traditional SPA is dead. If you're not universally rendering on the server, you're at risk of choking search engine visibility. As it stands, SEO and client-side rendering are not a match for SSR. Even though many search engines claim better SPA indexing, there are many caveats. Server-side rendering matters: JavaScript & SEO Backfire โ A Hulu.com Case Study
The real problem has been simultaneous SSR + Splitting. If you've ever attempted such, you know. Here is a one-of-a-kind solution that brings it allโฆ
SSR is a good thing, but, you know, hard. Small projects might want to have a SSR โ there are a lot of reasons to have it โbut they might not want to setup and maintain it.
SSR could be really, REALLY hard. Try razzle or go with Next.js if you want a quick win.
So the easiest my solution for SSR, especially for simple SPA would be prerendering. Like opening your SPA in a browser and hitting "Save" button. Like:
React-snapโ-โuses puppeteer(aka headless Chrome) to render your page in a "browser" and saves a result as a static HTML page.
Rendertronโ-โwhich does the same, but in a different (cloud) way.
Prerendering is "SSR" without "Server". It's SSR using a Client. Magic! And working out of the boxโฆ โฆ โฆ but not for code-spitting.
Soโ-โyou just rendered your page in a browser, saved HTML, and asked to load the same stuff. But Server Side Specific Code (to collect all used chunks) was not used, cos THERE IS NO SERVER!
In the previous part, I've pointed to libraries which are bound to webpack in terms of collecting information about used chunksโ-โthey could not handle hybrid render at all.
Loadable-components version 2(incompatible with current version 5), was partially supported by react-snap. Support has gone.
React-imported-component could handle this case, as long as it is not bound to the bundler/side, so there is no difference for SSR or Hybrid, but only for react-snap, as long as it supports "state hydration", while rendertron does not.
This ability of react-imported-component was found while writing this article, it was not known beforeโ-โsee example. It's quite easy.
And here you have to use another solution, which is just perpendicular to all other libraries.
๋ฏธ๋ฆฌ ๋ ๋๋ง ์ด์ ๋ธ๋ฆฌ ๋ฐ์
This library was created for partial hydration, and could partially rehydrate your app, keeping the rest still de-hydrated. And it works for SSR and Hybrid renderers without any difference.
The idea is simple:
during SSRโ-โrender the component, wrapped with a
on the clientโ-โfind that div, and use innerHTML until Component is ready to replace dead HTML.
you don't have to load, and wait for a chunk with split component to NOT render a white hole instead of itโ-โjust use pre-rendered HTML, which is absolutely equal to the one a real component would render, and which already exists - it comes with a server(or hybrid) response .
That's why we have to wait for all the chunks to load before hydrateโ-โto match server-rendered HTML. That's why we could use pieces of server-rendered HTML until the โclient is not ready - it is equal to the one we are only going to produce.
import{PrerenderedComponent}from'react-prerendered-component';constimporter=memoizeOne(()=>import('./Component'));// ^ it's very important to keep the "one" promiseconstComponent=React.lazy(importer);// or use any other library with ".prefetch" support// all libraries has it (more or less)constApp=()=>(<PrerenderedComponentlive={importer()}>{/* ^ shall return the same promise */}<Component/>{/* ^ would be rendered when component goes "live" */}</PrerenderedComponent>
);