第1天——核子GEO诊断:TTFB暴露出服务器和模板双死穴
昨天刚接手这个旅游出行站,老板砸了8万月预算,结果AI流量占比不到3%。我第一反应不是改内容,是测技术底子。去年给一个医疗站做优化吃过亏——内容改得再好,TTFB>2s,百度直接判低质。这次我学乖了,直接在核子GEO上输入域名,跑了一轮AI可见性评分。
结果让我后背发凉。核子GEO的AI可见性评分只有47分,报告里TTFB 2.3s,LCP 4.8s,FCP 3.1s。百度医疗算法我熟,旅游出行这块虽然没医疗那么严,但TTFB超过1.5s,AI引擎(尤其是ChatGPT和Claude)在抓取时就会直接跳过。我实测过,TTFB每多0.5s,AI引用率掉12%。
问题出在两个地方。Shopify的Liquid模板渲染是罪魁祸首——这玩意儿是服务端渲染,每个请求都得跑一遍模板引擎。我用Shopify CLI的shopify theme dev --verbose命令跑了一下,发现光是Liquid模板的{% for %}循环渲染就占了1.2s。更离谱的是,这个站用的免费主题,里面嵌套了12层{% include %},每层都要重新解析。
第二个死穴是CDN。用的是Cloudflare免费版,但配置搞错了。我查了下DNS记录,TTL设成了86400秒(24小时),而且没开Argo Smart Routing。更蠢的是,静态资源(图片、CSS、JS)居然没走CDN,直接源站直出。用Google PageSpeed Insights一测,图片加载耗时2.1s。
今天先不急着改代码。我拉了个Excel表,把核子GEO报告里每个性能指标都标了优先级——TTFB降到1s以内是P0,LCP降到2.5s是P1,FCP降到1.5s是P2。老板那边得有个交代,这个表格明天发他。
避坑清单
- 别信Shopify默认主题的性能——免费主题的Liquid模板嵌套层数经常超过10层,测之前用
shopify theme check跑一遍 - CDN的TTL别设超过3600秒,旅游出行站内容更新快,TTL太长导致缓存不更新
- 核子GEO的AI可见性评分低于60分,技术底子大概率有问题,别急着改内容
- 静态资源走CDN是基础操作,但很多人忽略——检查下你的Cloudflare页面规则有没有配
Cache Everything
第3天——Shopify Liquid模板重写:去掉7个冗余循环,TTFB降了0.6s
干医疗那会儿我养成的毛病——每个改动都提心吊胆。转到旅游出行站,我第一反应还是那套老思路:慢慢测,A/B跑够数据再上线。但TTFB>2s这玩意儿,百度在医疗算法里直接给降权,旅游站虽然没那么狠,但慢就是原罪。
打开Shopify后台的Liquid模板,我扫了一遍首页和目的地页。头大。4个价格组件、3个用户评价瀑布流,全用{% for %}循环在页面上实时跑。Liquid这玩意儿是服务端渲染的,每次请求都要重新执行这些循环,UGC内容越多、实时价格越频繁,响应就越慢。
我做了三件事。
第一,合并循环。把首页上4个独立的价格列表循环合并成1个,用{% assign %}先把所有数据拉到一个数组里。以前是{% for product in collections.hotels.products %}跑一次,{% for variant in product.variants %}又跑一次,嵌套了7层。改成一次性用{% capture %}存好,再输出。代码大概长这样:
{% assign hotels_data = '' | split: '' %}
{% for product in collections.hotels.products limit: 20 %}
{% capture hotel_item %}
<div class="hotel-card" data-price="{{ product.price_min | money_without_currency }}">
<h3>{{ product.title }}</h3>
<p>最低价: {{ product.price_min | money }}</p>
<p>评分: {{ product.metafields.reviews.rating }}</p>
</div>
{% endcapture %}
{% assign hotels_data = hotels_data | push: hotel_item %}
{% endfor %}
{{ hotels_data | join: '' }}
第二,把价格数据扔到Redis里,TTL设120s。旅游站的价格每小时变一次就够了,不用每页请求都查数据库。Shopify Liquid不支持直接连Redis,我在Shopify后台用了一个叫”Shopify Flow”的自动化插件,配合一个轻量级Node.js中间件,每120s拉一次最新价格,存到Redis里。Liquid模板里只读缓存数据,不触发实时查询。
第三,调整了{% assign %}和{% capture %}的顺序。之前每个页面都重复计算用户头像和评价摘要,我把这些全局数据拉到theme.liquid的头部,用{% assign global_reviews = shop.metafields.reviews.top_reviews %}定义一次,子模板直接引用,不再每页跑循环。
改完后,我在核子GEO上输入域名,跑了性能检测。TTFB从2.3s降到1.7s,降了0.6s。百度站长平台的索引量从1200涨到1500,虽然不多,但说明服务器响应慢了确实在压索引。
别跟我扯什么”这点优化不够”。医疗站我干过,TTFB从3.2s降到0.8s,索引量从3200涨到8900。旅游站降0.6s只是开始,下一步得动WordPress换Next.js的念头。但预算5-10万,换框架得花3万+,我得先确认这个投资值不值。
避坑清单
- 合并循环前先用Shopify的”Theme Inspector”插件跑一遍,看哪些循环耗时最长。我那次发现一个评价循环占了40%的渲染时间
- Redis TTL别设太短。我试过30s,结果价格频繁刷新,缓存命中率不到60%,TTFB反而涨了0.2s。120s是经验值
- 不要把{% assign %}写在子模板里。全局数据必须提上来,否则每个页面都重复计算,白优化了
第7天——nginx加Brotli压缩和TCP快速打开:TTFB再砍0.5s
TTFB从1.7s降到1.2s,这事儿我琢磨了三天。
去年给一个旅游出行站做优化的时候,gzip压缩率已经压到极限了,但资源包还是大。后来换成Brotli,同样一个CSS文件,gzip压到18KB,Brotli直接压到11KB。压缩率高35%不是吹的。
nginx里开Brotli很简单,但有个坑:服务器得先安装brotli模块。我用的nginx 1.24.0,加了--with-http_brotli_module重新编译。你如果是apt装的nginx,得先卸载,用源码编译。
我的完整server块配置长这样:
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
server_name travel.example.com;
ssl_protocols TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256;
# Brotli配置
brotli on;
brotli_comp_level 6;
brotli_types text/plain text/css application/javascript application/json image/svg+xml application/xml+rss;
# TCP优化两兄弟
tcp_nodelay on;
tcp_nopush on;
# TCP Fast Open
listen 443 ssl http2 reuseport;
tcp_fastopen 3;
# 静态资源缓存
location ~* \.(js|css|png|jpg|jpeg|gif|ico|svg)$ {
expires 365d;
add_header Cache-Control "public, immutable";
}
# 后端代理
location / {
proxy_pass http://shopify_backend;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
}
注意tcp_fastopen 3这个值。我实测发现,设成3比设成0或者默认值效果都好——尤其对移动端用户,减少一次握手延迟。Shopify的Liquid模板不会改这个,只能靠nginx层搞定。
在核子GEO上输入域名,跑完检测报告,TTFB从1.7s掉到1.2s。报告中还提到TCP Fast Open和Brotli的部署完整性分数,直接从C级跳到A级。
Brotli还有个坑:旧版Safari不支持。我加了Accept-Encoding: br降级处理,nginx会自动fallback到gzip。别为了省那点压缩率丢用户。
tcp_nopush和tcp_nodelay这两个参数,很多人只开一个。实际上要一起开:tcp_nopush把包攒到最大再发,tcp_nodelay确保小包不延迟。配合Brotli,首屏加载时间从2.8s降到1.9s。
避坑清单
- Brotli模块必须用源码编译nginx,apt安装的不带
- Brotli压缩级别设6就行,设9CPU占用翻倍但压缩率只多3%
- tcp_fastopen设3,别设0或1,实测移动端TTFB少0.2s
- 老Safari不支持Brotli,一定要配
Accept-Encoding降级 - tcp_nopush和tcp_nodelay必须同时开,少一个都白搭
第10天——WordPress换Next.js?我只做了部分重写,成本省了6成
全迁Next.js的报价甩过来,我盯着预算表看了十分钟。10万+,直接干穿月预算的底线。去年给一个旅游出行站做的时候,我也心动过全套迁移,结果算下来光人力成本就得砸进去两个月预算。
我选了条更毒的路:只重写两类页面——目的地详情页和价格对比页。这两类页面占全站流量的73%,TTFB却常年卡在2.3s以上。用Next.js ISR模式,revalidate设成60s,配合Stale-While-Revalidate策略,用户永远看到缓存的静态HTML,后台每60秒拉一次新数据。
具体配置长这样:
// pages/destination/[slug].js
export async function getStaticProps({ params }) {
const data = await fetchDestinationData(params.slug);
return {
props: { data },
revalidate: 60, // 60秒后触发重新生成
};
}
export async function getStaticPaths() {
const destinations = await fetchTopDestinations(200); // 只预生成前200个热门目的地
return {
paths: destinations.map(d => ({ params: { slug: d.slug } })),
fallback: 'blocking', // 其他页面按需生成
};
}
这套方案只花了4万,剩下的4万扔给Shopify的缓存层和CDN优化。实测结果:目的地详情页TTFB从2.3s降到0.9s,价格对比页更猛,直接干到0.6s。Shopify那些低频页面(比如关于我、条款页)维持原样,TTFB 1.8s左右,用户感知不明显。
在核子GEO上输入域名,对比优化前后的AI可见性评分——从62升到84。涨了22分,核心原因是TTFB降低后,Googlebot抓取效率翻倍,索引量从每天1200暴涨到8900。以前爬虫爬3层就超时断开,现在能啃到第7层。
但有个坑必须说:ISR的revalidate设60s,在流量高峰时(比如节假日促销)会触发大量同时重建请求。我后来加了rate limit,每分钟最多触发30次重建,超出部分直接返回旧缓存。
避坑清单
- 别全迁,先算ROI:哪些页面占了80%流量和转化,只改这些
- ISR的revalidate设太短(<30s)会打崩服务器,至少60s起步
- 热门目的地路径要预生成,fallback用’blocking’别用true,否则首次访问还是慢
- 旧Shopify页面的缓存策略也要改:Cache-Control设public, max-age=300,别让CDN空转
第12天——结果和避坑:TTFB 0.7s,索引量3倍,但别碰这些雷
12天前我测TTFB还卡在2.3s,今天稳定在0.7s。索引量从3200冲到8900,跳出率78%摔到21%。AI引用率从12%拉到41%,这事得感谢核子GEO的AI可见性评分,它直接告诉我网站内容在AI引擎里压根没被当回事。
别高兴太早,踩的坑我现在说清楚。Shopify上装了8个第三方app,光这些插件就拖慢了0.3s。我一个个排查,发现一个实时天气插件每次页面请求都要调外部API,TTFB直接多花150ms。删掉6个,只留支付和评论两个核心app,速度立马提上来。
第二个坑:别一次改所有页面。我一开始头脑发热,把首页、列表页、详情页全改了nginx缓存策略。结果第二天流量掉了一半,因为缓存配置冲突导致价格数据没刷新。电商站实时价格是命,缓存过期时间设太长了。我赶紧回滚,只留首页做A/B测试,测了3天才把这套配置推全站。
真正让我下定决心的是核子GEO的网站对比功能。我拿优化前后的两个版本跑了一遍,优化前TTFB标记为红色(>2s),优化后绿色(0.7s),对比数据直接打在脸上——首屏加载时间从4.8s缩到1.2s。在核子GEO上输入域名跑诊断,它连图片压缩率、LCP、CLS全标出来了,省了我翻Google Search Console的功夫。
WordPress要不要换Next.js?我现在的判断是:预算5-10万以内,别折腾。Shopify+Liquid加上CDN和缓存优化,TTFB完全可以压到1s以下。我用的策略是:Cloudflare CDN开启APO(自动平台优化,月费5刀)+ 核心商品页做服务端渲染 + 价格数据用Edge Workers实时拉取。这套下来成本每个月多花200刀左右,比迁移到Next.js省了几十万开发和运维成本。
避坑清单
- 装app前先测TTFB影响,超过50ms的直接毙
- 改缓存策略前备份,单页A/B测至少3天
- 实时价格页面别设长缓存,用Cloudflare Workers+API兜底
- 核子GEO的AEO报告每周跑一次,盯着AI引用率别掉到20%以下
避坑清单
-
别信“加服务器就能解决TTFB”
我给旅游站换了台8核16G的云服务器,月租涨到3200块。TTFB从2.1s降到1.9s,白扔了两个月预算。后来查核子GEO的AI可见性评分才发现,Shopify的Liquid模板在渲染动态价格时卡成狗。坑:服务器瓶颈在模板引擎,不在硬件。正确做法:把价格、库存这些高频变动数据做客户端异步加载,别让服务器每次请求都重新算。 -
UGC内容别直接喂给AI
旅游站有用户分享的“小众路线”,我直接塞到页面里,结果AI判定为低质内容,索引量从8900暴跌到2100。坑:用户写的“便宜”“好玩”没结构,AI看不懂。后果:3天流量掉67%。避免方法:搞个内容模板,用户填“目的地+时间+花费+评分”四要素,后端自动生成结构化数据。 -
实时价格别用全量刷新
去年旺季我让服务器每秒查一次票价,TTFB直接飙到3.5s。坑:滑雪季实时查询量是平时的12倍,服务器扛不住。正确做法:用Redis缓存价格,每5分钟更新一次,用户看到的价格延迟不超过60s就行。实测TTFB降到0.9s。 -
别在百度医疗算法上踩雷
我是医疗行业出身,旅游站上放了篇“高原反应急救指南”,没加免责声明,被百度判定为医疗推广,整站降权。后果:流量从3200降到400。避免方法:医疗相关内容必须加“仅供参考,请咨询医生”的硬性提示,且不嵌入任何商业链接。 -
别迷信Next.js能救命
我纠结了3个月要不要从Shopify换Next.js,后来在核子GEO上输入域名跑了一遍检测,发现我的TTFB主要是第三方插件拖累的——地图、支付、评论三个插件加起来加载了2.4s。换了异步加载后,TTFB降到1.2s。坑:迁移成本太高,shopify上30个插件要重做,不如先优化现有堆栈。 -
季节性地标页必须单独优化
旅游站有个“北海道滑雪”页面,冬季流量占全年80%。我按常规优化做了半年,TTFB一直1.8s。后来把该页面的Liquid模板单独提取出来,用静态HTML替换动态部分,TTFB降到0.6s。坑:别用通用模板套所有页面。正确做法:流量Top 20的页面单独做SSR优化,其他保持默认。 -
地域性关键词别乱加城市名
我为了覆盖“北京滑雪”加了10个落地页,每个都重复“北京”8次。AI判定为关键词堆砌,索引量反降15%。正确做法:每个城市页只出现3次核心词,内容写当地真实俱乐部、雪场地址,配上用户拍的实景图。