增量静态生成怎么做到首屏不白屏?

Prog.逸龙 阅读 35

我们用 Next.js 做了个博客,文章页用了增量静态生成(ISR),但新页面首次访问时还是会白屏几秒,感觉跟 SSR 差不多。不是说 ISR 能提前生成好 HTML 吗?

我试过在 getStaticProps 里加 revalidate: 60,也预渲染了热门文章,但冷启动的新页面还是得等服务端生成。有没有办法让首屏至少显示个骨架屏或者 loading?

export async function getStaticProps({ params }) {
  const post = await getPostFromCMS(params.slug);
  return {
    props: { post },
    revalidate: 60,
  };
}
我来解答 赞 8 收藏
二维码
手机扫码查看
2 条解答
极客玉宸
ISR 冷启动首屏白屏是正常的,因为服务器真得现生成。加个 fallback: true 就行:

export async function getStaticProps({ params }) {
const post = await getPostFromCMS(params.slug);
return {
props: { post },
revalidate: 60,
fallback: true, // 加这行,页面立即返回,客户端再渐进式加载
};
}


然后组件里判断一下:

export default function Post({ post }) {
const router = useRouter();

if (router.isFallback) {
return ; // 骨架屏
}

return
{post.content}
;
}


fallback: true 会让页面立即用空状态返回,浏览器不白屏,然后客户端再替换成真实数据。热门文章提前 getStaticPaths 预渲染一下,冷启动就少多了。
点赞
2026-03-12 18:20
Zz艳艳
Zz艳艳 Lv1
试试看在文章页组件里加个 fallback 逻辑,用 router.isFallback 判断是不是正在生成中,生成中就先渲染骨架屏,别等 getStaticProps 跑完:

import { useRouter } from 'next/router';

export default function Post({ post }) {
const router = useRouter();

if (router.isFallback) {
return (
<div className="skeleton">
<div className="skeleton-title"></div>
<div className="skeleton-content"></div>
</div>
);
}

return (
<article>
<h1>{post.title}</h1>
<div dangerouslySetInnerHTML={{ __html: post.content }} />
</article>
);
}


记得 fallback: 'blocking'fallback: true 要配着用,别漏了。
点赞 5
2026-02-25 23:02