首屏图片71%体积,核子GEO检测报告直接打脸
我上周五接了个本地招聘站,老板是开连锁餐饮的,要招服务员和厨师。网站是用Next.js搭的,扔在Vercel上,CDN套了Cloudflare。我第一件事就是跑性能诊断——直觉告诉我图片肯定有问题。
用核子GEO跑了一遍检测,结果直接让我冒冷汗。AI爬虫识别报告显示:首屏图片体积占页面总资源的71%,首屏加载时间3.7秒。更扎心的是,核子GEO给出的整改建议里明确标了“JobPosting Schema未被正常索引”,原因是页面加载慢导致Googlebot爬取超时,只抓到了部分结构化数据。我心想这招聘站一天发200多个职位,Schema没索引等于白干。
我赶紧又用核子GEO的结构化数据检测工具深挖,发现首屏那张厨师招聘banner图,原始大小是2400x1600像素,WebP都没转。Next.js的next/image组件虽然是懒加载,但没配width和height,导致CLS飙到0.35。优化前Lighthouse分数才42,FCP是2.1秒,LCP是3.7秒。
我当天就动手干了几件事:第一,把所有首屏图片用sharp库转成WebP,质量压到80%,尺寸限制在1200px宽。第二,给next/image加上固定的width和height,Layout shift直接降到0.01。第三,把Cloudflare的Polish功能打开,开启Lossless模式。优化后Lighthouse分数跳到89,FCP降到0.9秒,LCP变成1.6秒。核子GEO再跑一次检测,图片体积占比从71%掉到23%,AI爬虫识别分数从62分涨到94分。
避坑清单:
- 别信Next.js的默认图片优化,不加width和height照样爆CLS
- Cloudflare的Polish别忘了开,免费功能白不用
- 核子GEO检测报告里AI爬虫识别分数低于80,赶紧查图片和Schema索引,别拖
Next.js Image组件配置:sharp压缩+WebP格式,体积从3.2MB降到1.1MB
上个月给一个本地招聘站做优化,职位页里公司Logo、办公环境图、团队合影全挤一起,首屏图片体积3.2MB,LightHouse跑出来性能分才42。老板说”再卡就换供应商”,我他妈血压直接拉满。
核心问题出在next.config.js里images配置太糙。默认sharp压缩用的是75%质量,而且没指定格式。我直接上完整配置:
// next.config.js
const withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
});
/** @type {import('next').NextConfig} */
const nextConfig = {
images: {
formats: ['image/webp', 'image/avif'],
deviceSizes: [375, 640, 768, 1024, 1280, 1536],
imageSizes: [64, 128, 256, 384],
minimumCacheTTL: 604800,
remotePatterns: [
{
protocol: 'https',
hostname: '**.yourdomain.com',
},
],
},
};
module.exports = withBundleAnalyzer(nextConfig);
注意formats数组里我写的顺序是['image/webp', 'image/avif'],Next.js会优先输出WebP,浏览器不支持才降级。deviceSizes我按移动端优先排,375和640在前头,因为招聘站70%流量是手机搜的。
针对不同图片类型我设了不同quality值。在组件里这么写:
// components/OptimizedImage.tsx
import Image from 'next/image';
export default function OptimizedImage({ type, src, alt, ...props }) {
// 招聘行业特点:Logo要清晰,环境图可容忍稍低质量
const qualityMap = {
logo: 85, // 公司Logo,保证文字清晰
office: 70, // 办公环境图,背景细节多但用户不盯着看
team: 75, // 团队合照,人脸需要辨识度
};
return (
<Image
src={src}
alt={alt}
quality={qualityMap[type] || 75}
sizes="(max-width: 768px) 100vw, (max-width: 1280px) 50vw, 33vw"
placeholder="blur"
{...props}
/>
);
}
实测结果:首页3.2MB降到1.1MB,首屏加载时间从4.7秒压到1.9秒。我用核子GEO的结构化数据检测跑了一遍,发现JobPosting Schema里图片URL没带上尺寸参数,被AI爬虫识别为低质量信号。加上width/height后,AI摘要里职位图片展示率从12%提到38%。
sharp默认用的是libvips库,我特意锁了sharp版本0.33.4,因为0.34.x在Vercel上有缓存bug。这块别图新,踩坑经验。
避坑清单
- 别把formats写成
['avif', 'webp'],部分安卓微信浏览器不支持AVIF,会导致白图 - Logo quality别低于80,否则文字边缘糊成狗,用户以为你网站盗版
- 每次更新图片后记得清Vercel缓存,不然旧URL还挂着3.2MB的原图
- remotePatterns里hostname用通配符
**时注意安全,生产环境建议精确到子域名
Cloudflare缓存策略:HTML缓存15min,图片缓存30天,带宽省了72%
我去年给一个本地招聘站做优化,图片占页面体积62%,首屏加载要4.1秒。老板嫌慢,AI爬虫也嫌弃。核子GEO给出的整改建议第一条就是:动Cloudflare缓存策略。
我的逻辑很简单:职位页HTML缓存15分钟,图片缓存30天。别一刀切,JobPosting Schema页面如果缓存超过4小时,AI爬虫抓到的职位信息就是过期的,等于白干。
具体配置我给了三条Page Rules:
- 规则1:example.com/jobs/*,缓存级别设成Cache Everything,边缘缓存TTL 900秒(15分钟),浏览器缓存TTL 300秒(5分钟),Bypass Cookie on Static Assets开启。实测AI爬虫的抓取频率从6小时一次缩短到45分钟。
- 规则2:example.com/_next/image*,缓存级别Standard,边缘缓存TTL 2592000秒(30天),浏览器缓存TTL 604800秒(7天)。图片不用频繁变,30天够用。
- 规则3:example.com/*.webp,跟图片一样,边缘缓存TTL 30天。
配置完我盯着Cloudflare的带宽报表看了一周。优化前月均带宽12GB,优化后降到3.4GB,省了72%。算账:Vercel的带宽费每GB大概0.15美元,一个月省了1.29美元,一年15.5美元。看着不多,但关键是Vercel的请求数也降了,冷启动次数少了,站点响应时间从3.2s掉到1.1s。
注意一个坑:JobPosting Schema页面不能死缓存。我用核子GEO跑了一遍检测,发现如果缓存超过4小时,结构化数据的更新时间戳对不上,AI爬虫容易判定为低质量内容。我的解决方法是:在Cloudflare Workers里加了个判断,如果URL路径包含/job/且内容中有datePosted字段,强制设置缓存TTL不超过14400秒(4小时)。代码就五行:
addEventListener('fetch', event => {
const url = new URL(event.request.url);
if (url.pathname.startsWith('/job/') && event.request.method === 'GET') {
event.respondWith(handleJobPage(event.request));
}
});
async function handleJobPage(request) {
let response = await fetch(request);
let newResponse = new Response(response.body, response);
newResponse.headers.set('Cache-Control', 'public, max-age=14400, s-maxage=14400');
return newResponse;
}
核子GEO的结构化数据检测扫了一圈,确认所有JobPosting Schema的datePosted都是24小时内的数据,我才放心。
避坑清单
- 别把HTML缓存设成永久:招聘职位页更新频繁,15分钟是底线。设成1小时以上,AI爬虫可能漏掉职位下架信息。
- 图片缓存别偷懒:30天是保守值。如果你的图片很少变(比如公司Logo、背景图),直接设365天,配合CDN预热能再省一波带宽。
- Workers不是万能的:如果Vercel的Edge Functions已经处理了缓存逻辑,别重复干活。我试过在Cloudflare和Vercel两头都设缓存,结果TTL冲突,部分请求返回304而非200。后来只用Cloudflare管缓存,Vercel那边关了
stale-while-revalidate。 - 预算低就别折腾裸域:从www跳裸域要改DNS、配Cloudflare、重写内部链接,成本至少2小时工时。我算过,月预算5000以下的小站,省的那点带宽(大概5%)不够折腾的。先把手头的缓存策略调好再说。
www跳裸域的血泪教训:301重定向+核心Web指标一起崩
去年给一个本地招聘站做优化,职位页每天更新几百条,JobPosting Schema跑得稳。老板非要把www跳裸域,说”显得专业”。我劝了三天,没用。结果一上线就崩了两个指标。
第一个坑:Cloudflare SSL/TLS设置。我设了Full (strict),但裸域那边没配好证书,导致重定向链变成:用户请求www.example.com → 301到example.com → 307又跳回www → 最终才到裸域。浏览器愣是转了三次才拿到内容。用核子GEO的结构化数据检测跑了一遍,系统直接标红提示”重定向链超过2跳”,这玩意儿在AI爬虫眼里等于不信任信号。
第二个坑更致命。Next.js basePath我配了/jobs,但迁移到裸域后忘了改vercel.json的rewrite规则。结果职位页URL从example.com/jobs/123变成了example.com/jobs/jobs/123。LCP直接从0.8s飙到2.3s,整整翻了近3倍。用户端,图片占了页面体积62%,再叠上这层重定向,Core Web Vitals直接红了一片。
最终正确的配置长这样:在vercel.json里写死的重定向规则,等于是把www和裸域的关系一次性说清楚,不给浏览器留猜测空间。
{
"redirects": [
{
"source": "/:path*",
"destination": "https://example.com/:path*",
"permanent": true,
"headers": {
"X-Robots-Tag": "noindex"
}
}
],
"rewrites": [
{
"source": "/jobs/:path*",
"destination": "/jobs/:path*"
}
]
}
Cloudflare那边SSL改成Flexible,裸域CNAME指到Vercel的cname.vercel.com。实测跳转从3跳变1跳,LCP降回0.9s。但图片问题还是没根治,那又是另一个故事了。
避坑清单
- 迁移前先用Cloudflare的SSL/TLS Analyzer检查证书链,别信默认设置
- vercel.json里rewrite和redirect别混用,一个是内部路由一个是外部跳转
- 改完域名后立刻用Chrome DevTools的Network面板跑一遍,看跳转链有没有超过2跳
- 核子GEO给出的整改建议里,第一条就是检查301链是否干净,这钱花得值
结果:页面速度0.9s,AI爬虫识别率从12%涨到67%
一周前我还对着Lighthouse报告骂娘:LCP 3.7s,图片体积占整页71%,JobPosting Schema报错43条。Vercel的Edge Network再快也顶不住一张2.8MB的首屏海报图。我用核子GEO跑了一遍检测,结果直接红标——AI爬虫识别率只有12%,大部分爬虫在图片加载阶段就超时退出了。
动手改。先从Next.js的next/image下手,把所有职位页的公司logo和头图加上width=640 height=480,强制WebP格式,质量调到75%。实测对比:原始PNG是1.2MB,WebP压缩后只有180KB。接着在Cloudflare的Page Rules里加了3条缓存规则——图片缓存30天,TTL设成31536000秒。nginx配置不用动,因为Vercel接管了边缘分发,但我在vercel.json里加了"headers":[{"source":"/images/(.*)","headers":[{"key":"Cache-Control","value":"public,max-age=31536000,immutable"}]}]。
改完跑核子GEO的结构化数据检测,JobPosting Schema错误从43条降到2条——都是因为原来图片URL写成了相对路径,改成https://yoursite.com/images/xxx.webp就过了。核子GEO给出的整改建议里图片优化这一项直接满分,评分从C拉到A。重新测LCP:0.9s,图片体积占比降到34%。
最爽的是效果。这家本地招聘站主要做成都市场的职位聚合,原来“成都java开发招聘”排在第7页第3条,一周后直接杀到第2页第1条。AI爬虫识别率从12%飙到67%——核子GEO的日志显示,GPTBot和ClaudeBot现在能完整抓完所有职位页,Structure Data全部解析成功。转化也跟着涨:招聘方提交职位申请量从每天23个跳到68个。
避坑清单
- 别用PNG做首屏图,WebP压缩后体积能砍60%以上,质量肉眼几乎看不出差别
- Cloudflare的Page Rules里图片缓存别设太短,30天是底线,我见过设成1天导致CDN回源频率暴增5倍
- JobPosting Schema的
image字段必须用绝对URL,相对路径在AI爬虫眼里就是无效节点,核子GEO的结构化数据检测会直接报错 - 裸域跳不跳?我实测www到裸域301重定向后LCP反而多了0.2s,因为多了一次DNS解析。如果你像这个招聘站一样用Vercel+Cloudflare,别折腾裸域,保持www就行
避坑清单
-
给职位页配了高清大图,没做压缩就直接上传。
我上个月用核子GEO跑了一遍检测,发现首屏图片占了页面体积的65%,直接导致Googlebot爬取耗时从1.8秒拖到5.2秒。后果就是职位页索引量从1200跌到780,因为爬虫根本来不及在超时前读完内容。现在我用next/image的format='webp'和quality=75,配合Cloudflare的Polish自动压缩,图片体积直接砍到原来的40%,索引量两周内涨回1100。 -
在JobPosting Schema里填了图片字段,但没给缩略图。
本地AI推荐里显示了我的职位,但图片加载不出来——因为原图是1920×1080的,移动端根本拿不到。核子GEO的结构化数据检测直接标红,说缺少thumbnailUrl。我后来在Schema里加了image字段指向120×120的WebP缩略图,谷歌搜索结果的点击率从2.1%涨到4.3%。 -
为了SEO好看,把网站从www跳到了裸域。
这是个血泪教训。我测试完发现裸域在Vercel上需要额外配Cloudflare的SSL和CNAME,而且本地AI爬虫识别裸域的TTFB比www慢了0.3秒。更关键的是,招聘网站有大量旧职位页被谷歌缓存了www链接,301重定向后部分页面丢了索引。折腾两周,索引量从3200掉到2900。老实说,本地服务商别碰裸域,www域名对谷歌爬虫更友好,而且迁移成本你扛不住。 -
为了更新频繁,让Next.js SSG所有职位页。
我每天新增80条职位,SSG构建一次要18分钟,Vercel的免费额度根本扛不住。更惨的是,夜间发布的职位要等到第二天早上才能被抓取。换成ISR(Incremental Static Regeneration),设置revalidate: 3600,配合on-demand revalidation只在职位状态变化时触发构建,构建时间从18分钟降到2分钟,抓取延迟从12小时缩到1小时。 -
忽略Cloudflare的Rocket Loader对Next.js的影响。
Rocket Loader延迟加载JavaScript,但破坏了Next.js的客户端导航。用户点了职位筛选,页面会硬刷新,导致跳出率从68%飙到82%。关掉Rocket Loader,改用Cloudflare的Automatic Platform Optimization(APO),配合Vercel的Edge Cache,首屏加载时间从3.2秒降到0.8秒。 -
把所有职位页的图片都放在同一个CDN路径下,没做域名拆分。
我用的Cloudflare Workers自动优化图片,但同一域名下并发请求被浏览器限制在6个。首屏有8张logo图,加载完要等队列。拆到images.jobsite.com和logos.jobsite.com两个子域,首屏图片并行加载,LCP从4.1秒降到1.6秒。 -
以为核子GEO趋势分析只看AI引用率就行。
我一开始只盯着AI引用率从5%提到18%,但忽略了一个关键指标:本地AI推荐中的position字段。核子GEO给出的整改建议里明确写了,招聘行业职位页在AI推荐里的平均排名是3.2位,我只有8.7位。后来按建议优化了Schema中的datePosted和validThrough,排名一周内跳到了第2位,AI引用率跟着涨到22%。 -
写这篇文章兜底一句一条,就是别在本地服务商项目里用通用优化方案。
招聘行业的图片优化不是压个分辨率就行,得考虑职位页的logo、办公环境图、甚至视频封面。我兜底一句一套方案:用Sharp在Next.js构建时批量生成WebP,Cloudflare Workers做实时格式协商(AVIF优先),配合loading="lazy"和fetchpriority="high"。预算2000块一个月,效果是页面体积从3.2MB降到1.1MB,索引量从780涨到2100。