getStaticProps
,获取静态数据
React 虽然好用,但是一直以来为人所诟病的一点就是:SEO 优化问题。Vercel 团队在构建 Next.js 的时候就考虑到了这个问题,并且提供了两种 SEO 友好的处理方式,其中之一就是使用 getStaticProps
这个方法。
以之前写的某个 React 小 demo 为例,在按下 f12
对页面进行 inspect 的时候,是能够看到所有的代码:
不过这已经是在客户端完成渲染的情况下,如果直接 inspect 页面源码(chrome 快捷键 ctrl + u
),那么就能看到:
页面是空的,备注还贴心的说明,如果在浏览器中打开这个网页,那么就会看到一个空的页面。这种情况下,爬虫、机器人是无法正确的抓取页面的信息,SEO 也就无从谈起。
如何使用 getStaticProps
使用 getStaticProps
能够解决这个问题,参考代码如下:
import React from "react";
import EventList from "../components/events/event-list";
// 这个是 util 函数,负责获取数据,可以是从本地 json 中获取或是从 数据库 中获取
import { getFeaturedEvents } from "../helpers/api-util";
const HomePage = ({ featuredEvents }) => {
return (
<div>
<EventList items={featuredEvents} />
</div>
);
};
export async function getStaticProps(context) {
const featuredEvents = await getFeaturedEvents();
return {
props: {
featuredEvents: featuredEvents,
},
revalidate: 1800,
};
}
export default HomePage;
渲染效果如下:
页面源码如下:
源码是 Next.js 直接打包压缩好了,所以看起来会比较乱,但是这里也能看到,页面上的数据是真实反应到了源码之中,而当机器人/爬虫在爬取页面的时候,也能够抓取以下几个关键词:
- event
- extroverts
- introverts
- 相关地点
- 相关事件
对于用户来说,当他们在搜索引擎中搜索以上关键字时,有可能会浏览到生成的网页。
注意这一段代码:revalidate: 1800
,虽然 getStaticProps
是在打包时构建出来的页面,但是 Next.js 自身本就通过 node 实现了服务器,所以在部署上线后也可以重新构筑(rebuild)页面,这个时候 Next.js 就会检查 getStaticProps
中是否有 revalidate
这个返回值。
有的话 Next.js 就会在指定时间过后重新生成静态渲染的页面,并且向用户返回最新的页面。如使用 Next.js 构筑一个博客系统,首页的 revalidate
可以设置为 1 天(即 86400s,也就是 revalidate: 86400
),毕竟正常情况下博客最多的还是日更。
这种情况下,这个项目就会每天定时重新 build,爬虫/机器人也能抓到最新的页面。
什么时候使用 getStaticProps
Next.js 的官方文档中提到以下情况会比较适合使用 getStaticProps
:
-
The data required to render the page is available at build time ahead of a user’s request
-
The data comes from a headless CMS
-
The data can be publicly cached (not user-specific)
-
The page must be pre-rendered (for SEO) and be very fast —
getStaticProps
generates HTML and JSON files, both of which can be cached by a CDN for performance
getStaticProps
运行时间
-
getStaticProps
always runs during next build -
getStaticProps
runs in the background when using revalidate -
getStaticProps
runs on-demand in the background when usingunstable_revalidate