Next.js精通SEO第四章(JSON-LD + web vitals)

JSON-LD

JSON-LD(JSON for Linked Data)是一种用于表达结构化数据的 JSON 格式。

它能帮助搜索引擎和 AI 更准确理解页面内容(例如商品、文章、组织、人物、活动等实体),从而提升页面在检索系统中的可理解性。

在 Next.js(App Router)里,推荐在 layout.tsxpage.tsx 中,直接输出一个原生 <script type="application/ld+json"> 标签来注入 JSON-LD。

JSON-LD 的基础结构

一个最小可用示例如下:

json 复制代码
{
  "@context": "https://schema.org",
  "@type": "Person",
  "@id": "https://example.com/people/zhangsan",
  "name": "张三",
  "age": 25
}

字段说明:

  • @context:通常使用 https://schema.org
  • @type:实体类型(如 ProductArticleOrganization)更多类型请查看文档https://schema.org/docs/full.html
  • @id:唯一标识符,通常是实体的URL
  • 其他字段:请根据文档填写例如Person https://schema.org/Person 你的网站是什么type你就把链接后面的值换成你对应的type就行了

在 Next.js 中添加 JSON-LD

下面是一个页面级示例(以商品页为例):

tsx 复制代码
// app/products/[id]/page.tsx
export default async function Page({
  params,
}: {
  params: Promise<{ id: string }>;
}) {
  const { id } = await params;
  const product = await getProduct(id);

  const jsonLd = {
    '@context': 'https://schema.org',
    '@type': 'Product',
    name: product.name,
    image: product.image,
    description: product.description,
  };

  return (
    <section>
      <script
        type="application/ld+json"
        dangerouslySetInnerHTML={{
          __html: JSON.stringify(jsonLd).replace(/</g, '\\u003c'),
        }}
      />
      <h1>{product.name}</h1>
    </section>
  );
}

为什么要做 .replace(/</g, '\\u003c')

JSON.stringify 本身不会自动处理所有潜在注入风险。

当结构化数据里包含不可信字符串时,建议至少将 < 替换为 \u003c,降低 XSS 注入风险。

ts 复制代码
JSON.stringify(jsonLd).replace(/</g, '\\u003c');

如果你们团队有统一的安全序列化方案,也可以采用社区库(如 serialize-javascript)或公司内部安全工具。

TypeScript 类型约束(推荐)

为避免字段名拼错、类型不匹配,建议使用 schema-dts 做类型提示:

tsx 复制代码
import type { Product, WithContext } from 'schema-dts';

const jsonLd: WithContext<Product> = {
  '@context': 'https://schema.org',
  '@type': 'Product',
  name: 'Next.js Sticker',
  image: 'https://nextjs.org/imgs/sticker.png',
  description: 'Dynamic at the speed of static.',
};

常见问题

1)用 next/script 还是原生 <script>

JSON-LD 不是要执行的脚本代码,而是结构化数据声明。

在这个场景里,官方建议使用原生 <script type="application/ld+json">

2)放在 layout.tsx 还是 page.tsx
  • 放在 layout.tsx:适合站点级、栏目级的通用结构化数据
  • 放在 page.tsx:适合文章、商品详情这类强依赖当前页面数据的实体
3)如何验证配置是否有效?

可使用以下工具进行校验:

  • Google Rich Results Test:检查可用于 Google 富结果的结构化数据
  • Schema Markup Validator:通用 Schema.org 结构校验

实践建议

  • 使用与页面真实内容一致的字段,避免"标注内容"和"页面内容"不一致
  • 动态页面优先在服务端生成 JSON-LD,保证首屏 HTML 可被爬虫读取
  • 关键实体(文章、商品、组织)优先完善,再逐步扩展更多 schema 类型

web vitals

Web Vitals 是 Google 推出的一套以用户为中心的网页性能指标体系,用来衡量真实用户在加载速度、交互响应、页面稳定性三个维度的体验表现,也是 SEO 评估的重要参考项。

核心三项(LCP、INP、CLS)

截至 2026 年,Core Web Vitals 仍由以下三项组成:

LCP(Largest Contentful Paint,最大内容绘制时间)

LCP 衡量的是视口内最大内容元素(通常是大图、视频封面或大段文本)完成渲染所需的时间,反映"主要内容何时可见"。

  • Good:<= 2.5s
  • Needs Improvement:2.5s ~ 4.0s
  • Poor:> 4.0s

INP(Interaction to Next Paint,交互到下一次绘制)

INP 衡量用户交互(点击、输入、键盘操作)到页面下一次可见更新之间的延迟,反映整体交互流畅度。

  • Good:<= 200ms
  • Needs Improvement:200ms ~ 500ms
  • Poor:> 500ms

CLS(Cumulative Layout Shift,累积布局偏移)

CLS 衡量页面在生命周期内发生的意外布局位移总量,反映视觉稳定性。比如图片未预留尺寸、异步内容插入导致页面"跳动"。

  • Good:<= 0.1
  • Needs Improvement:0.1 ~ 0.25
  • Poor:> 0.25

如何测评

可以使用 Chrome DevTools 的 Lighthouse 面板快速进行本地评估:

  1. 打开 DevTools,进入 Lighthouse 面板。
  2. 选择设备(移动端/桌面端)与检测类别(建议勾选 Performance 和 SEO)。
  3. 点击"分析网页加载情况"生成报告。
  4. 在报告中查看 LCP、CLS 等核心指标分数与诊断建议。

代码示例

bash 复制代码
npm install web-vitals

下面示例展示在 Next.js 客户端中订阅 Web Vitals 指标并输出到控制台(可替换为埋点上报逻辑):

tsx 复制代码
'use client'

import { useEffect } from 'react'
import { onCLS, onFCP, onINP, onLCP, type Metric } from 'web-vitals'

function reportWebVital(metric: Metric) {
  // 生产环境中建议上报到日志系统或分析平台
  console.log('[WebVitals]', metric.name, metric.value, metric.rating)
}

export default function HomePage() {
  useEffect(() => {
    onCLS(reportWebVital)
    onFCP(reportWebVital)
    onINP(reportWebVital)
    onLCP(reportWebVital)
  }, [])

  return (
    <section>
      <button type="button">点击交互</button>
      <div>你已经进入 Home 页面</div>
    </section>
  )
}

示例输出:

ts 复制代码
{ name: 'FCP', value: 1164, rating: 'good', delta: 1164, entries: [...] }
{ name: 'INP', value: 78, rating: 'good', delta: 78, entries: [...] }
{ name: 'CLS', value: 0, rating: 'good', delta: 0, entries: [...] }
{ name: 'LCP', value: 1530, rating: 'good', delta: 1530, entries: [...] }
相关推荐
云水一下9 小时前
从零开始!VMware安装Fedora Workstation 44桌面系统完整教程
前端
小码哥_常10 小时前
安卓黑科技:实现多平台商品详情页一键跳转APP
前端
killerbasd10 小时前
还是迷茫 5.3
前端·react.js·前端框架
不会敲代码111 小时前
TCP/IP 与前端性能:从数据包到首次渲染的底层逻辑
前端·tcp/ip
kyriewen11 小时前
奥特曼借GPT-5.5干杯,而你的Copilot正按Token收钱
前端·github·openai
AC赳赳老秦11 小时前
投标合规提效:用 OpenClaw 实现标书 / 合同自动审核、关键词校验、格式优化,降低废标风险
开发语言·前端·python·eclipse·emacs·deepseek·openclaw
kyriewen11 小时前
代码写成一锅粥?3个设计模式让你的项目“起死回生”
前端·javascript·设计模式
千寻girling12 小时前
《 Git 详细教程 》
前端·后端·面试
之歆13 小时前
DAY08_CSS浮动与行内块布局实战指南(下)
前端·css