Speeding up build times in the Jamstack with DPR in Next.js
https://bit.ly/faster-jamstack
Developer Experience Engineer - Netlify
YouTube
Jamstack Explorers
Remotely Interesting podcast 
Mixologist
Get all my friends drunk at home for no reason at all

Kenny

What you'll learn
* Understand the term 'Jamstack'
* Understand DPR and the problem it solves
* See how to use DPR in a Next.js app
* Learn how to build faster Jamstack sites
* See a demo
Jamstack
Jamstack is a way of thinking about building the web where:
* The UI is compiled
* The frontend is decoupled, and 
* Data is pulled is as needed

https://jamstack.org/glossary/jamstack/

i.e that:
Has a build process that pre-generates the markup of the site in advance.

* The UI is compiled
i.e that:
Frontend part (of your app) is deployed separately and independent of any backend services.

 

* The frontend is decoupled
i.e that:
​Data Fetching happens mostly during the build but still possible when it is needed.
* Data is pulled in as needed
Summary
* Has a build process that compiles the site into pre-generated HTML

* The frontend is deployed separately and independent of backend services

​* Data Fetching happens mostly at build time but still possible when needed.
The Benefits
1. Your site is faster and users are happy (performance).

2. Search Engines would be your friends (SEO).

​3. You can go from 0 to 1k users with little to no effort (scale).

4. Security, DX, etc ...
What then is the problem?
Note really a problem, more like a tradeoff
For very large sites, the build times can get undesirably high.
If it took 1s to generate 1 page, it'll take 3,700s (1hr+)for this site to build
3,700​ pages
That's not all ...
Popular approaches
* Incremental Builds - Gatsby
* ISR - Next.js
* Sharding
* DPR 

 

Distributed Persistent Rendering
A new approach that encourages you to split your site into two main components, critical and deferred. Where the critical content is generated at build time and the rest at request time.
We are dealing with two overhaeds -
1. Lengthy build times for large sites.
2. full site re builds on site updates.
Before we proceed, a quick recap
DPR's offering
You can tell your build process to ignore other pages and only generate your site's critical pages. (i.e headlines WRT our earlier examples).


What about the deferred pages?
Requests for any deferred page will be generated at request time. The generated pages is then cached and returned for every subsequent call.
How is it different?
* It improves build times at both deploy and update cycles.

* It doesn't break core Jamstack principles like atomic & immutable deploys.

* It is framework agnostic.
How would it impact our current app? let's find out...
Reduced site build from 3,700s to 200s

 

== 94.6% decrease in build time

How ?
via On demand Builders (ODB) - A special type of serverless function that help bring the idea of DPR to life.

const { builder } = require("@netlify/functions")

async function myfunction(event, context) {
    // logic to generate the required content


exports.handler = builder(myfunction);
Create an On-demand Builder
const pageTemplate = require("../templates/product-details");
const fetch = require("node-fetch");

const { builder } = require("@netlify/functions");

const handler = async (event) => {
  const id = event.path.split("news/")[1];
  
  const result = await fetch(`${process.env.PRODUCTS_DATA}/${id}`, {
    method: "GET",
  })
    .then((res) => res.json())
    .catch((error) => console.log(error));
  

  return {
    statusCode: 200,
    headers: {
      "Content-Type": "text/html",
    },
    body: pageTemplate(result),
  };
};

exports.handler = builder(handler);
On-demand Builder in action
const pageTemplate = require("../templates/product-details");
const fetch = require("node-fetch");

const { builder } = require("@netlify/functions");

const handler = async (event) => {
  const id = event.path.split("news/")[1];
  
  const result = await fetch(`${process.env.PRODUCTS_DATA}/${id}`, {
    method: "GET",
  })
    .then((res) => res.json())
    .catch((error) => console.log(error));
  

  return {
    statusCode: 200,
    headers: {
      "Content-Type": "text/html",
    },
    body: pageTemplate(result),
  };
};

exports.handler = builder(handler);
What makes an On-demand Builder?
ODB
with
Next.js 
on Netlify
export async function getStaticPaths() {
  const res = await fetch(process.env.DATA);
  const newsItems = await res.json();
  
  const breakingNews = newsItems.filter((news) => news.tag == "breaking");

  const paths = breakingNews.map((news) => ({
    params: { id: news.id.toString() },
  }));

  /*
  console.log(paths)
  [
    { params: { id: '1' } },
    { params: { id: '2' } },
    { params: { id: '3' } }
  ]
  */

  return { paths, fallback: false };
}
Regular Next.js
export async function getStaticPaths() {
  const res = await fetch(process.env.DATA);
  const newsItems = await res.json();
  
  const breakingNews = newsItems.filter((news) => news.tag == "breaking");

  const paths = breakingNews.map((news) => ({
    params: { id: news.id.toString() },
  }));

  /*
  console.log(paths)
  [
    { params: { id: '1' } },
    { params: { id: '2' } },
    { params: { id: '3' } }
  ]
  */

  return { paths, fallback: true };
}
ODB in Next.js
Demo Time

https://next-odb-demo.netlify.app/news

https://app.netlify.com/sites/next-odb-demo/overview

Resources
* ODB with Next.js post https://ntl.fyi/3BfaLom
* On-demand builder docs https://ntl.fyi/3jh7PBt
* Use ODB in Next.js YouTube tutorial 
https://youtu.be/T916umjd5Eo
Even More Resources
Twitter, Polywork, LinkedIn, Github: @kenny_io

Speeding up build times in the Jamstack with DPR

By Ekene Eze

Speeding up build times in the Jamstack with DPR

Given that the Jamstack way of building the web can often result in lengthy build times for larger sites, we can reduce the build times by taking advantage of concepts like DPR as we'll see in this deck.

  • 142