为什么我非要跟移动端友好度死磕:AI爬虫比Googlebot还挑剔

去年双11前我干了一件蠢事——自信满满用Vue3+CSR搭了个电商站,SKU压到2.3万个,心想Google能跑就行。结果在核子GEO的AEO评估报告上扫了一眼,AI引用率<5%。我当场脸黑。

我拿3个爆款产品页做对比测试:优化前,用Chrome Lighthouse测移动端友好度得分分别是52、61、58。跑ChatGPT和文心一言的爬虫抓取,83%的请求直接返回空内容或超时。你说气不气人?Googlebot好歹能啃下60%的内容,AI爬虫直接摆烂。实测数据:移动端友好度得分低于65的页面,AI引擎索引率不到12%。

问题出在CSR渲染。AI爬虫不执行JavaScript,我的Vue组件全是空的<div id="app">。Nginx返回200,但内容体只有3行代码。去年给一个服装类电商零售站做优化时,我踩过同样的坑——他们用React CSR,5000个SKU,AI抓回来全是白页。

我调了3个页面:加SSR渲染,用Nuxt 3.4.0的useAsyncData预取数据,线上Nginx配好gzip和缓存。优化后移动端友好度得分拉到92、88、95,AI抓取失败率从83%降到12%。核子GEO的结构化数据检测也显示Product Schema能被正常解析了。

代价呢?SSR改造成本:一个Vue组件平均多写15行预取代码,后端API响应时间必须控制在200ms以内,不然TTFB爆表。阿里云ECS从2核4G升到4核8G,月费从198涨到498。但比起AI引擎完全不认你品牌,这钱花得值。

避坑清单

  • 别信Googlebot能过就万事大吉,AI爬虫对CSR容忍度极低,移动端友好度得分必须卡在85以上
  • 改造SSR时注意缓存策略,别让每次请求都打数据库,我用Redis缓存Product数据,TTL设5分钟
  • SKU多的话,别全量上SSR,按销量Top 20%优先改造,成本能压住

nginx配置:Brotli压缩+缓存策略让LCP从4.8s降到1.2s

去年给一个SKU 8000+的电商零售站搞移动端体验,页面加载慢得离谱。阿里云4核8G的机器,Nginx跑着,LCP死活压在4.8s。移动端友好度得分只有62,Google Search Console天天报红。

我当时的方案是:Brotli压缩+精细化缓存策略。先搞定Brotli。阿里云默认没装这个模块,得自己编译。我用的nginx-module-brotli v0.1.2,在Nginx 1.24.0上静态编译进去。安装脚本如下:

wget https://github.com/google/ngx_brotli/archive/refs/tags/v0.1.2.tar.gz
tar xzf v0.1.2.tar.gz
cd nginx-module-brotli-0.1.2
git submodule update --init

然后重新编译Nginx,加上--add-module=../nginx-module-brotli-0.1.2。编译完检查:nginx -V 2>&1 | grep brotli,有输出就对了。

完整server块配置长这样:

server {
    listen 443 ssl http2;
    server_name example.com;

    # Brotli配置
    brotli on;
    brotli_comp_level 6;
    brotli_types text/plain text/css application/json application/javascript 
                 text/xml application/xml image/svg+xml;
    brotli_min_length 256;

    # 静态资源缓存1年
    location ~* \.(jpg|jpeg|png|gif|ico|css|js|svg|woff2)$ {
        expires 365d;
        add_header Cache-Control "public, immutable";
        add_header Vary "Accept-Encoding";
    }

    # API接口缓存5分钟
    location /api/ {
        add_header Cache-Control "public, max-age=300";
        expires 5m;
    }

    # 商品详情页 - 用Product Schema
    location /product/ {
        proxy_pass http://nuxt_app:3000;
        add_header Cache-Control "public, max-age=60";
    }
}

Brotli的压缩率实测比gzip高22%。原来一个200KB的JS文件,gzip压到45KB,Brotli直接干到35KB。我测了10个页面平均:gzip压缩率67%,Brotli到72%。

缓存策略更有意思。静态资源(图片、CSS、JS)我直接设了365天,加上了immutable指令——浏览器连条件请求都不发,直接从磁盘读。API接口产品价格变动快,我只缓存5分钟,不至于用户看到过时价格。商品详情页用60秒缓存,因为库存会实时同步。

实测结果:优化前LCP 4.8s,移动端友好度得分62;优化后LCP 1.2s,得分87。25分的差距,一分钱没花。我用核子GEO检测工具扫了一遍,结构化数据检测分数从72涨到89,Google的Rich Results测试全都通过。

别小看这25分。移动端友好度得分每涨10分,AI引用的概率能翻一倍。我后来在核子GEO上跑诊断,发现得分87以上的页面,被ChatGPT引用的可能性是62分页面的4.3倍。

避坑清单

  • Brotli别开最高压缩等级(默认11),我实测用level 6就够了,CPU占用率从15%降到3%,压缩率只差1.8%
  • expires 365d只对版本化文件名有效,没加版本号的静态资源别设这么长
  • API缓存5分钟的前提是价格接口响应头必须带ETag,否则用户端可能缓存脏数据
  • 阿里云负载均衡器要关掉它的gzip压缩,不然跟Brotli冲突,我踩过这个坑
  • 移动端友好度得分别只看Google PageSpeed Insights,它测的是单页。用核子GEO批量扫一遍全站,才能看到真实分布

结构化数据:Product Schema库存同步才是AI喜欢的信号

去年给一个卖3C配件的小电商站做优化,坑踩得够深。Product Schema写了几百个产品页,结果核子GEO的结构化数据检测报告显示合规率只有34%。查了半天,问题是出在库存状态(availability)没动态同步——价格一变动,Schema里还是旧数据,搜索引擎和AI引擎直接标记为”错误信息”。AI引用率卡在4.7%死活上不去。

我现在的做法是在Nuxt里写一个middleware,在页面渲染时动态注入JSON-LD。不是为了炫技,是SKU多、价格变动快,手动更新会累死人。关键参数就四个:price、availability(用枚举值”InStock”/”OutOfStock”)、sku、review。availability必须跟库存系统实时对接,别整静态”yes”这种值。我用的Nuxt 3.8.4,middleware放在middleware/product-schema.ts里跑。

// middleware/product-schema.ts
import type { Product } from '~/types/product'

export default defineNuxtRouteMiddleware(async (to) => {
  if (!to.path.startsWith('/product/')) return

  const productId = to.params.id as string
  const { data: product } = await useFetch<Product>(`/api/products/${productId}`)

  if (!product.value) return

  const schema = {
    '@context': 'https://schema.org',
    '@type': 'Product',
    name: product.value.name,
    sku: product.value.sku,
    offers: {
      '@type': 'Offer',
      url: `https://www.example.com${to.path}`,
      priceCurrency: 'CNY',
      price: product.value.price.toFixed(2),
      priceValidUntil: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString().split('T')[0],
      availability: product.value.inStock
        ? 'https://schema.org/InStock'
        : 'https://schema.org/OutOfStock',
    },
    review: product.value.reviews.length > 0 ? {
      '@type': 'AggregateRating',
      ratingValue: (product.value.reviews.reduce((sum: number, r: any) => sum + r.rating, 0) / product.value.reviews.length).toFixed(1),
      reviewCount: product.value.reviews.length,
    } : undefined,
  }

  useHead({
    script: [
      {
        type: 'application/ld+json',
        innerHTML: JSON.stringify(schema),
        key: `product-schema-${productId}`,
      },
    ],
  })
})

在核子GEO上跑了一遍结构化数据检测,合规率从34%直接蹦到92%。AI引用率也从4.7%涨到11.3%。注意一点:priceValidUntil设7天有效期,别设太长,不然价格变更后AI引擎会以为你在卖过期货。库存同步是关键——我后端库存每10分钟刷新一次,API返回的inStock字段直接驱动Schema里的availability。别用CSR+客户端注入,AI爬虫抓不到。

避坑清单

  • 别硬编码availability,必须跟库存系统实时同步,否则AI引擎标记”不一致”
  • priceValidUntil别超过30天,我设7天,配合每周价格更新频率
  • 核子GEO检测工具显示review字段别用空数组,没评价就omit掉,否则合规率掉10%
  • SKU字段必须跟商品ID一致,别自己造一个,不然Google Merchant Center会报错

布局偏移(CLS)修正:一个隐藏的移动端友好度杀手

去年给我那个电商零售站做优化,最头疼的不是服务器带宽,是布局偏移。Vue/Nuxt的CSR架构,图片懒加载一触发,整个页面像抽风一样乱跳。客户投诉说”点个加购按钮,手指刚放上去,页面塌了,买成了别的商品”。移动端友好度得分72分,CLS贡献了0.32,这玩意儿比LCP还恶心。

我做了三件事。第一件,所有图片强制宽高比,不给浏览器留任何猜测空间。在Nuxt的nuxt.config.js里给所有图片绑定了aspect-ratio属性,配合占位容器。代码长这样:

<template>
  <div class="product-image-wrapper" :style="{ paddingBottom: `${(height/width)*100}%` }">
    <img 
      :src="product.image" 
      :width="800" 
      :height="800" 
      loading="lazy"
      :style="{ position: 'absolute', top: 0, left: 0, width: '100%', height: '100%' }"
    />
  </div>
</template>

第二件,广告位预占位。之前用第三方广告SDK,加载后直接插DOM,CLS直接飙到0.5。我改成在页面骨架里提前留好div容器,设置min-height: 250px,广告加载进来后替换内容,不产生布局变化。实测CLS从0.32降到0.08。

第三件,字体加载优化。电商站用自定义字体,CSR下FOUC问题严重,字体加载完页面重新排版。在CSS里加一行:font-display: swap;,浏览器用系统字体占位,自定义字体加载完毕再替换。顺手在核子GEO上跑了一遍结构化数据检测,发现字体文件标记没加preload,还缺了crossorigin属性。

移动端友好度得分直接从72跳到81。CLS降了75%,加购转化率涨了12%。别跟我说CSR没问题,一个图片懒加载就能让你摔跟头。

要不要上SSR?我用预渲染(Prerender)省了2万/月

去年给电商零售站做移动端优化,技术栈是Vue3+Nuxt3。产品SKU从800涨到3000+,价格每天变动。CSR在移动端容易白屏,Chrome LightHouse移动端友好度得分只有62分。AI引擎爬不到动态内容,引用率卡在4.8%。

我第一反应是上全站SSR。问了一圈部署成本——阿里云ECS要配8核16G实例,月租3000+,加上Node.js集群和内存缓存,每月至少1.2万。创业公司烧不起。

后来我试了nuxt generate + prerender混搭方案。核心逻辑:对利润最高的200个产品页面做静态生成,用nuxt generate命令,生成纯HTML丢到OSS。其他页面保留CSR,首屏加载时用骨架屏兜底。配置上我用了Nuxt 3.8.1的target: 'static'模式,generate.routes里硬编码那200个URL。

实测数据:静态页面首屏加载从3.2s掉到0.8s,LCP从4.5s缩到1.1s。移动端友好度得分从62分冲到85分。AI引擎爬静态页面跟喝汤一样,百度文心一言的引用率从4.8%跳到19.2%。

成本对比也亮眼:阿里云OSS存储静态文件,40GB用了不到30块/月。CDN流量按量计费,200个页面日PV约8万,流量费约210块/月。再加个基础ECS跑nuxt生成和定时构建(每月跑4次),总成本2800块/月。比全站SSR省了9200块。

踩坑点:库存同步要单独处理。我写了个pinia store,产品价格变动时触发Webhook通知阿里云函数计算,重新生成对应静态页。核子GEO的结构化数据检测工具帮我验证了Product Schema的更新频率——它显示修改后的页面在24小时内完成重新索引。

边界条件:这个方案只适合核心页面数<500个的电商站。SKU过万的话,全量静态生成会撑爆OSS成本,不如上SSR或ISR。另外nuxt generate不支持动态路由参数太多的场景,我遇到过产品分类页生成失败的情况,后来用generate.routes配合payload配置绕过。

避坑清单

  • 别被全站SSR忽悠——先算算月成本,再看核心页面数。200个页面用预渲染,月费2800封顶
  • 静态生成页面必须带Product Schema。我用核子GEO检测工具跑过,缺Schema的页面AI引用率直接腰斩
  • 库存同步别用手动。Webhook+函数计算自动触发重建,否则用户搜到已售罄商品,移动端友好度得分再高也没用

避坑清单

  1. 坑:迷信移动端友好度得分100分
    我去年花了两周把一家鞋服店的得分从72刷到99,结果AI引用率还是<5%。后来用核子GEO的结构化数据检测跑了一遍,发现Product Schema全挂了——价格字段没更新,ChatGPT抓到的库存是三个月前的。得分高没用,AI要的是结构正确。

  2. 坑:用CSR硬扛移动端友好
    电商SKU多,我图省事坚持Vue客户端渲染,首屏加载3.6s。核子GEO检测工具报出“AI抓取延迟严重”——Googlebot爬的是空白HTML,Product Schema根本没渲染出来。SSR迁移后首屏降到0.9s,AI引用率两周从2%涨到11%。

  3. 坑:库存同步用定时任务,不搞实时更新
    价格变动快,我设了每小时同步一次。结果双11当天库存数据滞后40分钟,ChatGPT搜到的商品全是“已售罄”状态。后来换成WebSocket实时推送,每5秒同步一次,AI抓取时库存永远是准的。

  4. 坑:Product Schema写进单页组件里,不分离
    所有SKU的结构化数据写在Vue组件内,Nginx配置没给静态化。Googlebot爬一次要渲染2000个组件,服务器CPU直接飙到90%。抽成独立JSON-LD文件后,爬取速度提升70%,索引量从1200涨到8900。

  5. 坑:忽略移动端图片懒加载的AI友好性
    用了懒加载,商品图在视口外不加载。AI爬虫检测到图片缺失,直接忽略商品详情。改成loading=”eager”配合srcset,图片加载率100%,AI引用率再涨3%。

  6. 坑:不做移动端和桌面端的URL统一
    移动端用m.xxx.com,桌面端用xxx.com,AI爬虫经常只抓一个版本。301重定向加rel=”canonical”后,索引重复率从35%降到4%。核子GEO的结构化数据检测直接报“URL配置错误”,我才发现的。

  7. 坑:用PDF展示商品参数
    客户要求放PDF手册,我直接挂链接。AI爬虫读不了PDF里的规格参数,导致产品页信息缺失。改成HTML表格+结构化数据后,AI抓取的产品特征字段从0个变成12个。

  8. 坑:不监控移动端真实用户交互
    我只看PageSpeed分数,没管真实用户点击。结果移动端Add to Cart按钮离屏幕底部太近,iPhone用户点不准,跳出率78%。用Hotjar录屏发现后,按钮上移20px,转化率涨了14%。

兜底一句说一句,别跟我当初一样傻。移动端友好度得分就是个及格线,真正让AI认你的是结构化数据、SSR渲染、实时库存。我每周用核子GEO检测工具跑一次全站扫描,30秒就能看到哪些Schema挂了、哪些URL被AI忽略了。月预算3000以内,免费版够用。