performance mobile
本地来源:seo-llm/skill/google-seo-skill/references/performance-mobile.md
性能优化与 Core Web Vitals
1. Core Web Vitals(2024+ 标准)
INP (Interaction to Next Paint) — 已替代 FID(2024年3月生效)
目标: < 200ms(75th percentile)
INP 测量页面整个生命周期中所有交互的响应速度,取最差交互的延迟。与 FID 不同,INP 关注的是所有交互而非仅首次交互。
INP vs FID 对比
| 维度 | FID(已废弃) | INP(当前标准) |
|---|---|---|
| 测量范围 | 仅首次交互的输入延迟 | 所有交互的完整延迟 |
| 计算方式 | 首次交互到浏览器开始处理 | 交互到下一帧渲染完成 |
| 覆盖阶段 | 仅 Input Delay | Input Delay + Processing + Presentation |
| 取值 | 单次测量 | 取 p98 最差值(近似最差交互) |
| 阈值 | < 100ms | < 200ms |
| 适用场景 | 简单页面 | 复杂SPA、多交互页面 |
INP 三阶段优化
用户交互 → [Input Delay] → [Processing Time] → [Presentation Delay] → 视觉更新
↑ 减少主线程阻塞 ↑ 优化事件处理器 ↑ 减少渲染工作
// ===== 阶段1: 减少 Input Delay =====
// ❌ 阻塞主线程的操作
function processLargeData(data: any[]) {
data.forEach(item => heavyComputation(item)) // 可能阻塞 >50ms
}
// ✅ 使用 scheduler.yield() 让出主线程(推荐,2024+ 浏览器支持)
async function processWithYield(data: any[]) {
const chunkSize = 50
for (let i = 0; i < data.length; i += chunkSize) {
const chunk = data.slice(i, i + chunkSize)
chunk.forEach(item => heavyComputation(item))
// scheduler.yield() 优于 setTimeout(0):保持任务优先级
if ('scheduler' in globalThis && 'yield' in scheduler) {
await scheduler.yield()
} else {
await new Promise(resolve => setTimeout(resolve, 0))
}
}
}
// ✅ 使用 requestIdleCallback 处理非紧急任务
function processWhenIdle(data: any[]) {
let index = 0
function processChunk(deadline: IdleDeadline) {
while (index < data.length && deadline.timeRemaining() > 5) {
heavyComputation(data[index++])
}
if (index < data.length) {
requestIdleCallback(processChunk)
}
}
requestIdleCallback(processChunk)
}
// ===== 阶段2: 优化 Processing Time =====
// ✅ 事件处理器中避免同步布局(强制重排)
// ❌ 错误示范
button.addEventListener('click', () => {
element.style.width = '100px' // 写入
const height = element.offsetHeight // 读取 → 触发强制重排!
element.style.height = height + 'px'
})
// ✅ 正确示范:读写分离
button.addEventListener('click', () => {
const height = element.offsetHeight // 先读取
element.style.width = '100px' // 再写入
element.style.height = height + 'px'
})
// ===== 阶段3: 减少 Presentation Delay =====
// ✅ 使用 CSS contain 减少渲染范围
// .widget { contain: layout style paint; }
// ✅ 使用 content-visibility 延迟渲染屏幕外内容
// .offscreen-section { content-visibility: auto; contain-intrinsic-size: 0 500px; }
// 2. 第三方脚本使用 async/defer
// ✅ 不阻塞页面交互
<script src="analytics.js" async></script>
<script src="widget.js" defer></script>
// ❌ 阻塞渲染和交互
<script src="heavy-library.js"></script>
Long Animation Frames (LoAF) 检测
LoAF 是 Long Tasks 的升级版,提供更详细的阻塞信息:
// 检测 Long Animation Frames(比 Long Tasks 更精确)
const loafObserver = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
// LoAF 阈值: > 50ms
console.warn('Long Animation Frame:', {
duration: entry.duration,
blockingDuration: entry.blockingDuration,
startTime: entry.startTime,
// LoAF 独有:可以看到具体的脚本信息
scripts: entry.scripts?.map(s => ({
sourceURL: s.sourceURL,
sourceFunctionName: s.sourceFunctionName,
invokerType: s.invokerType, // 'user-callback', 'event-listener', etc.
duration: s.duration,
})),
})
}
})
// 注意:LoAF 需要 Chrome 123+ 支持
try {
loafObserver.observe({ type: 'long-animation-frame', buffered: true })
} catch {
// 降级到 Long Tasks
const ltObserver = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (entry.duration > 50) {
console.warn('Long Task:', entry.duration, 'ms')
}
}
})
ltObserver.observe({ entryTypes: ['longtask'] })
}
INP 测量与调试工具
inp_measurement_tools:
chrome_devtools:
- "Performance 面板 → 录制交互 → 查看 Interaction track"
- "Lighthouse → Performance → Total Blocking Time(关联指标)"
web_vitals_library:
code: |
import { onINP } from 'web-vitals'
onINP((metric) => {
console.log('INP:', metric.value, 'ms')
console.log('交互元素:', metric.attribution?.interactionTarget)
console.log('交互类型:', metric.attribution?.interactionType)
// 发送到分析服务
sendToAnalytics({ name: 'INP', value: metric.value })
}, { reportAllChanges: true })
crux_api:
description: "CrUX API 获取真实用户 INP 数据"
url: "https://chromeuxreport.googleapis.com/v1/records:queryRecord"
LCP (Largest Contentful Paint)
目标: < 2.5s(75th percentile)
// LCP 优化策略
// 1. 预加载关键资源
<link rel="preload" href="/hero-image.webp" as="image" />
<link rel="preconnect" href="https://cdn.example.com" />
// 2. Next.js Image priority
<Image src="/hero.jpg" alt="..." priority />
// 3. 避免 render-blocking 资源
// ✅ 关键 CSS 内联
<style dangerouslySetInnerHTML={{ __html: criticalCSS }} />
// ✅ 非关键 CSS 异步加载
<link rel="preload" href="/styles.css" as="style"
onLoad="this.onload=null;this.rel='stylesheet'" />
CLS (Cumulative Layout Shift)
目标: < 0.1(75th percentile)
// CLS 优化策略
// 1. 图片和视频设置尺寸
<Image width={800} height={450} alt="..." src="/img.jpg" />
<video width="640" height="360" />
// 2. 为动态内容预留空间
<div style={{ minHeight: '300px' }}>
{isLoading ? <Skeleton height={300} /> : <DynamicContent />}
</div>
// 3. 避免在已有内容上方插入新内容
// ❌ 在顶部插入广告/横幅
// ✅ 使用 CSS transform 代替改变布局属性的动画
2. TTFB (Time to First Byte)
目标: < 800ms
ttfb_optimization:
server_side:
- "使用 CDN 分发静态资源"
- "启用 HTTP/2 或 HTTP/3"
- "服务器端缓存(Redis/Memcached)"
- "数据库查询优化"
next_js:
- "使用 SSG 预渲染静态页面"
- "ISR 增量静态再生成"
- "Edge Runtime 用于低延迟 API"
- "配置适当的缓存头"
3. 页面大小优化
目标: 首次加载页面总大小 < 1MB
// next.config.js - 性能优化配置
module.exports = {
images: {
formats: ['image/avif', 'image/webp'],
deviceSizes: [320, 640, 768, 1024, 1280, 1920],
imageSizes: [16, 32, 48, 64, 96, 128, 256],
},
// 压缩
compress: true,
// 代码分割优化
experimental: {
optimizeCss: true,
optimizePackageImports: ['@heroicons/react', 'lucide-react'],
},
// 生产环境移除 console
compiler: {
removeConsole: process.env.NODE_ENV === 'production',
},
}
4. 移动端优化
4.1 Viewport 配置(Google 强制要求)
<!-- ✅ 推荐配置(Google 可访问性要求) -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=5.0" />
<!-- ❌ 禁止禁用缩放(违反 WCAG 和 Google 指南) -->
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
viewport_rules:
必须设置:
- "width=device-width:适应设备宽度"
- "initial-scale=1.0:初始缩放比例"
推荐设置:
- "maximum-scale=5.0:允许用户缩放至5倍(无障碍要求)"
禁止设置:
- "user-scalable=no:禁止用户缩放(违反 WCAG 2.1 1.4.4)"
- "maximum-scale=1.0:等效于禁用缩放"
Google Mobile-Friendly 测试:
- "缺少 viewport meta 标签 → 移动端不友好 → 排名降低"
- "禁用缩放 → 可访问性扣分"
4.2 触摸目标规范(Google 要求 + WCAG)
touch_targets:
# === 尺寸要求 ===
minimum_size:
google_requirement: "48x48 CSS像素(移动端最低要求)"
wcag_2_5_5_aaa: "44x44 CSS像素(WCAG AAA级)"
apple_hig: "44x44 点(iOS Human Interface Guidelines)"
material_design: "48x48 dp(Material Design 3)"
recommended: "48x48px 最小点击区域,视觉大小可小于此"
# === 间距要求 ===
spacing:
minimum: "8px 间距(相邻可点击元素之间)"
recommended: "12-16px 间距(复杂表单中)"
google_lighthouse_flag: "间距 < 8px 时 Lighthouse 会报告问题"
# === 实施方式 ===
implementation:
css_padding: |
/* ✅ 用 padding 扩大点击区域,而非增大视觉尺寸 */
.touch-target {
min-width: 48px;
min-height: 48px;
padding: 12px;
}
invisible_expand: |
/* ✅ 透明扩展区域(视觉紧凑,点击友好) */
.small-icon-button {
position: relative;
}
.small-icon-button::after {
content: '';
position: absolute;
inset: -8px; /* 向四周扩展8px */
}
# === 例外情况 ===
exceptions:
- "行内文本链接(不需要满足 48px 要求)"
- "由用户自定义大小的控件"
- "法律合规性要求的小字体链接(如隐私政策底部链接)"
# === 检测工具 ===
detection:
- "Chrome DevTools → Lighthouse → SEO → Tap targets"
- "Google Mobile-Friendly Test"
- "PageSpeed Insights → SEO 审计"
4.3 字体与可读性
font_requirements:
# === 最小字号 ===
minimum_font_size:
body_text: "16px(移动端正文最低要求)"
reason: "< 16px 会导致 iOS Safari 自动缩放表单输入框"
secondary_text: "14px(辅助信息、标注等)"
minimum_readable: "12px(绝对最小值,仅用于法律声明等)"
# === 行高与间距 ===
line_height:
body: "≥ 1.5(WCAG 1.4.12 要求)"
heading: "≥ 1.2"
tight_text: "≥ 1.3(列表项等紧凑场景)"
# === 段落宽度 ===
paragraph_width:
optimal: "45-75 字符每行(英文)/ 25-35 字符每行(中文)"
max_width: "使用 max-width: 65ch 限制段落宽度"
# === 对比度要求 ===
contrast:
wcag_aa: "正常文本 4.5:1,大文本 3:1"
wcag_aaa: "正常文本 7:1,大文本 4.5:1"
large_text_threshold: "≥ 18px 或 ≥ 14px 加粗"
tools:
- "Chrome DevTools → 元素 → Contrast ratio"
- "WebAIM Contrast Checker"
4.4 防止水平滚动
horizontal_scroll_prevention:
# === 常见原因与修复 ===
common_causes:
fixed_width_elements:
problem: "固定宽度元素超出屏幕"
fix: "使用 max-width: 100% 代替固定 width"
images:
problem: "图片未设置最大宽度"
fix: "img { max-width: 100%; height: auto; }"
tables:
problem: "表格宽度超出视口"
fix: "使用 overflow-x: auto 的容器包裹表格"
code_blocks:
problem: "代码块无换行"
fix: "pre { overflow-x: auto; white-space: pre-wrap; }"
absolute_positioning:
problem: "绝对定位元素超出边界"
fix: "父容器设置 overflow: hidden"
# === 全局防护 CSS ===
global_protection: |
/* ✅ 防止水平溢出的全局样式 */
html, body {
overflow-x: hidden; /* 最后手段,优先修复根本原因 */
max-width: 100vw;
}
* {
box-sizing: border-box;
}
img, video, iframe, embed, object {
max-width: 100%;
height: auto;
}
# === 检测方法 ===
detection:
javascript: |
// 检测是否存在水平滚动
if (document.documentElement.scrollWidth > document.documentElement.clientWidth) {
console.warn('页面存在水平滚动!');
// 找出溢出元素
document.querySelectorAll('*').forEach(el => {
if (el.scrollWidth > document.documentElement.clientWidth) {
console.warn('溢出元素:', el, '宽度:', el.scrollWidth);
}
});
}
lighthouse: "Lighthouse → SEO → Content is not sized correctly for the viewport"
4.5 响应式设计规范
responsive_design:
# === 移动优先断点 ===
breakpoints:
mobile: "320px(基础设计起点)"
mobile_large: "375px(iPhone 标准)"
tablet: "768px(iPad 竖屏)"
desktop: "1024px(桌面起点)"
wide: "1280px(宽屏优化)"
# === 断点策略 ===
strategy:
approach: "mobile-first(使用 min-width 媒体查询)"
css_example: |
/* 移动端基础(无媒体查询) */
.container { padding: 16px; }
/* 平板增强 */
@media (min-width: 768px) {
.container { padding: 24px; max-width: 720px; margin: 0 auto; }
}
/* 桌面增强 */
@media (min-width: 1024px) {
.container { padding: 32px; max-width: 960px; }
}
# === 测试要求 ===
testing:
必须测试设备:
- "iPhone SE (375px) — 最小主流 iPhone"
- "iPhone 14/15 (390px) — 标准 iPhone"
- "iPad (768px) — 平板竖屏"
- "iPad 横屏 (1024px) — 平板/小桌面"
- "桌面 (1280px+) — 标准桌面"
测试工具:
- "Chrome DevTools Device Mode"
- "真实设备测试(iOS Safari + Android Chrome)"
- "BrowserStack / LambdaTest(跨设备测试)"
常见遗漏:
- "横竖屏切换时布局断裂"
- "键盘弹出时内容被遮挡"
- "iOS Safari 底部安全区域(env(safe-area-inset-bottom))"
- "Android 刘海屏 / 折叠屏适配"
4.6 移动端性能预算
mobile_performance_budget:
# === 加载时间 ===
load_time:
mobile_3g: "< 3s 完全可交互(Slow 3G 模拟)"
mobile_4g: "< 1.5s 完全可交互"
首屏渲染: "< 1.5s FCP(移动 4G)"
# === 资源大小 ===
resource_budget:
total_page_weight: "< 1MB(首次加载)"
html: "< 100KB(压缩后)"
css: "< 100KB(压缩后)"
javascript: "< 300KB(压缩后,首屏关键 JS)"
images: "< 500KB(首屏可见图片总和)"
fonts: "< 100KB(WOFF2 格式)"
# === 优化策略 ===
strategies:
- "减少 JavaScript bundle(代码分割、Tree-shaking)"
- "使用 WebP/AVIF 图片格式(比 JPEG 小 25-50%)"
- "延迟加载非首屏内容(Intersection Observer)"
- "消除 render-blocking 资源(async/defer scripts)"
- "启用 Brotli/Gzip 压缩"
- "使用 CDN 分发静态资源"
- "Service Worker 缓存关键资源"
- "字体子集化(仅加载使用的字符)"
5. Long Tasks 消除
// 检测 Long Tasks
const observer = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
if (entry.duration > 50) {
console.warn('Long Task detected:', {
duration: entry.duration,
startTime: entry.startTime,
name: entry.name,
})
}
}
})
observer.observe({ entryTypes: ['longtask'] })
// 优化策略
// 1. Web Workers 处理重计算
const worker = new Worker('/workers/heavy-computation.js')
worker.postMessage({ data: largeDataSet })
worker.onmessage = (e) => updateUI(e.data)
// 2. requestAnimationFrame 分帧处理
function processInFrames(items: any[], callback: Function) {
let index = 0
function nextFrame() {
const start = performance.now()
while (index < items.length && performance.now() - start < 16) {
callback(items[index++])
}
if (index < items.length) {
requestAnimationFrame(nextFrame)
}
}
requestAnimationFrame(nextFrame)
}
6. 性能检测
使用 Google PageSpeed Insights 在线检测:https://pagespeed.web.dev/
性能指标阈值汇总:
| 指标 | 良好 | 需改进 | 差 |
|---|---|---|---|
| INP | < 200ms | 200-500ms | > 500ms |
| LCP | < 2.5s | 2.5-4.0s | > 4.0s |
| CLS | < 0.1 | 0.1-0.25 | > 0.25 |
| TTFB | < 800ms | 800-1800ms | > 1800ms |
| FCP | < 1.8s | 1.8-3.0s | > 3.0s |
7. PageSpeed Insights 算法与评分
7.1 Field Data vs Lab Data
field_data_vs_lab_data:
# === Field Data(真实用户数据)===
field_data:
别名: "RUM (Real User Monitoring)"
来源: "CrUX (Chrome User Experience Report)"
采集方式: "Chrome 浏览器匿名收集真实用户访问数据"
数据周期: "滚动 28 天数据聚合"
优点:
- "反映真实用户体验(不同设备、网络、地理位置)"
- "Google 排名算法直接使用的数据源"
- "包含 INP 等只能在真实交互中测量的指标"
缺点:
- "需要足够流量才有数据(月访问量需达到一定阈值)"
- "数据有 28 天延迟,无法反映即时优化效果"
- "无法精确定位具体问题来源"
阈值取值: "75th percentile(第75百分位)"
# === Lab Data(实验室数据)===
lab_data:
别名: "Synthetic Monitoring"
来源: "Lighthouse(模拟环境运行)"
采集方式: "固定设备配置 + 网络节流 模拟访问"
模拟环境:
设备: "Moto G Power(中端 Android 手机)"
CPU: "4x 降速(模拟中端设备性能)"
网络: "模拟 Slow 4G(RTT 150ms, 下行 1.6Mbps)"
优点:
- "可重复、可控环境,便于调试"
- "即时反馈,适合开发阶段"
- "提供详细的优化建议和诊断信息"
缺点:
- "不代表真实用户体验"
- "无法测量 INP(需要真实用户交互)"
- "Lab 环境可能比用户实际设备更好或更差"
# === 关键区别 ===
critical_difference:
Google_排名使用: "Field Data(CrUX)"
Lighthouse_分数: "Lab Data"
常见误解: "Lighthouse 100分不等于 CrUX 全绿"
建议: "两者都要关注,以 Field Data 为优化目标"
7.2 CrUX(Chrome 用户体验报告)
crux_details:
# === 数据收集 ===
data_collection:
来源: "已同意发送使用统计信息的 Chrome 用户"
覆盖范围: "仅公开可访问的 URL(需足够流量样本)"
粒度:
- "Origin 级别(整个域名聚合)"
- "URL 级别(单个页面)"
更新频率:
CrUX_API: "每 28 天更新"
BigQuery: "每月更新"
PageSpeed_API: "实时返回最近 28 天数据"
# === 包含指标 ===
metrics:
Core_Web_Vitals:
- "LCP(Largest Contentful Paint)"
- "INP(Interaction to Next Paint)"
- "CLS(Cumulative Layout Shift)"
其他指标:
- "FCP(First Contentful Paint)"
- "TTFB(Time to First Byte)"
- "实验性指标(如 Round Trip Time)"
# === 查看方式 ===
access_methods:
- tool: "PageSpeed Insights"
url: "https://pagespeed.web.dev/"
特点: "最直观,同时展示 Field + Lab 数据"
- tool: "Google Search Console"
path: "体验 → 核心网页指标"
特点: "按照 良好/需改进/差 分组显示所有 URL"
- tool: "CrUX API"
用途: "程序化批量查询"
示例: |
curl "https://chromeuxreport.googleapis.com/v1/records:queryRecord" \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "metrics": ["largest_contentful_paint", "interaction_to_next_paint", "cumulative_layout_shift"]}'
- tool: "CrUX BigQuery"
用途: "大规模数据分析、历史趋势"
数据集: "chrome-ux-report.all.{YYYYMM}"
# === 流量门槛 ===
traffic_threshold:
说明: "CrUX 需要足够的数据样本才会显示"
无数据时: "PageSpeed Insights 仅显示 Lab Data"
建议: "新站点 / 低流量站点应重点关注 Lab Data,用 Lighthouse CI 监控"
7.3 Lighthouse 评分算法(v12.0+)
lighthouse_scoring:
# === 性能分数权重(2024-2025 Lighthouse 12) ===
performance_weights:
TBT: { weight: "30%", 说明: "Total Blocking Time — Lab 中替代 INP 的指标" }
LCP: { weight: "25%", 说明: "Largest Contentful Paint" }
CLS: { weight: "25%", 说明: "Cumulative Layout Shift" }
SI: { weight: "10%", 说明: "Speed Index — 页面内容视觉填充速度" }
FCP: { weight: "10%", 说明: "First Contentful Paint" }
# === 评分范围 ===
score_ranges:
good:
range: "90-100"
颜色: "绿色"
含义: "性能优秀"
needs_improvement:
range: "50-89"
颜色: "橙色"
含义: "有优化空间"
poor:
range: "0-49"
颜色: "红色"
含义: "性能差,需要立即优化"
# === 评分计算方法 ===
calculation:
步骤:
1: "测量每个指标的原始值(如 LCP = 2.3s)"
2: "使用对数正态分布将原始值映射到 0-1 分数"
3: "每个指标分数 × 权重 = 加权分数"
4: "所有加权分数求和 = 最终性能分数(0-100)"
注意: "评分使用对数曲线,越接近满分越难提升"
# === 常见分数瓶颈 ===
bottleneck_analysis:
"分数 < 50":
常见原因:
- "大量 render-blocking 资源"
- "未优化的图片(无压缩、无 lazy-load)"
- "过大的 JavaScript bundle"
快速修复:
- "添加 async/defer 到非关键 script"
- "使用 WebP/AVIF 图片格式"
- "启用 Gzip/Brotli 压缩"
"分数 50-89":
常见原因:
- "LCP 元素加载慢(大图、Web Font)"
- "CLS 抖动(无尺寸的图片/广告)"
- "第三方脚本阻塞主线程"
优化方向:
- "预加载 LCP 元素:<link rel='preload'>"
- "为所有媒体设置 width/height"
- "延迟加载非关键第三方脚本"
"分数 90+":
维护策略:
- "设置 Lighthouse CI 防止回退"
- "监控 CrUX 数据确认真实用户体验"
- "定期审查新增依赖对性能的影响"
# === TBT 与 INP 的关系 ===
tbt_vs_inp:
说明: "Lighthouse Lab 环境无法测量 INP,因此用 TBT 作为替代指标"
TBT定义: "所有超过 50ms 的 Long Task 的阻塞时间总和"
对应关系: "TBT 高 → 主线程繁忙 → INP 大概率也差"
但不等价:
- "TBT 只测量页面加载期间,INP 覆盖整个生命周期"
- "TBT 是自动化测量,INP 需要真实用户交互"
- "TBT 可能通过延迟脚本优化,但 INP 仍可能因交互处理器慢而差"
建议: "TBT 用于开发阶段优化,INP 用于线上监控"
7.4 SEO 影响与排名关系
seo_ranking_impact:
# === Google 官方声明 ===
official_stance:
- "Core Web Vitals 是排名因素之一(Page Experience Signals)"
- "在内容质量相近的情况下,CWV 好的页面会获得排名优势"
- "CWV 不会覆盖高质量内容的排名优势"
# === 实际影响程度 ===
practical_impact:
高影响:
- "移动端搜索排名(Google Mobile-First Indexing)"
- "Top Stories / Discover 等展示位的资格要求"
中等影响:
- "桌面端搜索排名"
- "同质内容竞争时的 tie-breaker"
间接影响:
- "用户体验差 → 跳出率高 → 间接影响排名"
- "加载慢 → 爬虫预算浪费 → 索引覆盖率下降"
# === 优化优先级 ===
optimization_priority:
1: "内容质量和相关性(最重要)"
2: "技术 SEO 基础(可爬取、可索引)"
3: "Core Web Vitals(性能体验)"
4: "其他 Page Experience 信号(HTTPS、无插页广告等)"
建议: "不要为了 CWV 牺牲内容质量,但也不要忽视性能"
相关文档
- JavaScript SEO 与渲染优化 — JS 对性能与渲染的影响
- 语义化 HTML 与图片优化 — 图片懒加载与格式优化
- 部署后 SEO 检查 — 上线后性能验证清单
- SEO 工具与资源 — PageSpeed Insights 与 Lighthouse 工具
- 技术 SEO — 爬虫控制与索引优化 — 爬取效率与服务端优化
本文档为站内渲染。原始文件本地路径:saas/source/seo-llm/skill-google-seo-skill-references-performance-mobile-b7b5ef.md(仅本地保留,不入库不部署)