[{"data":1,"prerenderedAt":314},["ShallowReactive",2],{"blog-cdn-cache-crawl":3,"blog-prev-cdn-cache-crawl":117,"blog-next-cdn-cache-crawl":208},{"id":4,"title":5,"author":6,"body":7,"canonical":101,"category":102,"cover":101,"date":103,"description":104,"draft":105,"extension":106,"keywords":101,"meta":107,"navigation":108,"noindex":105,"ogImage":101,"path":109,"seo":110,"seoDescription":101,"seoTitle":101,"stem":111,"tags":112,"updated":101,"__hash__":116},"blog\u002Fblog\u002Fcdn-cache-crawl.md","CDN 缓存配错，改版后蜘蛛三天没看到新内容","元析智能",{"type":8,"value":9,"toc":90},"minimark",[10,14,18,21,24,27,30,33,36,39,42,45,48,51,54,57,60,63,66,69,72,75,78,81,84,87],[11,12,13],"p",{},"一次改版上线三天，搜索引擎抓到的还是旧页面，原因是 CDN 缓存把 HTML 缓存了 7 天。缓存和抓取的关系，很多技术团队没意识到。",[15,16,17],"h2",{"id":17},"那次事故",[11,19,20],{},"2026 年 3 月，一个客户的官网改版，产品页 URL 和结构都变了，301 也配好了。上线三天，Google 和百度抓到的还是旧页面，新页面的收录为零。",[11,22,23],{},"查日志发现，蜘蛛请求的返回内容来自 CDN 缓存，缓存 key 没带版本号，HTML 的缓存时间被设成了 7 天。",[11,25,26],{},"我们把 HTML 的缓存策略改成\"短缓存 + 主动刷新\"，重新推送 CDN，第二天蜘蛛就抓到了新页面。但已经浪费了三天，加上恢复，排名掉了两周。",[15,28,29],{"id":29},"缓存和抓取的关系",[11,31,32],{},"搜索引擎抓的是 CDN 返回的内容，不是你源站的内容。CDN 缓存错，它看到的就是旧版本。",[11,34,35],{},"更麻烦的是缓存不一致：不同节点缓存的内容不同，蜘蛛今天抓到一个版本、明天抓到另一个版本，会被判定为页面不稳定。",[15,37,38],{"id":38},"三个配置原则",[11,40,41],{},"第一，HTML 不做长缓存。HTML 用短缓存（比如 5 分钟）或者协商缓存，图片、JS、CSS 这些带哈希的静态资源可以长缓存。",[11,43,44],{},"第二，缓存 key 带上版本。改版时版本号变，缓存自然失效，不用手动刷。",[11,46,47],{},"第三，按 UA 区分缓存要谨慎。有些站按设备做不同页面，缓存 key 里必须带 UA 维度，否则手机用户拿到桌面版。",[15,49,50],{"id":50},"怎么验证",[11,52,53],{},"改版或发布后，做三件事：",[11,55,56],{},"用 curl 请求目标 URL，看返回头里的缓存状态（HIT\u002FMISS）、缓存时间、以及内容是不是新的。",[11,58,59],{},"用搜索引擎的抓取工具（GSC 的 URL 检查、百度的抓取诊断）抓一次，看拿到的 HTML 是不是新版本。",[11,61,62],{},"在不同地区、不同网络下各请求一次，确认缓存一致。我们一般抽 3 个城市。",[15,64,65],{"id":65},"另外两个坑",[11,67,68],{},"第一个，CDN 默认缓存 HTML。很多云厂商的默认规则是\"静态资源缓存、HTML 不缓存\"，但也有些套餐默认缓存所有内容。上线前一定确认。",[11,70,71],{},"第二个，回源 HOST 配错。CDN 回源到错误的域名，拿到的是默认站点或者 404，蜘蛛看到的就是空页面。这个错误很隐蔽，查日志能看到大量 404 但源站正常。",[15,73,74],{"id":74},"一个流程建议",[11,76,77],{},"我们把\"CDN 缓存检查\"加进了上线清单：改版、迁移、大版本发布，发布后 10 分钟内必查。",[11,79,80],{},"检查项就三条：HTML 缓存时间、缓存 key 是否带版本、蜘蛛抓到的内容是否是新版本。",[15,82,83],{"id":83},"判断",[11,85,86],{},"CDN 是技术 SEO 里最容易被忽略的一层，因为它不在代码里，在基础设施里。开发不管、运维不懂 SEO，出了问题两边都查不到。",[11,88,89],{},"改版前把缓存策略定好，比改版后救火便宜得多。",{"title":91,"searchDepth":92,"depth":92,"links":93},"",2,[94,95,96,97,98,99,100],{"id":17,"depth":92,"text":17},{"id":29,"depth":92,"text":29},{"id":38,"depth":92,"text":38},{"id":50,"depth":92,"text":50},{"id":65,"depth":92,"text":65},{"id":74,"depth":92,"text":74},{"id":83,"depth":92,"text":83},null,"技术SEO","2026-08-20","一次改版上线三天，搜索引擎抓到的还是旧页面，原因是 CDN 缓存把 HTML 缓存了 7 天。缓存和抓取的关系、三个配置原则、怎么验证都在这篇，附我们踩过的两次坑。这层不出问题则已，出问题就是全站级别的，别等出事再查。",false,"md",{},true,"\u002Fblog\u002Fcdn-cache-crawl",{"title":5,"description":104},"blog\u002Fcdn-cache-crawl",[113,114,115],"CDN","缓存","抓取","ZyS6fM8EZ9kMvRp4SEEoxnE60e0MoaQYCVWPRnfVehQ",{"id":118,"title":119,"author":6,"body":120,"canonical":101,"category":102,"cover":101,"date":197,"description":198,"draft":105,"extension":106,"keywords":101,"meta":199,"navigation":108,"noindex":105,"ogImage":101,"path":200,"seo":201,"seoDescription":101,"seoTitle":101,"stem":202,"tags":203,"updated":101,"__hash__":207},"blog\u002Fblog\u002Fcanonical-on-parameter-pages.md","带参数的页面 canonical 怎么写，三种场景",{"type":8,"value":121,"toc":188},[122,125,129,132,135,139,151,154,158,161,164,167,170,173,176,179,182,185],[11,123,124],{},"参数页 canonical 的判断标准只有一条：这个带参数的地址，能不能独立回答一个搜索问题。能，就指向自己；不能，就指向无参数的规范页。",[15,126,128],{"id":127},"场景一筛选参数","场景一：筛选参数",[11,130,131],{},"如果某个筛选组合有稳定的搜索需求，比如\"支持私有化部署的 CRM\"，最好做成静态路径页，别让参数页参与排名。没有独立需求的组合，canonical 指向无参数的列表页。",[11,133,134],{},"这里有个常见错误：把所有筛选页都 canonical 到首页。2026 年 6 月一个 API 目录站就这么干，5 万个参数页的 canonical 全部指向首页，结果蜘蛛把首页当成所有页的规范版本，参数页整批掉出索引，首页也承担了不该有的主题。",[15,136,138],{"id":137},"场景二排序参数","场景二：排序参数",[11,140,141,142,146,147,150],{},"排序不改变内容的集合，只改变顺序。canonical 指向无排序的默认页，",[143,144,145],"code",{},"?sort=price"," 和 ",[143,148,149],{},"?sort=new"," 都指向默认列表。用户和蜘蛛都能正常访问，只是不单独收录。",[11,152,153],{},"如果排序页有独立价值——比如\"最新发布\"本身是一个栏目——那就不要参数，做成独立路径。",[15,155,157],{"id":156},"场景三追踪参数","场景三：追踪参数",[11,159,160],{},"utm、gclid、ref 这类参数，优先级从高到低是：链接生成时别加 > 服务器 302 清洗 > canonical 指向干净地址。canonical 是最后一道兜底，不是方案。只靠 canonical，蜘蛛每次还是会抓一遍带参数的地址，浪费的抓取预算不会回来。",[15,162,163],{"id":163},"怎么验证写对了",[11,165,166],{},"Screaming Frog 导出所有带参数的 URL 和它们的 canonical，逐条看指向：指向首页的、指向 404 的、指向自己的分别是哪些。GSC 看\"Google 选择的规范网页与用户指定的不同\"这一项，数量大说明你的声明和 Google 的判断不一致。日志里看参数 URL 的抓取量有没有下降。",[15,168,169],{"id":169},"我们在模板里怎么写",[11,171,172],{},"给前端一个判断函数，输入当前 URL 和参数白名单，输出 canonical。有白名单里的参数就保留，其余全部剥掉。这个函数放在服务端渲染层，别放在浏览器里执行——蜘蛛拿到的初始 HTML 里必须已经有正确的 canonical，靠 JS 改的不算数。",[11,174,175],{},"我们给客户交付时会附一份参数清单：哪些参数允许进 URL、哪些必须清洗、哪些保留但不索引。开发照着实现，比口头说\"参数要处理一下\"有效得多。",[15,177,178],{"id":178},"一个补充",[11,180,181],{},"分页参数别和筛选参数混在一起处理。分页页 canonical 指向自己，筛选页 canonical 指向无筛选版本，两套规则分开写，模板里也要分开实现。",[15,183,184],{"id":184},"立场",[11,186,187],{},"能静态化的页面就别用参数，参数页的 canonical 是兜底不是方案。一个站如果靠 canonical 治理参数，说明前端和产品还没把 URL 设计当回事。",{"title":91,"searchDepth":92,"depth":92,"links":189},[190,191,192,193,194,195,196],{"id":127,"depth":92,"text":128},{"id":137,"depth":92,"text":138},{"id":156,"depth":92,"text":157},{"id":163,"depth":92,"text":163},{"id":169,"depth":92,"text":169},{"id":178,"depth":92,"text":178},{"id":184,"depth":92,"text":184},"2026-08-19","参数页的 canonical 是最容易写错的一类。筛选、排序、追踪三种参数，写法完全不同。这篇给每种的正确配置、一个 2026 年 6 月的案例，以及写错之后怎么排查。",{},"\u002Fblog\u002Fcanonical-on-parameter-pages",{"title":119,"description":198},"blog\u002Fcanonical-on-parameter-pages",[204,205,206],"canonical","URL参数","重复内容","ZwaXEfJw-NfJuS8ygaY8NnrhzSR7DlH0e5QZSJdJWDI",{"id":209,"title":210,"author":6,"body":211,"canonical":101,"category":102,"cover":101,"date":303,"description":304,"draft":105,"extension":106,"keywords":101,"meta":305,"navigation":108,"noindex":105,"ogImage":101,"path":306,"seo":307,"seoDescription":101,"seoTitle":101,"stem":308,"tags":309,"updated":101,"__hash__":313},"blog\u002Fblog\u002Fmobile-desktop-cwv-gap.md","移动端比桌面慢三秒，差距不只在网络",{"type":8,"value":212,"toc":295},[213,216,219,222,225,228,231,234,237,240,243,247,250,253,256,259,262,265,268,271,274,277,280,283,286,289,292],[11,214,215],{},"2026 年 9 月我们测一个客户站，同一页面桌面 1.8 秒、移动端 5.1 秒。客户第一反应是移动网络慢。查下来，网络只占了一半，另一半是 CPU 和渲染。",[15,217,218],{"id":218},"四个差距来源",[11,220,221],{},"第一，CPU。中端安卓机的性能大约是桌面电脑的四分之一，同样的 JS 在手机上执行时间翻几倍。",[11,223,224],{},"第二，网络。4G 的往返延迟比宽带高，带宽也不稳定，晚高峰更明显。",[11,226,227],{},"第三，渲染。移动端屏幕小，但 DOM 没变，布局计算和绘制的工作量并没有减少。",[11,229,230],{},"第四，资源。移动端视口窄，可能触发不同的图片尺寸和懒加载逻辑，加载的资源反而不一样。",[15,232,233],{"id":233},"网络不是主因",[11,235,236],{},"很多人把移动端慢归咎于网络，实测下来 4G 的带宽对大部分页面够用，真正拖时间的是延迟。",[11,238,239],{},"一个请求来回 100 毫秒，首屏要串行发五个请求，光是等待就是半秒。桌面宽带这个数字是 20 毫秒。",[11,241,242],{},"所以减少请求数量比压缩资源体积更有效，尤其是在移动端。",[15,244,246],{"id":245},"cpu-降速才是大头","CPU 降速才是大头",[11,248,249],{},"桌面电脑跑得欢的 JS，在中端手机上执行时间能翻四倍。",[11,251,252],{},"如果首屏要执行 800 毫秒的 JS，手机上就是三秒多。这还没算解码图片和渲染布局。",[11,254,255],{},"测试时必须打开 CPU 降速。Lighthouse 默认给移动端 4 倍降速，这个值接近真实的中端机，别关掉。",[15,257,258],{"id":258},"移动端专属的四个坑",[11,260,261],{},"第一个，懒加载触发太早。移动端视口窄，图片懒加载的阈值如果按桌面设置，用户滚动一下就要下载好几张。",[11,263,264],{},"第二个，字体太大。移动端带宽和 CPU 都紧张，几兆的中文字体在手机上是灾难。",[11,266,267],{},"第三个，浮层太多。客服、Cookie 提示、下载 App 的横幅，三个浮层叠在小屏上，遮挡内容还影响交互。",[11,269,270],{},"第四个，横向溢出。页面出现横向滚动条，用户在手机上左右晃，体验直接崩掉。",[15,272,273],{"id":273},"怎么测",[11,275,276],{},"先用 DevTools 的移动端模拟，开 4G 降速和 4 倍 CPU 降速，看首屏指标。",[11,278,279],{},"再用真机测。模拟器和真机差很多，尤其是低端安卓机上的表现。",[11,281,282],{},"最后看 CrUX 按设备分组的数据。移动端的真实用户分布才是判断用户感受的依据。",[15,284,285],{"id":285},"一个判断",[11,287,288],{},"移动端优化不能靠桌面数据推算。同一套代码，桌面合格、移动端超标是常态。",[11,290,291],{},"我们的项目验收标准里，移动端的 LCP 单独设一条线，不和桌面共用。",[11,293,294],{},"因为大部分软件公司的流量里，移动端占比已经超过一半，甚至更高。只优化桌面，等于只做了一半。",{"title":91,"searchDepth":92,"depth":92,"links":296},[297,298,299,300,301,302],{"id":218,"depth":92,"text":218},{"id":233,"depth":92,"text":233},{"id":245,"depth":92,"text":246},{"id":258,"depth":92,"text":258},{"id":273,"depth":92,"text":273},{"id":285,"depth":92,"text":285},"2026-08-21","同一页面桌面 1.8 秒、移动 5.1 秒。很多人以为差在网络，其实 CPU 降速和布局复杂度占大头。这篇写四个差距来源和移动端专属的测试方法。",{},"\u002Fblog\u002Fmobile-desktop-cwv-gap",{"title":210,"description":304},"blog\u002Fmobile-desktop-cwv-gap",[310,311,312],"移动端","CoreWebVitals","测速","015VaLRnQmI9rnAktRBsKlBKBNOLm6Y8AltoddAZV7Y",1794088102626]