VitePress 博客 SEO 优化与性能提升指南 2026
VitePress 基于 Vite + Vue 3,天生就拥有极快的构建速度和优秀的首屏性能。但「快」不等于「SEO 好」——一个 VitePress 博客想要在 Google / Bing 搜索中获得高排名,还需要在结构化数据、Sitemap、Core Web Vitals、社交分享等方面做系统优化。
本文以本站 y-m.top(VitePress 2.0-alpha + pnpm)的真实配置为例,分享从 0 到 1 完成 VitePress SEO 优化的全部实践。文中的每一行配置代码都来自本站仓库,可以直接参考使用。
VitePress 的 SEO 基础能力
框架原生 SEO 优势
VitePress 在 SEO 方面有几个天然优势:
| 特性 | 说明 | 对 SEO 的影响 |
|---|---|---|
| SSG 预渲染 | 构建时生成完整 HTML | ✅ 搜索引擎爬虫无需执行 JS 即可获取内容 |
| cleanUrls | URL 无 .html 后缀 | ✅ URL 更简洁,搜索引擎友好 |
| metaChunk | 将 meta 信息提取为独立 chunk | ✅ 减小主 HTML 体积,加快解析 |
| lastUpdated | 自动记录文件修改时间 | ✅ 可用于 article:modified_time |
| sitemap | 内置 sitemap.xml 生成 | ✅ 自动生成站点地图 |
| transformPageData | 构建时动态修改页面元数据 | ✅ 可批量注入 canonical / og / json-ld |
| head 配置 | 全局 head 标签注入 | ✅ 统一管理 meta 标签 |
全局 head 配置
在 .vitepress/configs/head.ts 中配置全局 head 标签:
// .vitepress/configs/head.ts
import type { HeadConfig } from 'vitepress'
export const head: HeadConfig[] = [
// 浏览器 UI 配置
['meta', { name: 'theme-color', content: '#ffffff' }],
['meta', { name: 'msapplication-TileColor', content: '#da532c' }],
['meta', { name: 'format-detection', content: 'telephone=no' }],
// 网站图标
['link', { rel: 'icon', type: 'image/png', href: '/favicon-96x96.png', sizes: '96x96' }],
['link', { rel: 'icon', type: 'image/svg+xml', href: '/favicon.svg' }],
['link', { rel: 'shortcut icon', href: '/favicon.ico' }],
['link', { rel: 'apple-touch-icon', sizes: '180x180', href: '/apple-touch-icon.png' }],
['link', { rel: 'manifest', href: '/site.webmanifest' }],
// 站点基本信息
['meta', { name: 'author', content: '你的站点名' }],
['meta', { name: 'copyright', content: '你的站点名' }],
// Open Graph 全局默认
['meta', { property: 'og:type', content: 'website' }],
['meta', { property: 'og:locale', content: 'zh-Hans' }],
['meta', { property: 'og:site_name', content: '你的站点名' }],
// Twitter Card
['meta', { name: 'twitter:card', content: 'summary_large_image' }],
// Robots 指令
['meta', { name: 'robots', content: 'index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1' }],
]📌 robots meta 详解:
index, follow:允许索引并跟踪链接max-snippet:-1:不限制摘要长度max-image-preview:large:允许大图预览(影响搜索结果展示)max-video-preview:-1:不限制视频预览
frontmatter 最佳实践
每篇文章的 frontmatter 是 SEO 的第一道关卡:
---
title: 文章标题 2026:包含核心关键词的完整标题
description: 150-160 字符的描述文本,包含主关键词和辅助关键词,自然语句。
keywords:
- 关键词1
- 关键词2
- 关键词3
head:
- - meta
- property: og:image
content: https://example.com/og-image.jpg
- - meta
- name: twitter:image
content: https://example.com/og-image.jpg
---frontmatter SEO 检查清单:
✅ title 包含核心关键词,建议 30-60 字符
✅ description 150-160 字符(Google 搜索结果摘要上限)
✅ keywords 写 5-8 个相关关键词(Google 已不参考,但 Bing 仍使用)
✅ og:image 每篇都配独立封面图(1200×630px 最佳)
✅ twitter:image 与 og:image 可共用同一张图
✅ title 格式:核心关键词 + 副标题(用「:」或「|」分隔)结构化数据(JSON-LD)
结构化数据能让搜索引擎理解页面内容类型,从而在搜索结果中展示富摘要(Rich Snippets),大幅提升点击率(CTR)。
本站实践:transformPageData 自动注入
本站通过 transformPageData 在构建时自动为每个页面注入 JSON-LD:
// .vitepress/configs/transformPageData.ts
import type { UserConfig } from 'vitepress'
const baseUrl = 'https://y-m.top'
const defaultOgImage = '/logo/y-m-top-og.webp'
export const transformPageData: UserConfig['transformPageData'] = (pageData) => {
pageData.frontmatter.head ??= []
// 1. 生成 canonical URL
let DynamicUrl = `${baseUrl}/${pageData.relativePath}`.replace(/\.md$/, '')
if (DynamicUrl.endsWith('/index')) {
DynamicUrl = DynamicUrl.slice(0, -5)
}
const title = pageData.frontmatter?.hero?.name || pageData.title || '站点名'
const description = pageData.frontmatter?.hero?.tagline || pageData.description || ''
const modified_time = pageData.lastUpdated
? new Date(pageData.lastUpdated).toISOString()
: new Date().toISOString()
// 2. 获取 og:image(优先 frontmatter 中的,回退默认)
const ogImageEntry = pageData.frontmatter.head.find(
(item: any) => item[0] === 'meta' && item[1]?.property === 'og:image'
)
const ogImage = ogImageEntry?.[1]?.content || defaultOgImage
// 3. 根据页面类型生成不同的 JSON-LD
const isHome = pageData.relativePath === 'index.md'
const jsonLd = isHome
? {
'@context': 'https://schema.org',
'@type': 'WebSite', // 首页用 WebSite 类型
url: baseUrl + '/',
inLanguage: 'zh-Hans',
author: { '@type': 'Person', name: 'y-m.top', url: baseUrl },
publisher: {
'@type': 'Organization',
name: 'y-m.top',
logo: { '@type': 'ImageObject', url: baseUrl + '/logo/y-m-top-og.webp' }
},
description: description,
name: title
}
: {
'@context': 'https://schema.org',
'@type': 'BlogPosting', // 文章页用 BlogPosting 类型
headline: title,
inLanguage: 'zh-Hans',
author: { '@type': 'Person', name: 'y-m.top', url: baseUrl },
publisher: {
'@type': 'Organization',
name: 'y-m.top',
logo: { '@type': 'ImageObject', url: baseUrl + '/logo/y-m-top-og.webp' }
},
mainEntityOfPage: DynamicUrl,
description: description,
url: DynamicUrl,
image: ogImage
}
// 4. 批量注入 head 标签
pageData.frontmatter.head.push(
['link', { rel: 'canonical', href: DynamicUrl }],
['meta', { property: 'og:title', content: title }],
['meta', { property: 'og:url', content: DynamicUrl }],
['meta', { property: 'og:image', content: ogImage }],
['meta', { property: 'og:description', content: description }],
['meta', { name: 'twitter:title', content: title }],
['meta', { name: 'twitter:image', content: ogImage }],
['meta', { name: 'twitter:description', content: description }],
['meta', { property: 'article:published_time', content: '2020-07-21T08:17:36.000Z' }],
['meta', { property: 'article:modified_time', content: modified_time }],
['script', { type: 'application/ld+json' }, JSON.stringify(jsonLd)]
)
}常用 Schema 类型选择
| Schema 类型 | 适用场景 | 富摘要效果 |
|---|---|---|
WebSite | 首页 | 站点名称 + 搜索框 |
BlogPosting | 博客文章 | 标题 + 作者 + 发布日期 + 封面图 |
TechArticle | 技术教程 | 同 BlogPosting,更适合技术内容 |
FAQPage | FAQ 页面 | 折叠式问答展示 |
BreadcrumbList | 面包屑导航 | 搜索结果中显示路径 |
HowTo | 教程步骤 | 分步展示 |
Article | 通用文章 | 标题 + 日期 + 图片 |
FAQPage 结构化数据示例
如果你的文章底部有 FAQ 折叠块,可以额外注入 FAQPage Schema:
// 在文章 <script setup> 中动态注入
import { onMounted } from 'vue'
onMounted(() => {
const script = document.createElement('script')
script.type = 'application/ld+json'
script.text = JSON.stringify({
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "VitePress 需要装 SEO 插件吗?",
"acceptedAnswer": {
"@type": "Answer",
"text": "VitePress 原生支持 SSG、Sitemap 和 head 配置,基本 SEO 不需要额外插件。结构化数据可通过 transformPageData 自动注入。"
}
}
]
})
document.head.appendChild(script)
})⚠️ 注意:FAQPage 的内容必须与页面可见的 FAQ 文本完全一致,否则可能被 Google 判定为作弊。
Sitemap 与 Robots
VitePress 内置 Sitemap
VitePress 2.0 内置了 sitemap 生成功能,只需一行配置:
// .vitepress/config.mts
export default defineConfig({
sitemap: {
hostname: 'https://y-m.top'
}
})构建完成后,dist/sitemap.xml 会自动生成。配合 cleanUrls: true,所有 URL 都是无 .html 后缀的干净链接。
IndexNow 自动提交
Sitemap 生成后,搜索引擎需要主动去抓取。本站通过 buildEnd 钩子在每次构建完成后自动向 IndexNow 提交所有 URL:
// .vitepress/configs/buildEnd.ts
import path from 'node:path'
import fs from 'node:fs'
import type { SiteConfig } from 'vitepress'
export async function buildEnd(siteConfig: SiteConfig) {
try {
const sitemapPath = path.resolve(siteConfig.outDir, 'sitemap.xml')
// 轮询等待 sitemap.xml 生成(最多等 5 秒)
let retryCount = 0
while (!fs.existsSync(sitemapPath) && retryCount < 10) {
await new Promise(resolve => setTimeout(resolve, 500))
retryCount++
}
if (!fs.existsSync(sitemapPath)) {
console.warn('\n⚠️ 未找到 sitemap.xml, 退出了 IndexNow 提交')
return
}
// 从 sitemap.xml 中提取所有 URL
const sitemapContent = fs.readFileSync(sitemapPath, 'utf-8')
const urls = [...sitemapContent.matchAll(/<loc>(.*?)<\/loc>/g)].map(m => m[1])
// 向 IndexNow API 提交
const key = 'your-indexnow-key'
const data = JSON.stringify({
host: 'y-m.top',
key: key,
keyLocation: `https://y-m.top/${key}.txt`,
urlList: urls
})
const res = await fetch('https://api.indexnow.org/indexnow', {
method: 'POST',
headers: { 'Content-Type': 'application/json; charset=utf-8' },
body: data
})
if (res.ok) {
console.log(`\n🎉 成功将 ${urls.length} 个链接提交至 IndexNow!`)
} else {
console.error(`\n❌ 提交 IndexNow 失败: ${res.status} ${res.statusText}`)
}
} catch (error) {
console.error('\n❌ 提交 IndexNow 时引发错误:', error)
}
}IndexNow 支持的搜索引擎:
| 搜索引擎 | 支持 IndexNow | 备注 |
|---|---|---|
| Bing | ✅ | 即时索引,效果最明显 |
| Yandex | ✅ | 俄罗斯搜索引擎 |
| Seznam | ✅ | 捷克搜索引擎 |
| ❌ | 不支持 IndexNow,需通过 GSC 提交 Sitemap | |
| 百度 | ❌ | 需在百度搜索资源平台手动提交 |
💡 IndexNow 的密钥需要是一个 8-32 位的十六进制字符串,同时在站点根目录放一个
密钥.txt文件用于验证。
robots.txt 配置
在 public/robots.txt 中配置:
User-agent: *
Allow: /
Disallow: /tw/ # 如果繁体镜像不想被索引
Sitemap: https://y-m.top/sitemap.xml如果你不希望繁体镜像页面被搜索引擎收录(避免重复内容惩罚),可以通过 robots.txt 或
meta robots标签禁止爬取。
搜索引擎站长平台提交
| 平台 | 提交方式 | 链接 |
|---|---|---|
| Google Search Console | Sitemap + URL 检查 | search.google.com/search-console |
| Bing Webmaster Tools | Sitemap + IndexNow | bing.com/webmasters |
| 百度搜索资源平台 | Sitemap + 主动推送 | ziyuan.baidu.com |
| 搜狗站长平台 | Sitemap 提交 | zhanzhang.sogou.com |
Core Web Vitals 性能优化
Core Web Vitals 是 Google 排名的重要信号,三个核心指标:
三大指标解读
| 指标 | 全称 | 含义 | 良好阈值 | 评分权重 |
|---|---|---|---|---|
| LCP | Largest Contentful Paint | 最大内容绘制时间 | ≤ 2.5s | 最重要 |
| CLS | Cumulative Layout Shift | 累积布局偏移 | ≤ 0.1 | 视觉稳定性 |
| INP | Interaction to Next Paint | 交互到下一次绘制 | ≤ 200ms | 替代旧 FID 指标 |
LCP 优化策略
LCP 元素通常是首屏的大图或大标题。优化方向:
1. 图片优化
// VitePress 中使用 Vite 的资源处理能力
// .vitepress/config.mts
export default defineConfig({
vite: {
assetsInclude: ['**/*.webp', '**/*.svg', '**/*.gif', '**/*.png', '**/*.jpg', '**/*.jpeg'],
}
})| 优化手段 | 效果 | 实施难度 |
|---|---|---|
| 使用 WebP 格式代替 JPG/PNG | 体积减少 25-35% | ⭐ |
设置 loading="lazy" 非首屏图片 | 减少首屏加载量 | ⭐ |
首屏图片设置 fetchpriority="high" | 优先加载 LCP 图片 | ⭐ |
| 图片设置 width/height 属性 | 避免 CLS 偏移 | ⭐ |
| 使用 CDN 分发图片 | 减少网络延迟 | ⭐⭐ |
使用 <picture> 响应式图片 | 按设备加载不同尺寸 | ⭐⭐ |
首屏图片优先加载示例:
<img
src="/cover.webp"
alt="封面图"
width="1200"
height="630"
loading="eager"
fetchpriority="high"
/>2. 字体加载优化
/* 通过 font-display: swap 避免字体加载阻塞渲染 */
@font-face {
font-family: 'CustomFont';
src: url('/fonts/custom.woff2') format('woff2');
font-display: swap; /* 关键:先用系统字体渲染,字体加载后替换 */
}3. 关键 CSS 内联
VitePress 默认将关键 CSS 内联到 HTML <head> 中,无需额外配置。metaChunk: true 可以将 meta 信息提取为独立 chunk,进一步减小主 HTML 体积。
CLS 优化策略
CLS(累积布局偏移)通常由以下原因导致:
| 原因 | 解决方案 |
|---|---|
| 图片无尺寸属性 | 添加 width 和 height |
| 字体加载导致文字跳动 | 使用 font-display: swap + size-adjust |
| 广告/嵌入内容高度变化 | 预留占位空间 min-height |
| 动态插入内容 | 在已渲染内容上方插入时使用 transform |
INP 优化策略
INP 替代了旧的 FID 指标,衡量页面的整体交互响应速度:
优化方向:
1. 减少 JavaScript 执行时间
- 代码分割(Code Splitting)
- 延迟加载非关键 JS(defer / async)
- Tree Shaking 去除无用代码
2. 拆分长任务(Long Task)
- 使用 requestIdleCallback / scheduler.postTask
- 将大任务拆分为 < 50ms 的小任务
3. 减少第三方脚本
- 延迟加载分析脚本
- 使用 Partytown 将第三方 JS 移入 Web Worker性能检测工具
| 工具 | 用途 | 推荐度 |
|---|---|---|
| PageSpeed Insights | 线上检测 LCP/CLS/INP + 优化建议 | ⭐⭐⭐⭐⭐ |
| Lighthouse | Chrome DevTools 内置,本地检测 | ⭐⭐⭐⭐⭐ |
| Core Web Vitals Report | GSC 中的真实用户数据 | ⭐⭐⭐⭐ |
| Web Vitals Chrome 扩展 | 实时查看当前页面指标 | ⭐⭐⭐⭐ |
| CrUX Dashboard | Chrome 用户体验报告数据可视化 | ⭐⭐⭐ |
Open Graph 与社交分享
OG 标签完整配置
Open Graph 协议决定了链接在微信 / Twitter / Facebook / Telegram 等社交平台上的预览卡片样式:
| OG 标签 | 作用 | 示例值 |
|---|---|---|
og:type | 内容类型 | website / article |
og:title | 分享标题 | 文章标题 |
og:description | 分享描述 | 150 字以内摘要 |
og:image | 分享封面图 | 1200×630px |
og:url | 页面 canonical URL | https://y-m.top/xxx |
og:site_name | 站点名称 | 你的博客名 |
og:locale | 语言区域 | zh-Hans |
twitter:card | Twitter 卡片类型 | summary_large_image |
twitter:image | Twitter 封面图 | 同 og:image |
本站通过 transformPageData 自动注入所有 OG 标签,无需手动在每篇文章中重复配置。
OG 图片设计规范
📐 尺寸:1200 × 630 px(推荐)
📐 比例:1.91:1
📐 格式:JPG / PNG / WebP
📐 文件大小:≤ 300KB
📐 安全区域:中心 1200×630,边缘留 80px 安全区
设计建议:
- 使用品牌色作为背景
- 标题文字 ≥ 42px,确保移动端可读
- 添加站点 Logo(左下角或右下角)
- 使用 Unsplash 免费图片作为封面(本站实践)社交预览测试工具
| 工具 | 用途 |
|---|---|
| Meta Sharing Debugger | Facebook / WhatsApp 预览 |
| Twitter Card Validator | Twitter 卡片预览 |
| OpenGraph.xyz | 多平台预览 |
| 微信文件传输助手 | 发送链接查看微信内预览效果 |
内链策略
内链是 SEO 中最容易被忽视的部分,良好的内链结构能帮助搜索引擎理解站点架构,传递页面权重。
相关文章推荐
在每篇文章末尾添加「延伸阅读」区块,手动推荐 5-7 篇相关文章:
## 延伸阅读
- [流媒体观影终极指南](/streaming/2026-ultimate-core-guide)
- [Netflix 国内观看指南 2026](/streaming/netflix-guide)
- [优质机场推荐与选购指南](/serve/airport/summary)内链锚文本最佳实践:
✅ 好的锚文本:
- 「Netflix 国内观看指南 2026」→ 包含关键词 + 年份
- 「优质机场推荐」→ 简洁描述目标页面内容
❌ 差的锚文本:
- 「点击这里」→ 无信息量
- 「这篇文章」→ 搜索引擎无法理解目标页面主题面包屑导航
VitePress 默认侧边栏提供了层级导航。如果需要额外的面包屑结构化数据:
// 面包屑 BreadcrumbList JSON-LD
const breadcrumbJsonLd = {
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "首页",
"item": "https://y-m.top/"
},
{
"@type": "ListItem",
"position": 2,
"name": "技术笔记",
"item": "https://y-m.top/notes/"
},
{
"@type": "ListItem",
"position": 3,
"name": "VitePress",
"item": "https://y-m.top/notes/vitepress/"
}
]
}内链密度建议
| 指标 | 建议值 | 说明 |
|---|---|---|
| 每篇内链数量 | 5-8 个 | 过少不够,过多像垃圾站 |
| 内链锚文本多样性 | ≥ 3 种 | 不要所有链接都用相同锚文本 |
| 相关性 | 高 | 只链接主题相关的文章 |
| 深度链接比例 | ≥ 60% | 链接到具体文章而非分类页 |
站点分析集成
三大分析工具对比
| 工具 | 隐私友好 | 免费 | 国内可用 | 特点 |
|---|---|---|---|---|
| Google Analytics 4 | ⚠️ 一般 | ✅ | ❌ 需代理 | 功能最全,生态最好 |
| Umami | ✅ 优秀 | ✅ 自建 | ✅ | 轻量、隐私友好、Cookieless |
| Plausible | ✅ 优秀 | 💰 付费 | ✅ | 开源、简洁、GDPR 合规 |
| 百度统计 | ⚠️ 一般 | ✅ | ✅ | 国内访问无障碍 |
| Cloudflare Web Analytics | ✅ 优秀 | ✅ | ✅ | 免费、隐私友好、无脚本 |
GA4 配置(本站实践)
本站使用 Google Analytics 4,在 head.ts 中全局注入:
// .vitepress/configs/head.ts
export const head: HeadConfig[] = [
// ... 其他配置
[
'script',
{ async: '', src: 'https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX' }
],
[
'script',
{},
`window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXXXXXXX');`
]
]⚠️ GA4 在国内部分网络环境下可能加载缓慢。如果你的读者主要在国内,建议同时接入 Umami 或百度统计作为补充。
Umami 自建方案
# Docker 一键部署 Umami
docker run -d \
--name umami \
-p 3000:3000 \
-e DATABASE_URL=postgresql://umami:umami@db:5432/umami \
-e HASH_SALT=your-random-salt \
ghcr.io/umami-software/umami:latest
# 在 VitePress head 中添加追踪代码
# <script async src="https://umami.your-domain.com/script.js" data-website-id="xxx"></script>PWA 与离线访问
VitePress PWA 插件
使用 vite-plugin-pwa 为 VitePress 添加 PWA 能力:
// .vitepress/config.mts
import { VitePWA } from 'vite-plugin-pwa'
export default defineConfig({
vite: {
plugins: [
VitePWA({
registerType: 'autoUpdate',
includeAssets: ['favicon.svg', 'favicon.ico', 'robots.txt'],
manifest: {
name: '你的站点名',
short_name: '简称',
description: '站点描述',
theme_color: '#ffffff',
icons: [
{
src: 'pwa-192x192.png',
sizes: '192x192',
type: 'image/png'
},
{
src: 'pwa-512x512.png',
sizes: '512x512',
type: 'image/png'
}
]
},
workbox: {
// 预缓存 VitePress 构建产物
globPatterns: ['**/*.{css,js,html,svg,png,ico,txt,woff2}'],
// 运行时缓存策略
runtimeCaching: [
{
urlPattern: /^https:\/\/images\.unsplash\.com\/.*/i,
handler: 'CacheFirst',
options: {
cacheName: 'unsplash-images',
expiration: {
maxEntries: 100,
maxAgeSeconds: 60 * 60 * 24 * 30 // 30 天
}
}
}
]
}
})
]
}
})PWA 缓存策略选择
| 策略 | 适用场景 | 说明 |
|---|---|---|
CacheFirst | 静态资源(CSS/JS/字体/图标) | 优先缓存,缓存不存在才请求 |
NetworkFirst | HTML 页面 | 优先网络,离线时回退缓存 |
StaleWhileRevalidate | 图片/API 数据 | 先返回缓存,同时后台更新 |
NetworkOnly | 分析请求 | 不缓存,始终请求网络 |
CacheOnly | 离线页面 | 只用缓存 |
💡 VitePress 的 HTML 页面建议用
NetworkFirst——保证用户看到最新内容,同时离线时也能访问缓存版本。
Google Search Console 监测
配置流程
添加站点属性
- 访问 Google Search Console
- 添加域名属性(推荐)或 URL 前缀属性
- 通过 DNS TXT 记录验证
提交 Sitemap
- 在 GSC 左侧菜单 → Sitemaps
- 输入
sitemap.xml并提交 - 等待 Google 处理(通常 1-3 天)
请求索引
- 对于新发布的重要文章,使用 URL 检查工具
- 点击「请求编入索引」
- 加速首次收录
关键指标监测
| 指标 | 位置 | 含义 |
|---|---|---|
| 索引覆盖率 | 索引 → 网页 | 已被 Google 索引的页面数 |
| 搜索表现 | 搜索结果 → 搜索分析 | 展示次数 / 点击次数 / CTR / 平均排名 |
| Core Web Vitals | 体验 → 核心网页指标 | LCP / CLS / INP 真实用户数据 |
| 移动设备易用性 | 体验 → 移动设备易用性 | 移动端友好度报告 |
| 链接报告 | 链接 → 外部链接 / 内部链接 | 反向链接和内链统计 |
常见索引问题排查
问题 1:页面未被索引
→ 检查 robots.txt 是否屏蔽
→ 检查 meta robots 是否为 noindex
→ 检查 canonical URL 是否正确
→ 在 GSC 中手动请求索引
问题 2:索引后排名低
→ 检查 title/description 是否包含目标关键词
→ 检查内容质量(字数、深度、原创性)
→ 检查内链数量和质量
→ 检查 Core Web Vitals 是否达标
问题 3:页面从索引中被移除
→ 检查服务器是否经常不可用(503 错误)
→ 检查是否被标记为重复内容
→ 检查是否被 Manual Action 处罚本站优化实践复盘
y-m.top 的 SEO 配置架构
本站的 VitePress 配置采用了模块化拆分,便于维护:
.vitepress/
├── config.mts # 主配置入口
├── configs/
│ ├── head.ts # 全局 head 标签
│ ├── transformPageData.ts # 动态 meta + JSON-LD 注入
│ ├── buildEnd.ts # 构建后 IndexNow 提交
│ ├── nav.ts # 导航栏
│ ├── sidebar.ts # 侧边栏
│ ├── search.ts # 搜索配置
│ ├── markdown.ts # Markdown 插件
│ └── socialLinks.ts # 社交链接
└── theme/ # 自定义主题关键配置汇总
// .vitepress/config.mts 中的 SEO 相关配置
export default defineConfig({
head, // 全局 meta 标签
sitemap: { // 站点地图
hostname: 'https://y-m.top'
},
transformPageData, // 自动注入 canonical/og/json-ld
buildEnd, // 构建后 IndexNow 提交
cleanUrls: true, // 干净 URL
metaChunk: true, // meta 独立 chunk
lastUpdated: true, // 记录更新时间
srcDir: 'content', // 源文件目录
})繁体镜像的 SEO 处理
本站有简体 / 繁体双版本,为了避免重复内容问题:
| 处理方式 | 说明 |
|---|---|
| URL 分离 | 简体 /streaming/xxx,繁体 /tw/streaming/xxx |
hreflang 标签 | 告诉搜索引擎两个版本的关系 |
| robots.txt | 可选:禁止爬取 /tw/ 目录 |
| OpenCC 转换 | 使用 opencc-js 自动转换简→繁 |
// 简体→繁体自动转换(本站实践)
import * as OpenCC from 'opencc-js'
const converter = OpenCC.Converter({ from: 'cn', to: 'tw', _config: 's2t' })
// 在 locales 中配置繁体版本
locales: {
root: { label: '简体中文', lang: 'zh-Hans', ... },
tw: {
label: '繁體中文',
lang: 'zh-Hant',
link: '/tw/',
title: converter('简体标题'),
description: converter('简体描述'),
...
}
}优化效果数据
经过以上优化,本站在 SEO 方面的表现:
| 指标 | 优化前 | 优化后 | 提升幅度 |
|---|---|---|---|
| Google 索引页面数 | ~50 | 400+ | 8 倍 |
| Lighthouse SEO 评分 | 75 | 100 | +25 |
| Lighthouse 性能评分 | 82 | 96 | +14 |
| LCP(首屏绘制) | 3.2s | 1.1s | -66% |
| CLS(布局偏移) | 0.15 | 0.02 | -87% |
| Bing 收录速度 | 数周 | 24h 内 | IndexNow 效果 |
SEO 优化检查清单
将上述所有要点整理为一份可操作的检查清单:
基础配置
□ 配置 sitemap.hostname
□ 开启 cleanUrls: true
□ 开启 lastUpdated: true
□ 开启 metaChunk: true
□ 配置全局 head 标签(favicon / robots / og 默认值)
□ 配置 public/robots.txt
□ 配置 public/站点验证文件(Google / Bing / 百度)每篇文章
□ title 包含核心关键词(30-60 字符)
□ description 150-160 字符
□ keywords 5-8 个相关关键词
□ og:image 独立封面图(1200×630px)
□ jsonLD 结构化数据(TechArticle / BlogPosting)
□ 文章末尾 5-7 个内链(延伸阅读)
□ 图片设置 width / height / alt 属性
□ 首屏图片设置 fetchpriority="high"构建与部署
□ transformPageData 自动注入 canonical / og / json-ld
□ buildEnd 钩子自动提交 IndexNow
□ 图片使用 WebP 格式
□ 第三方脚本使用 async / defer
□ PWA Service Worker 缓存策略配置
□ GA4 / Umami 分析代码接入持续监测
□ 每周检查 Google Search Console 索引状态
□ 每月检查 Core Web Vitals 真实用户数据
□ 定期检查 Lighthouse 性能评分
□ 监控搜索关键词排名变化
□ 检查死链(404 页面)并修复
□ 每月提交一次 Sitemap(确保新页面被收录)常见问题(FAQ)
Q1:VitePress 需要安装额外的 SEO 插件吗?
不需要。VitePress 2.0 原生提供:
• SSG 预渲染 → 搜索引擎可直接读取 HTML 内容
• 内置 sitemap.xml 生成
• head 配置 → 全局 meta 标签管理
• transformPageData → 构建时动态注入 meta 和 JSON-LD
• cleanUrls → URL 无 .html 后缀
以上能力已覆盖 90% 的 SEO 需求。唯一可能需要插件的是 PWA 功能(vite-plugin-pwa)。Q2:为什么我的文章在 Google 搜索中显示的标题和 frontmatter 中的不一样?
Google 可能会根据搜索关键词自动重写标题。常见原因:
• title 过长或过短 → Google 认为需要优化
• title 与搜索意图不匹配 → Google 使用 H1 或描述文本
• title 中关键词堆砌 → Google 简化
解决方法:
• 确保 title 简洁明了(30-60 字符)
• title 包含核心关键词
• H1 与 title 保持一致
• 使用 GSC URL 检查工具查看 Google 实际抓取的标题Q3:VitePress 的 SSG 和 CSR 有什么区别?对 SEO 有什么影响?
SSG(Static Site Generation):
• 构建时预渲染为完整 HTML
• 搜索引擎爬虫无需执行 JS 即可获取内容
• VitePress 默认使用 SSG → SEO 友好 ✅
CSR(Client-Side Rendering):
• 浏览器加载 JS 后才渲染内容
• 部分搜索引擎爬虫不执行 JS → 可能无法索引
• VitePress 不使用纯 CSR
结论:VitePress 的 SSG 模式天然 SEO 友好,无需额外处理。
但注意:<script setup> 中动态生成的内容不会被预渲染到 HTML 中,
仅靠客户端 JS 执行。重要的 SEO 内容(标题、描述)应放在 frontmatter 中。Q4:如何加速 Google 对新文章的收录?
最快路径:
1. 发布文章后立即触发构建部署
2. buildEnd 钩子自动提交 IndexNow → Bing 即时收录
3. 在 GSC 中使用 URL 检查工具 → 请求编入索引
4. 在已收录的文章中添加新文章的内链
5. 确保新文章在 sitemap.xml 中(VitePress 自动生成)
通常新文章 1-3 天内会被 Google 收录。
如果超过一周仍未收录,检查 robots.txt 和 meta robots 是否有误。Q5:本站同时有简体和繁体版本,会被 Google 判定为重复内容吗?
风险存在但可规避:
方案 1:禁止繁体索引(简单粗暴)
→ robots.txt 中 Disallow: /tw/
→ 适合只面向简体中文用户
方案 2:使用 hreflang 标签(推荐)
→ 在 head 中添加 hreflang 互指
→ 告诉 Google 两个版本是同一内容的不同语言变体
方案 3:canonical 指向简体版
→ 繁体页面 canonical 指向简体版
→ Google 会只索引简体版,但不影响用户访问繁体
本站目前使用方案 1(robots.txt 禁止 /tw/),因为目标受众主要是简体中文用户。Q6:Cloudflare Pages / Vercel / Netlify 哪个对 VitePress SEO 更好?
三者都能完美支持 VitePress 部署,SEO 差异不大:
| 平台 | CDN 节点 | 自定义 Header | 预渲染 | 免费额度 |
|------|---------|:--:|:--:|:--:|
| Cloudflare Pages | 全球 300+ | ✅ | ✅ | 无限 |
| Vercel | 全球 100+ | ✅ | ✅ | 100GB/月 |
| Netlify | 全球 100+ | ✅ | ✅ | 100GB/月 |
推荐 Cloudflare Pages:
• 全球边缘节点最多,访问速度最快
• 无限免费请求量
• 原生支持自定义 Header 和重定向规则
• 参考 [VitePress + Cloudflare Pages 搭建指南](/notes/vitepress/build-with-cloudflare)总结
VitePress 的 SEO 优化不需要复杂的插件体系——框架原生能力已经覆盖了绝大部分需求。以本站 y-m.top 的实践经验来看,做好以下五件事就能达到 95 分以上:
🎯 1. transformPageData 自动注入
→ canonical URL + og 标签 + JSON-LD 结构化数据
→ 一处配置,所有页面自动生效
🎯 2. Sitemap + IndexNow 自动提交
→ sitemap.hostname 配置 + buildEnd 钩子
→ 新文章发布后 Bing 24h 内收录
🎯 3. Core Web Vitals 优化
→ WebP 图片 + fetchpriority + font-display: swap
→ LCP ≤ 2.5s / CLS ≤ 0.1 / INP ≤ 200ms
🎯 4. 内链策略
→ 每篇文章 5-8 个延伸阅读链接
→ 锚文本包含关键词 + 自然语句
🎯 5. Google Search Console 持续监测
→ 提交 Sitemap + 请求索引 + 监控排名
→ 定期检查索引覆盖率和 Core Web Vitals如果你正在使用 VitePress 搭建博客,希望本文的实践经验能帮你少走弯路。本站的所有配置代码都在仓库中公开,欢迎参考。
延伸阅读
- VitePress + Cloudflare Pages 搭建完全指南
- VitePress 宝塔面板部署完全指南
- VitePress Giscus 评论系统集成指南
- VitePress 图片放大功能配置
- GitHub Actions 完全指南:CI/CD 自动化部署
- Obsidian 知识管理完全指南
- Prettier 代码格式化配置指南
延伸阅读
免责声明
本文仅供技术交流和学习参考。涉及第三方服务的链接可能包含 sponsored 标记,请自行核实服务条款、价格和可用性,并遵守当地法律法规。