MST

星途 面试题库

面试题:Next.js 应用中 getStaticProps 与 API Routes 的复杂交互及优化策略

假设在一个 Next.js 大型电商应用中,产品列表页使用 getStaticProps 获取商品数据,而商品详情页需要通过 API Routes 实时获取动态库存信息。请描述如何实现这种复杂的交互,并且说明在高并发场景下,如何优化 getStaticProps 的缓存策略以及 API Routes 的性能,以确保应用的高效稳定运行。
38.0万 热度难度
前端开发Next.js

知识考点

AI 面试

面试题答案

一键面试

实现复杂交互

  1. 产品列表页使用 getStaticProps
    • 在 Next.js 页面组件中定义 getStaticProps 函数。
    • 利用该函数从数据源(如数据库、CMS 等)获取商品数据。例如,可以使用 axiosfetch 去请求商品列表 API 数据,然后返回包含商品列表数据的对象,这个对象会作为 props 传递给页面组件。
    • 示例代码:
export async function getStaticProps() {
  const res = await fetch('https://your - api - url/products');
  const products = await res.json();
  return {
    props: {
      products
    },
    revalidate: 60 // 每60秒重新生成页面,可根据需求调整
  };
}

const ProductListPage = ({ products }) => {
  return (
    <div>
      {products.map(product => (
        <div key={product.id}>{product.name}</div>
      ))}
    </div>
  );
};

export default ProductListPage;
  1. 商品详情页通过 API Routes 实时获取动态库存信息
    • pages/api 目录下创建一个 API 路由文件,例如 product - stock.js
    • 在该文件中处理获取商品库存的逻辑,连接数据库查询对应商品的库存数据并返回。
    • 在商品详情页组件中,使用 useEffect 钩子在组件挂载时通过 fetchaxios 调用这个 API Routes 获取动态库存信息。
    • 示例 API Routes 代码:
import { connectToDatabase } from '../../lib/db';

export default async (req, res) => {
  const { productId } = req.query;
  const client = await connectToDatabase();
  const db = client.db();
  const product = await db.collection('products').findOne({ id: productId });
  client.close();
  if (!product) {
    return res.status(404).json({ message: 'Product not found' });
  }
  res.status(200).json({ stock: product.stock });
};
  • 示例商品详情页组件代码:
import { useEffect, useState } from'react';

const ProductDetailPage = ({ product }) => {
  const [stock, setStock] = useState(null);
  useEffect(() => {
    const fetchStock = async () => {
      const res = await fetch(`/api/product - stock?productId=${product.id}`);
      const data = await res.json();
      setStock(data.stock);
    };
    fetchStock();
  }, [product.id]);
  return (
    <div>
      <h1>{product.name}</h1>
      {stock && <p>Stock: {stock}</p>}
    </div>
  );
};

export async function getStaticProps({ params }) {
  const res = await fetch(`https://your - api - url/products/${params.productId}`);
  const product = await res.json();
  return {
    props: {
      product
    }
  };
}

export async function getStaticPaths() {
  const res = await fetch('https://your - api - url/products');
  const products = await res.json();
  const paths = products.map(product => ({
    params: { productId: product.id.toString() }
  }));
  return { paths, fallback: false };
}

export default ProductDetailPage;

高并发场景下的优化

  1. 优化 getStaticProps 的缓存策略
    • 使用 Incremental Static Regeneration:通过设置 revalidate 选项(如上述 getStaticProps 示例中的 revalidate: 60),Next.js 会在指定时间间隔后重新生成页面,确保数据在一定程度上的实时性。对于变化不频繁但又需要保持相对新的数据,这种方式非常有效。
    • 缓存分层:可以结合 CDN(如 Vercel CDN 或 Cloudflare)进行缓存。CDN 可以缓存静态页面和资源,减少源站的负载。同时,应用服务器内部也可以使用内存缓存(如 Redis)来缓存 getStaticProps 获取的数据,减少数据库查询压力。如果数据量较大,可以考虑分布式缓存。
  2. 优化 API Routes 的性能
    • 数据库优化:确保数据库索引合理设置,对于查询库存的操作,索引能够大大提升查询速度。例如,在商品集合中对 id 字段建立索引,能够快速定位到对应商品的库存信息。
    • 缓存 API 响应:可以在 API 层使用内存缓存(如 node - cache 库)。在处理请求时,先检查缓存中是否有对应商品的库存数据,如果有则直接返回,避免重复查询数据库。设置合理的缓存过期时间,以保证库存数据的实时性。
    • 负载均衡:在高并发场景下,使用负载均衡器(如 Nginx、HAProxy 等)将请求均匀分配到多个服务器实例上,避免单个服务器过载。同时,水平扩展服务器数量,根据流量情况动态调整资源。
    • 优化代码性能:减少 API Routes 中的不必要计算和操作,确保代码简洁高效。例如,避免在每次请求时进行复杂的重复计算,可以将计算结果缓存起来。