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构建流程,达成纯静态生成目标:
- 创建独立数据获取脚本(如
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); });
- 修改
package.json构建命令,先执行脚本再构建:
{ "scripts": { "prebuild": "node scripts/fetch-stock-data.js", "build": "next build" } }
- 页面中直接导入静态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中运行:
- 把数据获取逻辑放到专属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; }
- 在页面(
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> ); }
- 确保使用Next.js 13.4+稳定版本,AppDir兼容性已大幅提升。
额外优化建议
- 若需定期更新股票数据,可结合CI工具(如GitHub Actions)定时执行前置脚本并重新部署
- 在前置脚本中添加缓存逻辑(如检查文件更新时间),避免重复请求
内容的提问来源于stack exchange,提问作者Sergey Sypalo
相关产品推荐
相关产品推荐

