Next.js中getServerSideProps请求过慢致页面无响应,如何加载骨架屏?
解决方案:实现即时导航+骨架屏的两种思路
你的核心问题在于getServerSideProps是在服务器端完成所有数据请求后,才会把完整页面返回给客户端,所以用户在等待期间完全看不到任何反馈,自然觉得网站无响应。下面给你两种可行的解决思路:
一、改用客户端异步数据获取(推荐)
放弃在getServerSideProps里预取数据,把请求放到页面组件内部,用SWR或React Query这类数据请求库来处理,这样页面会立刻渲染,同时显示骨架屏,等数据返回后再替换内容。
代码示例(用SWR):
import useSWR from 'swr'; // 定义请求函数 const fetcher = async (urls) => { const [res1, res2] = await Promise.all([ fetch(urls[0]), fetch(urls[1]) ]); return Promise.all([res1.json(), res2.json()]); }; export default function YourPage() { const { data, error, isLoading } = useSWR(['url1', 'url2'], fetcher); // 加载状态显示骨架屏 if (isLoading) return <SkeletonScreen />; // 错误处理 if (error) return <div>加载失败</div>; // 数据加载完成后渲染页面 const [data1, data2] = data; return ( <div> {/* 你的页面内容 */} </div> ); }
这种方式的优势是用户立刻能看到页面骨架,感知上网站是响应的,至于你担心的“多一次API调用”:如果你的API是内部服务,客户端直接请求和服务器端代理请求的耗时差异极小,甚至客户端请求可能借助CDN缓存更快。而且感知性能的提升远大于这点微小的耗时影响。
二、优化服务器端请求(如果必须保留SSR)
如果你因为SEO或其他原因必须用服务器端渲染,可以从以下方面优化:
- 合并API请求:和后端协商,把两个请求合并成一个接口,减少网络往返时间。
- 缓存API响应:如果数据不是实时更新的,在服务器端对API响应做缓存(比如用Redis),避免每次请求都去调用慢API。
- 增量静态再生(ISR):如果数据更新频率不高,用
getStaticProps配合revalidate参数,让Next.js定期重新生成页面,既保留静态页面的速度,又能更新数据。
补充说明
这不是Next.js独有的问题,所有SSR方案都会面临“预取数据等待导致无反馈”的问题,客户端异步加载+骨架屏是行业内解决感知性能的标准方案。之前你在_app.jsx加加载组件没用,就是因为getServerSideProps没完成的话,_app根本不会开始渲染客户端页面。
内容的提问来源于stack exchange,提问作者derickdecesare
相关产品推荐
相关产品推荐

