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

NextJS中yahoo-finance2页面性能优化及NextJS13兼容问题咨询

Next.js 13 中使用 yahoo-finance2 的高效解决方案

问题核心分析

  • 当前getStaticProps中引入yahoo-finance2,导致Next.js将页面标记为SSG + JSON(非纯静态HTML),第三方包代码被打包到客户端JS中,推高了First JS Load体积
  • 迁移AppDir时构建失败,大概率是yahoo-finance2的模块逻辑与AppDir的Server Components规则冲突(比如包含浏览器专属API或ESM兼容性问题)

可行解决方案

方案1:构建前置脚本生成静态JSON(彻底实现纯SSG)

完全剥离数据获取逻辑与Next.js构建流程,达成纯静态生成目标:

  1. 创建独立数据获取脚本(如scripts/fetch-stock-data.js):
const yahooFinance = require('yahoo-finance2');
const fs = require('fs');
const path = require('path');

async function fetchStockData() {
  const stocks = [{Ticker: "AAPL"},{Ticker: "ABNB"}];
  await Promise.all(
    stocks.map(async (stock) => {
      stock['prices'] = await (await yahooFinance.historical(stock.Ticker, { period1: '2019-01-01', interval: '1mo' }))
        .map((item) => ({[item.date.toLocaleDateString('en-us', { year:"numeric", month:"short"})]: Math.round(item.adjClose) }));
    })
  );
  // 将数据写入项目静态目录
  fs.writeFileSync(path.join(__dirname, '../src/data/stock-prices.json'), JSON.stringify(stocks));
}

fetchStockData().catch(err => {
  console.error('获取股票数据失败:', err);
  process.exit(1);
});
  1. 修改package.json构建命令,先执行脚本再构建:
{
  "scripts": {
    "prebuild": "node scripts/fetch-stock-data.js",
    "build": "next build"
  }
}
  1. 页面中直接导入静态JSON:
import stockData from '../data/stock-prices.json';

export async function getStaticProps() {
  return {
    props: {
      ...posts.find(post => post.slug == 'best-stocks'),
      stocks: stockData
    }
  };
}

此方案不会将yahoo-finance2打包到客户端,页面生成纯静态HTML,彻底解决First JS Load体积问题。

方案2:在Next.js 13 AppDir中适配使用yahoo-finance2

若需保留AppDir结构,确保yahoo-finance2仅在Server Components中运行:

  1. 把数据获取逻辑放到专属Server Component(如components/StockData.server.js,.server.js后缀强制标记为服务端组件):
import yahooFinance from 'yahoo-finance2';

export async function getStockData() {
  const stocks = [{Ticker: "AAPL"},{Ticker: "ABNB"}];
  await Promise.all(
    stocks.map(async (stock) => {
      stock['prices'] = await (await yahooFinance.historical(stock.Ticker, { period1: '2019-01-01', interval: '1mo' }))
        .map((item) => ({[item.date.toLocaleDateString('en-us', { year:"numeric", month:"short"})]: Math.round(item.adjClose) }));
    })
  );
  return stocks;
}
  1. 在页面(app/best-stocks/page.js)中调用该服务端组件的函数:
import { getStockData } from '../components/StockData.server';
import posts from '../data/posts';

export default async function BestStocksPage() {
  const stockData = await getStockData();
  const post = posts.find(post => post.slug == 'best-stocks');
  
  return (
    <div>
      {/* 页面内容渲染逻辑 */}
    </div>
  );
}
  1. 确保使用Next.js 13.4+稳定版本,AppDir兼容性已大幅提升。

额外优化建议

  • 若需定期更新股票数据,可结合CI工具(如GitHub Actions)定时执行前置脚本并重新部署
  • 在前置脚本中添加缓存逻辑(如检查文件更新时间),避免重复请求

内容的提问来源于stack exchange,提问作者Sergey Sypalo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.12 05:35:50