Abstract
Static sites are great. They are fast, cheap, secure, and easy to maintain. But generating static assets is a process that takes more and more time while our site gets bigger. We will talk about Incremental Static Regeneration (ISR), a feature that Next.js framework offers us to generate static pages at runtime. With it, we get the benefit of static, but supporting dynamic data and page re-rendering on demand.
We will talk about static web pages, static site generation and, in particular, Next.js. We will present Next.js Incremental Static Regeneration (ISR). We’ll see how it works and code a little example.
Transcript
This transcript was autogenerated. To make changes, submit a PR.
Hello everyone, my name is Fakundo and today we will talk about
incremental static regeneration. First of
all, I want to introduce myself. I'm Facundo Giuliani from Buenos
Aires, Argentina. I'm a developer relations engineer at
Storyblock. I'm also an odd serial ambassador,
a prism ambassador and a clothingary media developer expert.
It if you want to talk about any of these services
or tools, or if you want to talk about any other thing,
you can contact me. My website is fjuliani.com
and I'm on Twitter. My handle is fakundosurdo.
So first of all I wanted to define
what a static web page is. It is a web page
that is delivered to the user's browser exactly as
it's stored. So we can have a web page that
has an HTML file, CsS file and JavaScript
file that we will call it static page.
If we are delivering the same files to all the users that
visit our website no matter any condition.
This doesn't mean that the content of the page ISR
going to be static. I mean we can have interactions and
dynamism, but we will use that
or we will generate this using JavaScript,
but the files that we are going to deliver to all the users that are
visiting our website will be the same.
Different is the case of the dynamic web pages,
which are web pages where some of the content is generated dynamically
when needed. So depending on the user
that is visiting our website or other conditions,
we will generate HTML content dynamically
on the fly and we will return that to the
user as if it were an HTML page
that was statically stored on the website.
The user won't know that we have
two main methods of rendering this
dynamically generated HTML content.
One of these methods is the server sites rerendering,
where the HTML content is generated by the web server
and return it to the user as if it were an
HTML file. But on the other hand, we have
the client side rendering where the HTML
content ISR rendered directly in the browser using JavaScript.
So this will be the example of a react application, for instance,
where we have JavaScript code being executed
in the user's browser and generating HTML
content dynamically. So we can choose
these types of rerendering HTML content if we
want to generate it dynamically, let's say.
But let's go back to the static web page because even
though this was the first type of web pages that we were
able to create on the instance,
they have some cool benefits that we can
identify and that we can get advantage of even
in these times in these years. For instance,
static web page isr fast because we are delivering static assets
to the users without doing any kind of
processing or any dynamic generation
of content. The static web pages are cheap
because we will need sites, sorry,
web servers that will store these static
assets and deliver them to the users without doing
any process. Or we don't need any calculus to
be executed so they can only
store the files and deliver them to the users that are visiting our
websites. The static web pages are
easier to maintain because as any other file system
we can move sites from one side to the other.
They are more secure because we are not executing
code on the flight, so we don't have to worry about
securing any kind of code execution.
They are easy to scale because adding more storage
space to our web servers we will be able to scale
the static websites that we are working on. So for
instance, if we have a blog and
we are creating more and more articles and blog posts in
our website, just adding more storage space to
the web server will help us to scale
our website. And they are stable
because as we are not executing code or doing operations
on the flight, the visitors will only have to download
the files to their browsers and will browse
the website. So that will make our website
to work more stable. So having
all these benefits in mind, a new concept
was created. The concept of static sites generation which
ISR compiling and rerendering a web application
at build time, generating static assets like HTML,
JavaScript and CSS files.
So we will have a project
with a templating engine.
Depending on the programming language that we want to use, we can
have different templates that we can use and besides these templates,
we will have data sources like APIs that
we can consume, headless CMS or
content management systems. We can have databases,
we can have processes that are being executed and based
on these operations and these data sources and these
templates, we will run a build process using
a static site generator and we will
generate static assets that are going to be
my website, I mean my static website.
So we can work with different tools,
modern tools to create our projects and our
websites and generate static assets as if it
were a static sites like the ones that we
created in the said.
So there are different static site generators that we
can use and there are a lot of options in the market
depending on the framework or the programming language that you want to use
today. I will focus on next JS which is a react
framework that allows creating user interfaces,
static pages and server side rendered pages.
So we can create different pages
using react components and all the features that react offers
us. And next JS offers a page based
way of working. So we will have one JavaScript file
per page in our website or we can work
with dynamic roots that one JavaScript
file will generate multiple pages. Like for
instance we can create one JavaScript file with nextjs
code to generate all the blog posts that we
can have in our blog
site and we can use static site
generation to generate all these
static assets at build time. So we will
have all the blog generated and it will be
all static assets like HTML files, JavaScript files
and CSS files and we can deploy that to the web server.
So we will have our website using static
assets, but we created it using JavaScript
and a react framework like netjs.
What is cool about nextjs is that it also
offers other takes of rendering and generating HTML
content like server side rendering or client side rerendering
as we mentioned before. And it also offers API
roots that we can use as serverless functions, for instance to
execute an API, an operation and return information
to our pages that we can use to render HTML
content. And it also has a fast refresh
on develop environment. So if we are working locally and we are
working with the static sites generation mode,
we don't have to wait to generate the static asset whenever
we are making or applying a change to our
code, we will have it automatically
updated in our browser while we are working.
Another cool thing that Nextjs offers is that
we can work with the different types of rendering in
a page level. So we can have some pages that are generated at
build time using static site generation
and other pages that can be generated using server
side rendering or client side rerendering, all living in the same
project in the same website. So for instance
in the case of the blog, we can create the home
page and probably the latest ten
blog posts at build time as a static pages
and we can have the older blog posts that probably will be visited
by less users to be generated using
server side rendering or client side rendering.
If we want to offer the same experience in all the
blog posts that we have in our website or our
blog site, we can generate all of them using
static site generator at build time.
But here comes a problem. Because the process
of generating the static assets takes some time
and if our website is
getting bigger and bigger with more and more pages,
this build time will increase more and
more. So in the case that we want to add a new blog post
to our platform, or in the case that we want to edit one page
to our website. If we want to generate
all the static assets at build time, this process will take
longer and longer. And besides
that, there is a concept that is called atomic deployment,
which means that if we are using static site generation,
we have to generate all the static assets
that we need at build time without errors.
If there's any error in the middle of the process or
if there isr a page that we are not generating statically,
we will roll back all the process and we won't deploy
this version of the website. This is done so
we don't break the compatibility between the different pages
and we don't have different pages or different versions of the pages
living at the same time. So we
have our blog or for example our ecommerce
platform and we are increasing more and more products to the
ecommerce platform and we are building the whole website whenever
we add a new product or whenever we change something related to a
product. And this build time is getting longer and longer and
longer. And that's something that probably won't work for our
scenario. So to solve this problem,
NextJs now offers a new feature which
is called incremental static regeneration.
This feature enables developers to use static site
generation on a per page basis without
having to rebuild the entire site.
So we will have the build process of the static
site generator running for the first time
and we will generate the version one of our pages,
let's say after we generate all the pages
that we need, we will deploy them to the web server
and we will cache the first version of
these pages. We will have a
property called Revalidate that we can set in a
steroids value so we can set for instance 60
steroids. In that period of time, all the users
that visit our website will see the version that
is cached of the pages, the first version.
But if a visitor comes to our website and
wants to visit a certain page after this revalidate
time, nextjs will display
the version one of the page, the one that is cached
but in the background will execute a
build process to regenerate only this page
in the background, generate a new version and after
that deploy that to the web server and cache this version.
So all the following users that will visit this
page will see this version two of the page.
So in case that we are editing the content of this page
or we fix the typo or we are adding some more content
to the page. This is a cool feature because
we don't need to reveal the complete site. We will
have this revalidate time to work for us and to
generate the new version of the page when we need it.
So this offers us or
disallowed us to have faster bills because
in case that we want to generate just a set
of static pages, or we can work with a higher
cache so we can cache all the static assets of
our website and generate all of them at build time,
and after that generate one page at a
time when it's needed, just when it's needed.
This is cool that we can link this property
to a headless CMS. So in case that we have a team
of content editors working on our blog post for instance,
or the content of our website and they are making changes.
We don't have to run the build process whenever they
apply a new change or whenever they create new content.
We will just run the build process per page and
when needed, I mean when a visitor comes to our website
after this revalidate time.
One other thing that incremental static regeneration offers is
that the pages that are generated are persisted
between deployments. So if we deploy new version
of our website, we will persist
the pages that we generated before using incremental static
regeneration. This is a problem that we have to
evaluate because we are breaking the atomic deployment doing
this. I mean we will have pages of different versions
living at the same time, but probably this is something that can
help and we can solve a certain scenario using
incremental static regeneration.
I will show you a quick demo so you can see how each one of
these rendering methods works.
So what I'm going to do is go to this project,
this page that I created a title and three features.
We can see that I'm using a
nextjs application that is running locally in my computer and
I'm having the same content which will
return the same page using three different methods of rendering,
server side rendering, static site generation and
incremental static regeneration.
So we can see that this page is using server side
rendering which is the content. This content is generated
for every visitor that we will have in our website. I mean
every user that code to our website, we will
execute the code to generate the HTML content
for them.
Besides that we will have the static site generation method
where we have here the same content. But this was
generated at build time. When I run a build process
at the beginning to generate the static assets with this
example, probably you can see the benefit, but this
page will load faster because we are not rendering any content on the flight
like we did with the server side rendering.
And finally we will display incremental static
regeneration where this pages was
generated at build time also. But if we run
it again we have the revalidate feature running. But again
as I didn't change any content you can see any
change here. What I'm going to do now
is show you the code of my application.
This is a neck JS project. I don't want to go
super deep into the folder structure of nextjs and
how Nextjs works, but this is the boilerplate
that nextjs generates when we
execute create next app using
npm in our local computer.
So what we have here isr a pages folder and
each one of these is the URL that we
were visiting in the example that I just displayed.
And these ones are Javascript files you
can see with dynamic roots. We are
using the slugs for the dynamic roots.
So what we are doing in this particular case is for
server side rerendering we have the main function here
which is the one that generates the markup for our pages.
We have some react components here that are
using some story, that code from
our headless cms which in this case is a storyblok.
And I will show you storyblok in a couple of minutes and
we are bringing information from the headless cms to render it
on the page. So we have this main
function that will generate the markup and we have a get server
sites props function that is executed whenever
a user visits our website. So in
this code what we are doing is setting a slug variable
with the home value because we are going to bring all
the information related to the home page and well
setting some parameters that we will send to the headless cms and
using the storyblock client to get all the information
related to that story. One story
in storyblock is like a page, let's say.
So we are bringing all the data, all the content for that
page. We are returning that as a story and
this return is going to the main function and
using the story that we are sending to generate
the content related to that story.
We will execute this function for every user
that visits our website. On the other hand,
the static site generation version
of the page is using the same main
function. You can see that it's exactly the same,
but we have a gets static props method
or function that ISR executed at build time. When we run
the static site generation process you
can see that we are doing something very similar
here. We are bringing all the data related to
a certain story using the storyblok client and
we return that to the main function. But the thing
is, how do we identify which pages
we want to render at build time. So to do that
next, Js offers another function which is called
get static paths. So what we are doing here
is defining the logic that will generate the list of
pages of pages that we want to generate
at build time and generate the static assets related to them.
As my project has only one page which is the home page,
we are sending like a list of paths but with only
one value which is home. So with this
list we execute the get static props function
for every value of this list and we will
generate the markup. Finally, the incremental
static regeneration page ISR,
the main function is exactly the same and you will see
that it's very similar to the one of the static site
generation. Here we are doing exactly the same and
here is very similar. But we are setting this
property fallback to blocking and we are adding the revalidate
value that we saw before in the slide
and we are setting that to 10 seconds.
So when a user visits our website after
10 seconds we'll run the build process in the
background to generate a new version of the page.
So let's see in this example what happens if
I edit the content of the page.
So let's go to storyblok which is the headless CMS.
And you can see that. Well, Storyblok offers a visual editor,
a real time visual editor that we can use to using
the code of our application. You can see that it's pointing to my local
host. We can on the flight do some changes
and see how it's going to look like. So I can change
this feature test and we can see that how
it's going to look like without applying any change
to the real content that we are consuming
in our production instance, for instance.
But if I click on Save, we are applying
these changes to the draft version of
our steroids or the content of our page of our
website. So we have all the features
that say now feature test. So I will
go back to my example and I will first
render the server side rendering page.
What is happening? We are displaying the new content because we are
rerendering this content for each time a user visits
our web page. But on the other hand, if I
use static site generation, we will see that we
are seeing the old content because
this page was generated at build time and I didn't
run the build process again. So we have the version that was
generated before as a static asset. So we
don't notice that a change was applied to the content of the pages
using incremental static regeneration we
will see that we are displaying the old content
that was generated at build time,
like if it weren't edited or updated.
But on the background we are executing a build
process just for this pages. So I
mean this visitor won't notice the changes or will
see the old version of the page. But if I refresh the page
here I will see the new content and I am seeing
the version two of the page, let's say. And this will
happen for all the following users that visit this
web page, always considering
the revalidate property and the value of this property
that we set in the code of our application.
So with this demo, I hope it's now clear
for you how incremental static regeneration works.
If you want to learn more about it, you can go to the Nextjs official
website. They have an e commerce platform demo that
you can take a look using incremental static regeneration. Or if
you want to learn more about NextJs, they have a really
cool learning platform that you can follow and learn other
features from this very cool framework.
So thank you very much. I hope you enjoyed the talk
and see you there.