Next.js中getServerSideProps与useSWR的差异及数据库请求影响
getServerSideProps 与 useSWR 的核心差异
一、getServerSideProps 的执行时机
你贴的这段getServerSideProps代码不是仅在构建时运行,而是用户每次访问或导航到该页面时,都会在服务器端重新执行一次。
具体流程是:用户发起页面请求 → 服务器触发getServerSideProps执行数据库查询 → 将查询结果作为 props 传给页面组件 → 渲染完整 HTML 返回给客户端。
对应代码示例:
export const getServerSideProps = async () => { try { const palettes = [] const docRef = query(collection(db, 'palettes'), orderBy('likes', 'desc'), limit(16)) const docData = await getDocs(docRef) docData.forEach((doc) => { palettes.push(doc.data()) }) if (!docData) { return { props: { data: { error: 'Failed to load palettes. Please refresh the page.'} } } } else { return { props: { data: { palettes } } } } } catch (e) { console.log('error:', e) } }
二、与 useSWR 的核心区别
1. 执行环境不同
getServerSideProps:全程在服务器端执行,数据库查询直接在服务器与数据库之间完成,客户端完全看不到这个请求链路。useSWR:在客户端浏览器执行,需要通过调用你的 API 路由(比如/api/palette/${slug})间接请求数据库,链路是:客户端 → 服务器 API 接口 → 数据库。
2. 数据加载时机不同
getServerSideProps:页面渲染前就完成数据加载,用户收到的是已经填充好数据的完整 HTML,首屏无加载等待(除非服务器查询耗时过长)。useSWR:页面先渲染空壳或加载状态,等客户端请求完成后再填充数据,首屏会有明显的加载过程。
3. 数据传递与处理逻辑不同
getServerSideProps:数据作为组件 props 直接传入,组件拿到就能用,不需要额外处理异步状态。useSWR:通过 Hook 返回data/error/isLoading等状态,需要你在组件里手动处理加载、错误、数据渲染的逻辑。
4. 缓存机制不同
getServerSideProps:默认无缓存,每次用户请求都会重新查询数据库(除非你自己在服务器端实现缓存逻辑,比如用 Redis 暂存查询结果)。useSWR:自带客户端缓存、后台重验证、过期重试等机制,相同 URL 的请求会优先复用缓存,减少重复请求。
三、对数据库请求次数的影响
- getServerSideProps:每有一个用户访问页面,就会触发一次数据库查询。如果100个用户同时访问,就会产生100次数据库请求(服务器端加缓存的情况除外)。
- useSWR:每个用户的客户端会发起 API 请求,每个 API 请求对应一次数据库查询。但由于 SWR 有客户端缓存,同一个用户多次访问同页面时不会重复发请求;不同用户之间仍会各自触发请求,总请求次数和
getServerSideProps类似(API 路由加服务器端缓存的情况除外)。
额外注意:用 useSWR 时多了一层客户端到 API 路由的请求转发,而getServerSideProps是直接在页面的服务器逻辑里查询数据库,少了一次网络跳转。
内容的提问来源于stack exchange,提问作者RobbieC
相关产品推荐
相关产品推荐

