You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何避免Next.js getStaticProps重复获取数据以提升性能

优化Next.js畅销产品数据重复请求的方案

针对所有产品页面重复请求相同畅销产品数据的问题,给你几个实用的优化思路:

1. 在_app.jsx中统一获取并传递数据

_app.jsx是所有页面的入口组件,你可以在这里一次性获取畅销产品数据,再通过props传递给所有子页面(包括[product_id].jsx),避免每个页面单独请求。

具体实现:

修改_app.jsx,添加数据获取逻辑:

// _app.jsx
function MyApp({ Component, pageProps, bestSellingProducts }) {
  return <Component {...pageProps} bestSellingProducts={bestSellingProducts} />;
}

export async function getServerSideProps() {
  // 仅在此处请求一次畅销产品数据
  const res = await fetch('你的后端接口地址');
  const bestSellingProducts = await res.json();

  return {
    props: {
      bestSellingProducts,
    },
  };
}

export default MyApp;

然后在[product_id].jsx中直接使用传递过来的props,无需重复请求:

// [product_id].jsx
export default function ProductPage({ product, bestSellingProducts }) {
  // 直接使用bestSellingProducts
  return (
    <div>
      {/* 产品内容区域 */}
      <section>
        <h2>畅销产品</h2>
        {/* 渲染畅销产品列表 */}
      </section>
    </div>
  );
}

// 仅获取当前产品的专属数据
export async function getServerSideProps(context) {
  const { product_id } = context.params;
  const res = await fetch(`你的后端接口/products/${product_id}`);
  const product = await res.json();

  return {
    props: {
      product,
    },
  };
}

2. 给数据请求添加缓存逻辑

如果不想在_app.jsx中统一处理,可以在获取畅销产品的函数里加入缓存,让服务器复用已请求过的数据。

方式一:Node.js内存缓存

// [product_id].jsx
// 全局变量存储缓存数据,仅在服务器端生效
let cachedBestSelling = null;
let cacheExpireTime = 0;

async function getBestSellingProducts() {
  const now = Date.now();
  // 设置缓存有效期(示例为1小时),过期后重新请求
  if (cachedBestSelling && now < cacheExpireTime) {
    return cachedBestSelling;
  }

  const res = await fetch('你的后端接口地址');
  const data = await res.json();
  
  cachedBestSelling = data;
  cacheExpireTime = now + 3600 * 1000; // 1小时后过期
  return data;
}

export async function getServerSideProps(context) {
  const productRes = await fetch(`你的后端接口/products/${context.params.product_id}`);
  const product = await productRes.json();
  // 调用带缓存的函数
  const bestSellingProducts = await getBestSellingProducts();

  return {
    props: {
      product,
      bestSellingProducts,
    },
  };
}

方式二:Next.js内置fetch缓存(Next.js 12+)

Next.js的fetch默认支持缓存,通过配置参数可以直接复用请求结果:

async function getBestSellingProducts() {
  const res = await fetch('你的后端接口地址', {
    next: { revalidate: 3600 }, // 1小时后自动重新验证缓存
  });
  return res.json();
}

这种方式下,服务器会自动缓存请求结果,后续相同请求直接返回缓存数据,直到过期时间触发重新请求。

3. 静态生成场景下预取数据

如果你的产品页面是用getStaticProps静态生成的,可在生成页面时复用缓存的畅销产品数据:

// [product_id].jsx
let cachedBestSelling = null;

export async function getStaticProps(context) {
  // 首次请求后缓存数据,后续所有产品页面复用
  if (!cachedBestSelling) {
    const res = await fetch('你的后端接口地址');
    cachedBestSelling = await res.json();
  }

  const productRes = await fetch(`你的后端接口/products/${context.params.product_id}`);
  const product = await productRes.json();

  return {
    props: {
      product,
      bestSellingProducts: cachedBestSelling,
    },
    revalidate: 86400, // 可选,设置页面重新生成间隔
  };
}

export async function getStaticPaths() {
  // 生成所有产品页面的路径
  const res = await fetch('你的后端接口/products');
  const products = await res.json();
  const paths = products.map(product => ({
    params: { product_id: product.id.toString() },
  }));

  return { paths, fallback: 'blocking' };
}

这种方式在静态生成所有产品页面时,只会发起一次畅销产品数据请求,所有页面共享该缓存。

内容的提问来源于stack exchange,提问作者Ali Afzali

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 23:01:35