MST

星途 面试题库

面试题:Next.js 中 getStaticProps 和 getStaticPaths 的性能优化与复杂场景应用

在一个大型电商应用中,有数千种商品,每个商品都有详细页面。使用 getStaticProps 和 getStaticPaths 进行静态生成时,如何优化构建时间和内存使用?并且,当商品存在变体(如不同颜色、尺寸)时,如何确保变体相关的页面也能高效地静态生成,同时处理好 SEO 相关问题。
21.9万 热度难度
前端开发Next.js

知识考点

AI 面试

面试题答案

一键面试

优化构建时间和内存使用

  1. 分批生成静态页面
    • 由于有数千种商品,一次性生成所有商品详细页面可能会占用大量内存并花费很长时间。可以将商品按一定规则(比如按商品类别、字母顺序等)进行分组,然后分批调用 getStaticPathsgetStaticProps 来生成页面。例如,每次处理100个商品,这样可以减少每次构建时的内存压力。
    • getStaticPaths 函数中,可以通过循环分批获取商品ID数组,示例代码如下:
    export async function getStaticPaths() {
      const batchSize = 100;
      const totalItems = await getTotalProductCount();// 假设此函数用于获取商品总数
      const paths = [];
      for (let i = 0; i < totalItems; i += batchSize) {
        const batchIds = await getProductIdsInRange(i, i + batchSize - 1);
        batchIds.forEach(id => {
          paths.push({ params: { productId: id.toString() } });
        });
      }
      return { paths, fallback: false };
    }
    
  2. 增量静态再生
    • 启用增量静态再生功能,对于部分更新频率不高的商品,可以设置 revalidate 参数。这样在构建完成后,Next.js 会在指定的时间间隔(以秒为单位)后重新验证页面数据。例如,如果商品信息一周更新一次,可以设置 revalidate: 60 * 60 * 24 * 7(一周的秒数)。在 getStaticProps 函数中设置如下:
    export async function getStaticProps(context) {
      const product = await getProduct(context.params.productId);
      return {
        props: {
          product
        },
        revalidate: 60 * 60 * 24 * 7
      };
    }
    
  3. 缓存数据
    • getStaticProps 中,可以对获取商品数据的操作进行缓存。如果在一次构建过程中多次获取相同的商品数据(例如在生成变体页面时可能会重复获取基础商品数据),可以使用内存缓存(如 Map 数据结构)来避免重复查询数据库或API。示例代码如下:
    const productCache = new Map();
    export async function getStaticProps(context) {
      let product;
      if (productCache.has(context.params.productId)) {
        product = productCache.get(context.params.productId);
      } else {
        product = await getProduct(context.params.productId);
        productCache.set(context.params.productId, product);
      }
      return {
        props: {
          product
        }
      };
    }
    

处理商品变体及SEO问题

  1. 生成变体页面路径
    • getStaticPaths 中,除了生成基础商品页面路径,还需要生成每个变体的路径。假设变体信息存储在数据库中与商品关联,可以通过查询数据库获取每个商品的所有变体信息,并生成相应路径。例如,如果变体以颜色和尺寸标识,代码如下:
    export async function getStaticPaths() {
      const productIds = await getProductIds();
      const paths = [];
      productIds.forEach(productId => {
        const variants = await getVariantsByProductId(productId);
        variants.forEach(variant => {
          paths.push({
            params: {
              productId: productId.toString(),
              color: variant.color,
              size: variant.size
            }
          });
        });
      });
      return { paths, fallback: false };
    }
    
  2. 处理变体页面数据
    • getStaticProps 中,根据传入的变体参数(如颜色和尺寸)获取相应的变体数据。例如:
    export async function getStaticProps(context) {
      const product = await getProduct(context.params.productId);
      const variant = product.variants.find(v => v.color === context.params.color && v.size === context.params.size);
      return {
        props: {
          product,
          variant
        }
      };
    }
    
  3. SEO优化
    • 页面标题和描述:对于变体页面,生成独特的页面标题和描述,包含商品名称、变体信息(如颜色和尺寸)。例如,标题可以是 “[商品名称] - [颜色] - [尺寸] - 详细信息”,描述中也突出变体特性,以帮助搜索引擎理解页面内容。
    • 规范标签:在变体页面中,使用规范标签 <link rel="canonical" href="基础商品页面URL">,将变体页面关联到基础商品页面,避免搜索引擎将变体页面视为重复内容。这样可以集中页面权重,提升基础商品页面的SEO排名,同时也能让变体页面被搜索引擎收录。
    • 图片优化:对于变体商品的图片,确保图片文件名包含变体相关信息(如商品名 - 颜色 - 尺寸.jpg),并设置好图片的 alt 属性,描述变体商品的外观,以帮助搜索引擎理解图片内容。