在前一篇文章中,我们了解了如何使用 getStaticProps
让 Next.js 可以在打包阶段产生静态的 HTML 档案,让使用者在浏览指定网站时,服务器能够回传相对应的 HTML 档案,并且因为静态的 HTML 可以被 cache,所以有利於提升使用者看到网页内容的速度。
此外,还了解怎麽在 dynamic routes 中处理 SSG 的问题,因为 dynamic routes 等於是可以匹配无限的 url,但是 Next.js 不可能花费无限的时间打包档案,因此要使用 getStaticPaths
指定有哪些路径会参与 SSG 的打包过程。
而在 getStaticPaths
我们需要回传一个物件,物件中必须包含两个 key,分别为 params
与 fallback
, params
定义的是 SSG 对应的路由有哪些, fallback
则是定义使用者浏览 params
没有定义的页面时的对应方式。
今天要介绍的是 Next.js 的 Incremental Static Regeneration (拿到 Google 翻译会跑出增量静态再生,听起来很中二中名字 ?),这个 feature 对於有大量静态页面的网站非常有帮助。
先举一个例子,在 vercel 的这篇文章中就提到电商网站这个例子,在电商网站中假设有超过 10 万件商品,但是使用者只会搜寻他们想看的商品,并不是所有商品都会被看到,花上大量时间在打包 HTML 档案并不符合成本。
因此,Next.js 实作了一种功能叫做 Incremental Static Regeneration,这个功能是在 next build
打包阶段不用生成所有的页面,而是让页面可以动态的生成,以下有两个概念,在实作时可以取舍:
*https://vercel.com/docs/next.js/incremental-static-regeneration*
读者应该已经知道 getStaticPaths
与 fallback
的组合技,便是 Incremental Static Regeneration 的实作。但是这样会存在一个问题,尽管可以动态地打包档案,但是电商网站的商品内容可能会快速变动,什麽时候才会重新打包呢?
根据官方的说法,在没有设定 revalidate
的情况是不会重新生成已经存在的 HTML。
尽管,我们可以从 Next.js 官方文件或 Chrome 的 Network 中看到 SSG 预设的 cache 时间是 31536000:
Cache-Control: s-maxage=31536000, stale-while-revalidate
31536000 的单位是秒,所以换算成天的话是 365 天,但是 365 天过後,也只是重新设定 cache 与回传同样的 HTML 而已。
revalidate
revalidate
是 getStaticProps
的一个选择性参数,它可以用来决定一个页面多久会重新打包一次。
export async function getStaticProps(context) {
const res = await fetch(`https://.../data`)
const data = await res.json()
return {
props: {},
revalidate: 60,
}
}
以下是一个 revalidate
设定为 60 秒的示范图:
*https://vercel.com/docs/next.js/incremental-static-regeneration*
revalidate: 60
的意思是说页面会 60 秒後就会失去 cache 的作用,Next.js 必须为这个页面重新打包一次,但是如果没有使用者浏览这个页面的话,Next.js 也不会主动重新打包这个页面。
而这个设定实际上运作的方式如下:
getStaticProps
,进行重新打包的流程。在打包完成之後,Next.js 会更新 cache,并且当有使用者浏览该页面时,看到的都会是新的内容。以 revalidate: 60
作为范例,Next.js 会修改 header 中的 Cache-Control
数值, s-maxage
会等於 revalidate
设定的数值。
Cache-Control: s-maxage=60, stale-while-revalidate
fallback
?要使用 Incremental Static Regeneration 这个功能, 在 getStaticPaths
中的 fallback
就必须是 true
或 'blocking'
其中一种,对於使用者来说两个的体验差别是有没有 fallback page, 设定fallback: true
能够用 isFallback
判别目前的 fallback 阶段,并回传 loading 的特效或是其他的 component 给使用者,而设定 'blocking'
则没有 fallback page,更像是 SSR 的体验,使用者会等待页面生成完毕後,直接看到完整的网页内容。
两者看起来很相似,怎麽选择呢?
fallback: true
v.s. fallback: 'blocking'
'blocking'
:官方推荐使用这个参数,原因虽然没有说,但是在 Next.js 的 GitHub issue 中翻了一会儿,会发现 'blocking'
的好处是有利於 SEO,虽然对於会执行 JavaScript 的 Google 爬虫没有影响,但是像是 Facebook 或 Twitter 等不会执行 JavaScript 的爬虫, 'blocking'
才能确保爬虫拿到的资料是完整的。true
: 如上述,因为 true
会使爬虫看到的是 fallback page,如果没有执行 JavaScript,则无法拿到更新後的内容,如此对於 SEO 不利。但是,对於需要经过 authentication 的页面或是後台页面来说,也许 true
是一个好的选择,因为不用在意 SEO,而且透过 web skeleton 可以让使用者更快地看到网页预载入的内容框,从另一个面向来看是可以优化 UX 的选择。在这篇文章中,我们谈到了 Next.js 的 Incremental Static Regeneration 这项重要的功能,它能够帮助我们降低打包时间,在使用者请求页面时才动态地生成页面。
此外,我们还了解到如何使用 revalidate
设定重新生成页面的时间,并且 Next.js 还会自动更新 cahce;以及了解 fallback
的 true
与 'blocking'
的优缺点,也知道使用这两个参数的时间点。
Keychain Apple Keychain 是一个非常流行且功能强大的 Swift 工具,每个 ...
tags: 铁人赛 AWS EC2 闲话家常 历久不衰的虚拟机器 开赛以来发现大家都用很新很潮的技术...
文章内容 本章内容为阅读官方文件有关 interpolation 的笔记内容。 Expression...
表单input元素 一般表单中所看到的输入栏位,可以用 <INPUT> 元件与其属性ty...
(以下文章适用於Vue.js 2.X版本) Vue.js 官方手册 起手式 引入 Vue.js ne...