Next.js-like framework for server-rendered React apps built with React Router
After.js has first class support for SSG and allows you to create super fast static web apps and serve them over CDN. (needs razzle 4)
renderStatic
will return the data from getInitialProps
and this data will get saved by razzle into a file called page-data.json
. After.js won't call getInitialProps
at runtime, instead it will read the page-data.json
and pass it as a prop to your component.
from ./src/static_export.js
you should export render and routes function.
async render(req, res)
should render your app into html and at the end it should return html and data.async routes()
should return path for pages you want to statically generate.// ./src/static_export.js
import { renderStatic } from '@jaredpalmer/after';
import appRoutes from './routes';
const assets = require(process.env.RAZZLE_ASSETS_MANIFEST);
const chunks = require(process.env.RAZZLE_CHUNKS_MANIFEST);
export const render = async (req, res) => {
const { html, data } = await renderStatic({
req,
res,
routes: appRoutes,
assets,
chunks,
});
res.json({ html, data });
};
export const routes = async () => {
return ['/', '/about'];
};
after setting up this file you can build your app and run export script to generate your static site:
yarn build
yarn export
in instant mode, getInitialProps gets called and at the same time the page scrolls to the top in blocked mode, getInitialProps gets called and then when the promise that returned from it get resolved we scroll to top
isLoading
prop now gets injected to page componentsisLoading
prop shows that if getInitialProps
is in pending state
or not
function HomePage({ isLoading, error, data }) {
if (isLoading) {
return <Spinner />
}
if (error) {
return <span>something went wrong</span>
}
return <MyComponent data={data} />
}
HomePage.getInitialProps = () => {
try {
const { data } = await fetchHomePage();
return { data }
} catch (error) {
return { error }
}
}
<After />
// transitionBehavior: instant | blocked
<After transitionBehavior="instant" /> // default is `blocked`
blocked behavior (default):
navigation event occurs
-> wait until getInitailProps get finished
-> render the next page with injected props (I mean results of the getInitailProps)
instant behavior:
navigation event occurs
-> call getInitailProps
-> render the next page
-> re-render component when getInitailProps is finished with injected props
<After />
transitionBehavior: instant | blocked
the default for value for transitionBehavior
prop is blocked
(we can also change the default to instant
but it's going to be a breaking change)
blocked behavior (default):
navigation event occurs
-> wait until getInitailProps get finished
-> render the next page with injected props (I mean results of the getInitailProps)
instant behavior:
navigation event occurs
-> call getInitailProps
-> render the next page
-> re-render component when getInitailProps is finished with injected props
We Skipped version 2, there was a problem with our deployments to npm so a canary release tagged as a stable release and ...
Upgrading to version 3 should not take more than 10 minutes.
In v1, with asyncComponent
you split part of your application into a new chunk, and on BROWSER when you need that part of your code it gets downloaded automatically. when page rendered on the server there was no way to understand which chunks needed for the current request so After.js only sends client.js
and styles.css
file, then on BROWSER with ensureReady
method it tries to fetch chunks (split CSS and JS files) needed for the current request. and it's slow!
browser must download client.js
, then parse it and at the end, it executes the code. when code gets executed ensureReady
method gets called, ensureReady
finds and download chunks needed to render the current page and when all files get downloaded it start to re-hydrate.
browser will render the page without CSS styles (because we split them and it will get them when ensureReady
called), this makes the site look ugly for 2,3 seconds (bad UX).
have you ever think about why CSS is render blocking?
if browser finds a <link rel="stylesheet">
tag, it would stop rendering page and waits until CSS file be downloaded and parsed completely (this mechanism is necessary to have fast page renders), if CSS files attach to dom after page gets rendered, the browser must repaint the whole page. (painting is too much job for browser and it's slow)
in After.js 2 this problem is solved and it sends all JS and CSS files needed for current requests in the initial server response.