Vercel部署Nuxt 2冷启动解析文档超时问题求助
问题背景
基于Nuxt 2.15.7构建、部署在Vercel的SSR站点,使用@nuxt/content 1.14.0渲染文章。设置target: "server"后,服务器闲置休眠触发冷启动时,首次加载耗时超10秒甚至超时。经排查,根源是冷启动时@nuxt/content会重新解析所有文档,超出Vercel Serverless函数的启动时间限制。需要在保留SSR(保障SEO)的前提下解决该问题。
现有配置
nuxt.config.js
export default { ssr: true, target: "server", plugins: [ "@/plugins/articleManager.ts", "@/plugins/leaflet.client.js", "@/plugins/device.server.js", ], components: true, buildModules: [ "@nuxt/typescript-build", "@nuxtjs/vuetify", "vue-ssr-carousel/nuxt", ], modules: [ "@nuxtjs/pwa", "@nuxt/content", "@nuxtjs/sitemap", "@nuxtjs/robots", "@nuxt/image", ], content: { fullTextSearchFields: ["title", "description"], }, build: { build: { extend(config, { isClient }) { if (isClient) { config.devtool = "source-map"; } }, }, }, srcDir: "src/", };
vercel.json
{ "version": 2, "builds": [ { "src": "package.json", "use": "@vercel/node" }, { "src": "nuxt.config.js", "use": "@nuxtjs/vercel-builder", "config": { "serverFiles": [ ".nuxt/content/**", "src/content/**", "server/**", ".nuxt/dist/sitemap-routes.json" ] } } ] }
解决方案
1. 预解析文档并缓存到内存
在服务器启动阶段一次性解析所有@nuxt/content文档,将结果缓存到全局内存中,后续请求直接复用缓存,避免冷启动时重复解析。
修改src/plugins/articleManager.ts(确保它是server端插件,可添加.server.ts后缀):
import { Context } from '@nuxt/types' export default async (ctx: Context) => { // 仅在服务器首次启动时执行缓存逻辑 if (process.server && !global.contentCache) { const contentApi = ctx.app.$content // 预加载所有文章(根据你的内容目录调整路径) const articles = await contentApi('articles').fetch() // 缓存到全局变量,跨请求复用 global.contentCache = { articles } console.log('✅ 所有文章已预加载到内存缓存') } // 给上下文添加缓存访问方法,方便页面/组件调用 ctx.$cachedContent = { getArticles: () => global.contentCache?.articles || [] } }
在页面中使用缓存替代直接调用$content:
<script lang="ts"> import { Context } from '@nuxt/types' export default { async asyncData(ctx: Context) { // 使用缓存的文章数据 const articles = ctx.$cachedContent.getArticles() return { articles } } } </script>
2. 优化@nuxt/content内置缓存配置
启用@nuxt/content的内置缓存,减少重复解析的概率(配合内存缓存使用效果更佳):
在nuxt.config.js的content配置中添加:
content: { fullTextSearchFields: ["title", "description"], cache: true, // 启用内置文档缓存 cacheTime: 86400000 // 缓存有效期1天(单位:毫秒) },
3. 调整Vercel构建配置确保缓存资源被打包
更新vercel.json的serverFiles,确保内容文件和缓存相关资源被包含在Serverless函数包中:
{ "version": 2, "builds": [ { "src": "nuxt.config.js", "use": "@nuxtjs/vercel-builder", "config": { "serverFiles": [ "src/content/**", ".nuxt/content/**", ".nuxt/dist/**", "server/**" ] } } ] }
(移除不必要的package.json构建规则,避免冗余)
4. 定时预热Vercel Serverless函数
Vercel的Serverless函数闲置一段时间会休眠,通过定时请求站点关键页面,避免函数进入休眠状态:
使用GitHub Actions创建定时任务(.github/workflows/warm-vercel.yml):
name: Warm Vercel Server on: schedule: - cron: '*/15 * * * *' # 每15分钟执行一次 jobs: warm-server: runs-on: ubuntu-latest steps: - name: Request site pages run: | curl -s https://your-domain.com > /dev/null curl -s https://your-domain.com/articles > /dev/null
替换your-domain.com为你的站点域名,这样每15分钟会请求一次页面,保持函数活跃。
验证步骤
- 部署修改后的代码到Vercel
- 等待部署完成后,闲置站点30分钟以上(确保函数进入休眠)
- 访问站点首页和文章列表页,检查首次加载时间是否降至正常范围(一般2秒内)
内容的提问来源于stack exchange,提问作者Pablo Gutiérrez

