The 0kb Next.js blog
Update 3rd April 2023
Ok so this was a little bit clickbaity, but it's not technically a lie. This entire website has zero JavaScript on every single page... a Next.js app with zero client side JS. How can this be possible?
Context
Next.js is a huge abstraction of ReactDOMServer and other helpful utilities for building server side rendered apps powered by React. It's really easy to get started with, and features things like file system routing, statically generated content and much much more. I'm not trying to advertise it but I really really love it. There are a couple things to take in from the first sentence here, server side rendering and React.
For those of you who are not familiar with React, it's a JavaScript framework for building user interfaces. It handles the view layer of an app and is used to render the UI. Next.js takes this a step further and allows you to write your own view layer to have the first render performed on a server, which allows for a lot of performance and UI optimizations because we can ship back a lot less to the client (foreshadowing).
Runtime JS
With something called the Next.js PageConfig
, we can instruct Next.js to supply zero runtime JS to the client. It comes with a couple trade offs but the general idea is that we perform our first render on the server (executing JavaScript) and the resulting HTML and CSS is "frozen" and sent down to the client over the wire. Zero JavaScript runtime in the browser, no <script>
tags in sight!
Why not...?
As the saying goes, there's no such thing as free lunch. As with anything, doing this comes with some tradeoffs. For example, Next has a lot of built in React components that can speed up not only your app, but also development speed. Using the zero kb mode, we unfortunately cannot make full use of the next/link
component; a component that prefetches pages so that clicks on links don't cause a full page reload. Additionally, we cannot use next/image
as this also requires some minimal runtime JavaScript (a regular img
works just fine). This also means zero state updates or literally any JavaScript that would've otherwise been bundled can run.
However, apart from that, we are able to eliminate all JavaScript completely. No more worrying about installing momentjs and watching your user count drop in realtime. See your gorgeous website in pure static HTML & CSS. Gone are the days of bundlephobia.com... I bet at this point you are itching to know how to enable it. Well, here's a quick example:
import {PageConfig} from 'next';
export const config: PageConfig = {
unstable_runtimeJS: false,
};
export default function IndexPage() {
return <h1>This page has no JavaScript!</h1>;
}
import {PageConfig} from 'next';
export const config: PageConfig = {
unstable_runtimeJS: false,
};
export default function IndexPage() {
return <h1>This page has no JavaScript!</h1>;
}
And boom! just like that, 0kb bundle. If you are going to use this though, just bear in mind that as well as the trade offs mentioned above, you literally cannot use any JavaScript in the client anymore for this page. Zero. Nada. Null. Void. That means no state updates, no SWR requests. No useEffects
(thank god tbh).
p.s please check out my twitter @alistaiir :)