ApiGW
GraphQL
HTTP
Server Components
Tailwind
Inline SVG
(getting the data)
(presenting the data)
Record
Playback
Expose
Connect
type Backend = {
getTopModelsAwards():Promise<CompetitionPageData>;
getAwards():Promise<CompetitionPageData>;
list(superCat:SuperCategory, filter:Filter):Promise<ListPageData>;
chatPage(displayName:DisplayName):Promise<ChatPageData>;
// ...
}
class ApiGwBackend implements Backend {
getTopModelsAwards():Promise<CompetitionPageData> { ... }
getAwards():Promise<CompetitionPageData> { ... }
list(superCat:SuperCategory, filter:Filter):Promise<ListPageData> { ... }
chatPage(displayName:DisplayName):Promise<ChatPageData> { ... }
// ...
}
ApiGW
GraphQL
HTTP
interface App {
route(path:UrlPath):VDom | Error | Redirect;
frame():VDom;
renderToString(res:VDom):string;
report(path: UrlPath, error: Error):VDom;
}
class LiveJasmin implements App {
constructor(backend:Backend) { ... }
// interface implementation here ...
}
Record
https://livejasmin.com/en/girls
Expose
Connect
Playback
Hydrate
ApiGW
https://livejasmin.com/en/girls
(empty)
Render
ApiGW
Record
https://livejasmin.com/en/girls
Playback
ApiGW
Hydrate
SPA | Hybrid |
---|---|
✅no application servers required | ✅ application servers only have to deal with initial response |
❌ suboptimal SEO | ❌ more data loaded |
❌ initial loading more visible | ❌ less opportunity for caching |
❌ more JavaScript shipped | ❌ more JavaScript shipped |
npm i
: 15s, npm run build
: 2sMetrics for list page PoC: