Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prefer build-time and render-time server-rendering to the SSG/SSR dis… #4566

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

eric-burel
Copy link

@eric-burel eric-burel commented Apr 8, 2022

Ok, this sounds like a weird change, but bear with me. I've been doing some formal research on SSR and I am convinced that we can vastly improve the current state of the industry by starting to use some better wording. Namely, we could reduce the energy consumption of React apps.

SSG and SSR is the terminology chosen by Next to distinguish build-time and request-time server-rendering. This terminology is historical, and well accepted, as most people mean "it's rendered at request-time, server-side" when they say SSR, and "it's rendered at build-time, server-side" when they say static.

Should we keep pushing this terminology? No, I can prove formally why it's wrong.

  • It confuses many people, that don't get why "Server-Side Rendering" doesnt just mean "it's rendered on the server"

  • People believe that there are 2 ways to do server-render. It's been true for a while but many technologies are exploring the space in between: Next.js ISR, Gatsby Deferred Static Rendering.

  • It opposes SSR and SSG. If you see server-rendering as a big cache system for the web, SSG is simply a cache warm at build-time. SSR is a "cache miss". Next.js got it correctly, as ISR is "a cache that fills up when requested", well... like any good cache should do :)

I prefer to oppose "rendering times", so "Request Time Rendering" and "Build Time Rendering" for instance, making it clearer that those are not really incompatible choices, just configuration choice about when you render a page.

  • It has been hindering further research on websites optimization. Namely, people think you cannot use the Request object during static generation. They limit staticness to basic use cases.

SvelteKit states "The basic rule is this: for a page to be prerenderable, any two users hitting it directly must get the same content from the server."
This is maybe true for SvelteKit, but not true in the general case. I've heard the same idea from Gatsby, Astro. Even Next says that getStaticProps should be used when "The data can be publicly cached (not user-specific)" (which is all the more funny that I've coded a demo that bypass this limitation... using only Next.js, and Vercel Platforms also does this)

With a simple redirection proxy (not even a full-fledged server, just something that can read "req" and redirect to any URL), you can bypass this limitation. If you don't believe me, check Vercel Platforms implementation. It uses a tiny middleware and is able to prerender the same page for different tenants.

The problem is that the SSG/SSR distinction makes this way less obvious. The term "static" implies "there won't be any request processing". That's true at the app level, but apps are still run on servers. We can still put proxies in front of them. Therefore, we can make the "static"... dynamic again, and imagine incredible optimization, like prerendering paid, private, A/B tested, themed, internationalized, multi-tenant content without even running any Node server.

So, to sum it up, I believe this sentence is more correct this way.

Related PR on Next.js docs: https://github.com/vercel/next.js/pull/36018/files

…tinction

Ok, this sounds like a weird change, but bear with me. I've been doing some [formal research on SSR](https://tinyurl.com/ssr-theory) and I am convinced that we can vastly improve the current state of the industry by starting to use some better wording.

SSG and SSR is the terminology chosen by Next to distinguish build-time and request-time server-rendering. This terminology is historical, and well accepted, as most people mean "it's rendered at request-time, server-side" when they say SSR, and "it's rendered at build-time, server-side" when they say static.

Should we keep pushing this terminology? No, I can prove formally why it's wrong.

- It confuses many people, that don't get why "Server-Side Rendering" doesnt just mean "it's rendered on the server"

- People believe that there are 2 ways to do server-render. It's been true for a while but many technologies are exploring the space in between: Next.js ISR, Gatsby Deferred Static Rendering.

- It opposes SSR and SSG. If you see server-rendering as a big cache system for the web, SSG is simply a cache warm at build-time. SSR is a "cache miss". Next.js got it correctly, as ISR is "a cache that fills up when requested", well... like any good cache should do :)

I prefer to oppose "rendering times", so "Request Time Rendering" and "Build Time Rendering" for instance, making it clearer that those are not really incompatible choices, just configuration choice about when you render a page.

- It has been hindering further research on websites optimization.  Namely, people think you cannot use the Request object.

[SvelteKit](https://kit.svelte.dev/docs/page-options#prerender-when-not-to-prerender) states "The basic rule is this: for a page to be prerenderable, any two users hitting it directly must get the same content from the server."
This is maybe true for SvelteKit, but not true in the general case. I've heard the same idea from Gatsby, Astro. Even Next says that getStaticProps should be used when "The data can be publicly cached (not user-specific)" (which is all the more funny that I've coded a demo that bypass this limitation... using only Next.js)

With a simple redirection proxy (not even a full-fledged server, just something that can read "req" and redirect to any URL), you can bypass this limitation. If you don't believe me, check [Vercel Platforms implementation](https://github.com/vercel/platforms). It uses a tiny middleware and is able to prerender the same page for *different tenants*.

The problem is that the SSG/SSR distinction makes this way less obvious. The term "static" implies "there won't be any request processing". That's true at the app level, but apps are still run on servers. We can still put proxies in front of them. Therefore, we can make the "static"... dynamic again, and imagine incredible optimization, like prerendering paid, private, A/B tested, themed, internationalized, multi-tenant content without even running any Node server.

So, to sum it up, I believe this sentence is more correct this way
@facebook-github-bot
Copy link
Collaborator

Hi @eric-burel!

Thank you for your pull request and welcome to our community.

Action Required

In order to merge any pull request (code, docs, etc.), we require contributors to sign our Contributor License Agreement, and we don't seem to have one on file for you.

Process

In order for us to review and merge your suggested changes, please sign at https://code.facebook.com/cla. If you are contributing on behalf of someone else (eg your employer), the individual CLA may not be sufficient and your employer may need to sign the corporate CLA.

Once the CLA is signed, our tooling will perform checks and validations. Afterwards, the pull request will be tagged with CLA signed. The tagging process may take up to 1 hour after signing. Please give it that time before contacting us about it.

If you have received this in error or have any questions, please contact us at cla@fb.com. Thanks!

@github-actions
Copy link

github-actions bot commented Apr 8, 2022

Size Changes

📦 Next.js Bundle Analysis

This analysis was generated by the next.js bundle analysis action 🤖

This PR introduced no changes to the javascript bundle 🙌

@facebook-github-bot
Copy link
Collaborator

Thank you for signing our Contributor License Agreement. We can now accept your code for this (and any) Meta Open Source project. Thanks!

kodiakhq bot pushed a commit to vercel/next.js that referenced this pull request Apr 15, 2022
<!--
Thanks for opening a PR! Your contribution is much appreciated.
In order to make sure your PR is handled as smoothly as possible we request that you follow the checklist sections below.
Choose the right checklist for the change that you're making:
--

## Documentation / Examples

- [ ] Make sure the linting passes by running `yarn lint`
** I've made the change via GitHub UI sorry :)**

Hi, 

I think the "data must be public" condition on getSSP is not really true, and even counter-productive. Being able to statically render more content is most probably positive, in terms of perceived and real performance of the app + energy consumption. It's actually totally possible, and not even that hard thanks to middleware, to statically render custom, paid, segment-specific content (and even individual-specific content under certain conditions).

I've documented the reason for this change in a few places if you want more details:
- related PR on React: reactjs/react.dev#4566
- demo implementation and explanation on how to couple middlewares and getSSP to statically render any kind of content (including custom content): https://blog.vulcanjs.org/render-anything-statically-with-next-js-and-the-megaparam-4039e66ffde
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants