API Pipelining
As shown above, you can reduce the time taken for initial rendering by simultaneously initializing the React app and making API requests in the entry file. By utilizing the Stackflow Future API, you can implement API pipelining in a clean manner.
entry.ts
import { makeTemplate } from "@stackflow/plugin-history-sync";
import { config } from "./stackflow/stackflow.config";
async function main() {
let initialLoaderData: unknown | null = null;
for (const activity of config.activities) {
const t = makeTemplate({ path: activity.path });
const match = t.parse(location.pathname + location.search);
if (!match) {
continue;
}
// 1. Request API data (do not await)
initialLoaderData = activity.loader({ params: match as any });
break;
}
// 2. Download the React app simultaneously.
const { renderApp } = await import("./renderApp");
// 3. Combine them.
renderApp({ initialLoaderData });
}
main();
By passing initialLoaderData to Stack, it overrides the result with the received loaderData instead of executing the first loader.
renderApp.ts
export function renderApp({ initialLoaderData }: { initialLoaderData: unknown }) {
const root = ReactDOM.createRoot(document.getElementById("root")!);
root.render(
// Error and loading handling is possible in React
<ErrorBoundary>
<Suspense>
<Stack initialLoaderData={initialLoaderData} />
</Suspense>
</ErrorBoundary>
);
}