面试题答案
一键面试优化 getStaticProps
保证快速加载与数据更新
- 优化
getStaticProps
实现快速加载- 数据分层获取:将数据按更新频率和重要性分层。对于更新频率低且关键的数据(如产品基本信息),可以在
getStaticProps
中直接获取并静态生成。对于更新频繁的数据(如实时库存、价格变动等),可以通过 API 调用在客户端渲染时获取。 - 数据缓存:在服务器端使用缓存机制,如 Redis。当
getStaticProps
调用数据获取逻辑时,先检查缓存中是否有数据。如果有,则直接返回缓存数据,减少数据库或 API 调用次数。例如:
import redis from'redis'; const client = redis.createClient(); export async function getStaticProps() { const cachedData = await new Promise((resolve, reject) => { client.get('productData', (err, data) => { if (err) { reject(err); } else { resolve(data? JSON.parse(data) : null); } }); }); if (cachedData) { return { props: { product: cachedData }, revalidate: 60 // 每分钟重新验证 }; } const product = await fetchProductFromDatabase(); client.setex('productData', 3600, JSON.stringify(product)); // 缓存1小时 return { props: { product }, revalidate: 60 // 每分钟重新验证 }; }
- 数据分层获取:将数据按更新频率和重要性分层。对于更新频率低且关键的数据(如产品基本信息),可以在
- 处理数据更新
- 增量更新:对于更新频率较低的数据,
getStaticProps
中的revalidate
选项可以设置一个合理的时间间隔,Next.js 会在这个时间间隔后重新生成页面。例如,设置revalidate: 60
表示每分钟重新验证数据。如果数据有更新,在下一次请求时会获取最新数据并重新渲染页面。 - 实时数据处理:对于实时更新的数据(如库存、价格),使用 WebSockets 或 Server - Sent Events(SSE)在客户端与服务器之间建立实时连接。当数据发生变化时,服务器推送更新到客户端,客户端实时更新页面上相关部分,而不需要重新加载整个页面。
- 增量更新:对于更新频率较低的数据,
可能遇到的挑战及解决方案
- 缓存控制
- 缓存穿透:指查询一个不存在的数据,每次都查询数据库,缓存不起作用。解决方案是在查询数据库后,如果数据不存在,也将空值缓存起来,并设置较短的过期时间,避免后续重复查询数据库。
- 缓存雪崩:大量缓存数据在同一时间过期,导致大量请求直接打到数据库。可以将缓存的过期时间设置为一个随机值,避免集中过期。例如,将过期时间设置为 300 到 600 秒之间的随机数。
- 数据一致性
- 读写一致性:在更新数据时,要保证缓存和数据库的一致性。一种做法是先更新数据库,再删除缓存。这样下次读取数据时,会从数据库获取最新数据并重新缓存。另一种更复杂但一致性更好的方法是使用分布式事务,确保数据库和缓存更新操作的原子性。
- 跨实例一致性:在分布式系统中,多个实例可能同时缓存数据。可以使用分布式缓存如 Redis Cluster,并利用发布 - 订阅机制。当数据更新时,发布一个更新消息,所有实例接收到消息后更新或删除相关缓存数据。