[{"data":1,"prerenderedAt":302},["ShallowReactive",2],{"blog-cls-mobile-viewport-shift":3,"blog-prev-cls-mobile-viewport-shift":122,"blog-next-cls-mobile-viewport-shift":213},{"id":4,"title":5,"author":6,"body":7,"canonical":106,"category":107,"cover":106,"date":108,"description":109,"draft":110,"extension":111,"keywords":106,"meta":112,"navigation":113,"noindex":110,"ogImage":106,"path":114,"seo":115,"seoDescription":106,"seoTitle":106,"stem":116,"tags":117,"updated":106,"__hash__":121},"blog\u002Fblog\u002Fcls-mobile-viewport-shift.md","移动端 CLS 的三个特有来源，桌面测不出来","元析智能",{"type":8,"value":9,"toc":96},"minimark",[10,14,19,22,25,28,32,35,38,41,44,48,51,54,57,60,63,66,69,72,75,78,81,84,87,90,93],[11,12,13],"p",{},"2026 年 5 月我们遇到一个站，桌面 CLS 0.02，移动端 0.21。图片宽高、第三方组件都查过了，没问题。最后发现三个偏移来源只在手机上出现，桌面版永远看不到。",[15,16,18],"h2",{"id":17},"第一处地址栏收起和展开","第一处：地址栏收起和展开",[11,20,21],{},"移动浏览器滚动时，地址栏会收起，视口高度变大，页面重新布局。如果页面里有依赖视口高度的元素，就会跳一下。",[11,23,24],{},"最典型的是用 100vh 设定的全屏区块。地址栏一收，100vh 变大，里面的内容跟着重排。",[11,26,27],{},"改法是换成 svh 或 dvh 单位，让高度跟着实际视口走。固定底部的按钮也要检查，别用绝对定位加百分比高度。",[15,29,31],{"id":30},"第二处输入法和键盘弹出","第二处：输入法和键盘弹出",[11,33,34],{},"用户在表单页点输入框，键盘弹出，视口高度瞬间减少一半。底部固定的元素被顶上去，或者页面滚动位置变化，都会记一次偏移。",[11,36,37],{},"这个问题在注册页、留资页特别常见，而这些页面恰恰是转化最关键的页面。",[11,39,40],{},"改法是尽量不用 fixed 定位的底部元素，或者用 visualViewport 接口监听键盘状态，主动调整布局。",[11,42,43],{},"还有一个细节：输入框获得焦点时页面自动滚动，这个滚动不算 CLS，但如果同时触发了元素重排，就会算。",[15,45,47],{"id":46},"第三处折叠菜单和横向标签","第三处：折叠菜单和横向标签",[11,49,50],{},"移动端的导航是折叠的。用户点开菜单，菜单把下面的内容推下去，这是一次明显的偏移。",[11,52,53],{},"横向滚动的标签栏也有类似问题：切换标签时内容区高度变化，下面的内容跟着跳。",[11,55,56],{},"改法是把折叠面板做成浮层，不占文档流；或者给内容区固定最小高度，变化范围控制在几十像素内。",[15,58,59],{"id":59},"为什么桌面测不出来",[11,61,62],{},"桌面浏览器没有地址栏收起，没有软键盘，视口高度固定，所以这三类问题在桌面上不会触发。",[11,64,65],{},"DevTools 的设备模拟虽然能模拟移动端视口，但它不会模拟地址栏和键盘的真实行为，滚动起来视口尺寸是固定的。",[11,67,68],{},"所以移动端 CLS 必须上真机测。模拟器只能看个大概。",[15,70,71],{"id":71},"真机怎么测",[11,73,74],{},"用安卓手机连电脑，打开 Chrome 的远程调试，在电脑上看 Performance 面板录屏。",[11,76,77],{},"录的时候做三个动作：上下滚动、点开菜单、在表单里点输入框。每个动作之后看有没有 Layout Shift 标记。",[11,79,80],{},"录屏比数据有用，因为你能看到具体是哪个元素在动、动了多少。",[11,82,83],{},"再看 CrUX 里按设备分组的数据。桌面合格、移动端超标，就说明问题出在这三类场景里。",[15,85,86],{"id":86},"一个建议",[11,88,89],{},"移动端的 CLS 单独设一条线，不和桌面共用。我们给客户的标准是移动端 0.1 以内、桌面 0.05 以内。",[11,91,92],{},"因为移动端的偏移对用户影响更大。屏幕小，一次偏移可能把整个按钮挪出视野，用户点不到，直接流失。",[11,94,95],{},"这类问题修起来都不难，难的是发现。桌面数据好看的时候，很少有人会想到用真机再测一遍。",{"title":97,"searchDepth":98,"depth":98,"links":99},"",2,[100,101,102,103,104,105],{"id":17,"depth":98,"text":18},{"id":30,"depth":98,"text":31},{"id":46,"depth":98,"text":47},{"id":59,"depth":98,"text":59},{"id":71,"depth":98,"text":71},{"id":86,"depth":98,"text":86},null,"技术SEO","2026-05-04","一个站桌面 CLS 0.02、移动端 0.21，查下来是地址栏、输入法和折叠菜单三个移动端独有的场景。这篇写成因、改法，以及真机怎么测。",false,"md",{},true,"\u002Fblog\u002Fcls-mobile-viewport-shift",{"title":5,"description":109},"blog\u002Fcls-mobile-viewport-shift",[118,119,120],"CLS","移动端","页面体验","GwKpO4JJL9LLd1xbPHLu8h2ikEaAATw7UjWswU2FolU",{"id":123,"title":124,"author":6,"body":125,"canonical":106,"category":107,"cover":106,"date":202,"description":203,"draft":110,"extension":111,"keywords":106,"meta":204,"navigation":113,"noindex":110,"ogImage":106,"path":205,"seo":206,"seoDescription":106,"seoTitle":106,"stem":207,"tags":208,"updated":106,"__hash__":212},"blog\u002Fblog\u002Fxml-sitemap-segmentation.md","大站 sitemap 怎么分片：5 万页站点的三条规则和一次失败",{"type":8,"value":126,"toc":194},[127,130,133,136,139,143,146,149,152,156,159,162,165,169,172,175,179,182,185,188,191],[11,128,129],{},"一个 5 万页的 SaaS 文档站，sitemap 之前只有 40% 的页面被收录。我们按内容类型拆成 18 个分片、给 lastmod 立了规矩，8 周后收录率到 78%。分片不是玄学，有三条能落地的规则。",[15,131,132],{"id":132},"我们接手的那个站",[11,134,135],{},"2025 年 11 月接的一个开发者工具客户，站点 5 万页左右：文档 3.2 万页、博客 6000 页、产品页 800 个、剩下的是一堆版本归档和参数页。",[11,137,138],{},"当时只有一份 sitemap.xml，5 万条 URL 塞在一个文件里，lastmod 全部写成抓取当天。Google Search Console 显示已发现 5 万条、已收录 2.1 万条，百度那边更差，收录不到 1.5 万。",[15,140,142],{"id":141},"规则一按内容类型分不按日期分","规则一：按内容类型分，不按日期分",[11,144,145],{},"第一版分片我们按月份拆，每个月一个 sitemap。结果证明这是错的：文档页和博客页混在一起，版本归档页和老文档混在一起，搜索引擎没法判断哪个分片值得优先抓。",[11,147,148],{},"第二版改成按内容类型拆：docs、blog、product、changelog、archive 五个大类，docs 再按产品模块拆成 12 份，一共 18 个分片，外面套一个 sitemap index。",[11,150,151],{},"改完第二周，GSC 里\"已发现\"从 5 万涨到 4.9 万（之前有一部分根本没被发现），文档页的抓取频次涨了 2 倍。",[15,153,155],{"id":154},"规则二单文件不超过-3-万条留余量","规则二：单文件不超过 3 万条，留余量",[11,157,158],{},"协议上限是单文件 5 万条，但我们建议控制在 3 万以内。原因很简单：文件越大，解析越慢，出错的概率越高。",[11,160,161],{},"这个站的文档分片每个控制在 1.5 万到 2 万条，18 个文件加起来不到 600KB。搜索引擎的抓取和解析都很顺。",[11,163,164],{},"还有一条：sitemap 文件本身不要做 gzip 之外的压缩，不要加登录鉴权，不要 301。我们见过一个客户把 sitemap 放在需要登录的 CDN 后面，蜘蛛拿到的是 403，白等了三个月。",[15,166,168],{"id":167},"规则三lastmod-只写真实更新时间","规则三：lastmod 只写真实更新时间",[11,170,171],{},"这个站的 lastmod 之前全写抓取当天，等于告诉搜索引擎\"所有页面每天都在变\"。结果搜索引擎不再相信这个字段，抓取优先级完全按别的信号走。",[11,173,174],{},"改成真实更新时间之后：只有内容实质变更的页面才更新 lastmod，模板调整、样式修改不算。改完第六周，GSC 里\"已发现未收录\"从 2.8 万降到 9000。",[15,176,178],{"id":177},"一次失败分片后忘了更新索引","一次失败：分片后忘了更新索引",[11,180,181],{},"第一版上线时我们只提交了 18 个子 sitemap，忘了更新 sitemap index 里的引用。搜索引擎三天没发现新分片，我们以为分片没用，差点回滚。",[11,183,184],{},"教训：分片上线后必须验证三件事——index 能访问、index 里的子文件都能访问、每个子文件里的 URL 都能打开。我们后来写了个脚本，每次发布跑一遍，5 分钟。",[15,186,187],{"id":187},"判断",[11,189,190],{},"sitemap 分片不是给搜索引擎看的\"提交动作\"，是给抓取排优先级的\"结构声明\"。内容类型清楚、文件大小可控、lastmod 可信，这三件事做到，收录率自然上来。",[11,192,193],{},"5 万页以下的站，其实一份 sitemap 就够。分片是给大站和内容类型复杂的站准备的，别为了\"看起来规范\"过度拆分。",{"title":97,"searchDepth":98,"depth":98,"links":195},[196,197,198,199,200,201],{"id":132,"depth":98,"text":132},{"id":141,"depth":98,"text":142},{"id":154,"depth":98,"text":155},{"id":167,"depth":98,"text":168},{"id":177,"depth":98,"text":178},{"id":187,"depth":98,"text":187},"2026-05-03","一个 5 万页的 SaaS 文档站，sitemap 之前只有 40% 的页面被收录。我们按内容类型拆成 18 个分片、给 lastmod 立了规矩，2025 年 11 月开始改，8 周后收录率到 78%。分片规则、失败教训和验证方法都在这篇。如果你也在管大站，这篇能省一次返工，少走三个月弯路。",{},"\u002Fblog\u002Fxml-sitemap-segmentation",{"title":124,"description":203},"blog\u002Fxml-sitemap-segmentation",[209,210,211],"sitemap","收录","站点结构","1ntf9MrnCVdbtT39M-cGiU6X493sqN3_fTXMBioldAE",{"id":214,"title":215,"author":6,"body":216,"canonical":106,"category":290,"cover":106,"date":291,"description":292,"draft":110,"extension":111,"keywords":106,"meta":293,"navigation":113,"noindex":110,"ogImage":106,"path":294,"seo":295,"seoDescription":106,"seoTitle":106,"stem":296,"tags":297,"updated":106,"__hash__":301},"blog\u002Fblog\u002Fhit-competitor-weak-pages.md","打竞品写得最差的二十个页面，比追爆款有效",{"type":8,"value":217,"toc":282},[218,221,224,227,230,233,236,239,243,246,249,252,255,258,261,264,267,270,273,276,279],[11,219,220],{},"找竞品的软肋，不要看他们写得最好的页面，要看写得最差的 20 个。写得好的你追不上，写得差的才有位置。2026 年 3 月我们给一个客户挑出 20 个这样的页面，他去做了 8 篇，六周后 6 篇进前 30。",[15,222,223],{"id":223},"怎么挑",[11,225,226],{},"给竞品的每篇文章打四个分：字数是否够、有没有数据或截图、结构是否清楚、最近一次更新是什么时候。四项都弱的，就是最差的那批。",[11,228,229],{},"431 篇里我们挑出 20 篇，绝大多数有三个共同点：800 字以下、没有一张图、发布时间超过两年。",[15,231,232],{"id":232},"这些页面的价值在哪",[11,234,235],{},"它们往往还在前 30 名，说明这个词有搜索量、竞争不激烈，只是没人认真做。你只要做得比它完整，位置就是你的。",[11,237,238],{},"一个具体的例子：竞品有一篇讲“日志按天分片还是按小时分片”，1200 字，没有任何配置示例。我们客户补了一篇带两个真实集群配置的，三周排到第 7。",[15,240,242],{"id":241},"另一种软肋过时的页面","另一种软肋：过时的页面",[11,244,245],{},"竞品两年前写的定价页、版本对比页、功能清单，只要产品改过，这些页面就是错的。用户一验证就发现问题。",[11,247,248],{},"这类页面比薄页更好打，因为你不需要写得多好，只要写得准。",[15,250,251],{"id":251},"别照抄结构",[11,253,254],{},"看到竞品的差页面，容易顺手把它的小标题抄过来，写得比他长一点。这么做排名一般不动。",[11,256,257],{},"正确的做法是换角度：他讲概念，你讲操作步骤；他讲通用情况，你讲某个行业的具体情况。",[15,259,260],{"id":260},"打分表怎么维护",[11,262,263],{},"每季度更新一次，只重算新增页面和更新过的页面。表格里加一列“我们做不做”，明确标出放弃的，别含糊。",[11,265,266],{},"我们给客户的表里，20 个页面中标的 11 个，放弃 9 个。放弃的原因写得很清楚：没素材、跟产品定位不符、词太小。",[15,268,269],{"id":269},"为什么不追爆款",[11,271,272],{},"竞品的爆款文章背后往往有品牌、外链、社群一起推，你看到的是结果，不是方法。追爆款的成功率低，还容易被带偏选题方向。",[11,274,275],{},"还有一个副作用值得说：打软肋这件事，销售也用得上。客户在对比阶段问“你们和 XX 有什么区别”，你能拿出这几篇比他写得更细的页面，对话会短很多。",[11,277,278],{},"打软肋的成功率高得多，因为你是在别人没做好的地方做得好一点，这个门槛低且可控。",[11,280,281],{},"我们内部把这类页面叫“有位置的废页”，有位置说明词有需求，废说明没人做好，两个条件同时成立的页面不多，遇到就别放过。",{"title":97,"searchDepth":98,"depth":98,"links":283},[284,285,286,287,288,289],{"id":223,"depth":98,"text":223},{"id":232,"depth":98,"text":232},{"id":241,"depth":98,"text":242},{"id":251,"depth":98,"text":251},{"id":260,"depth":98,"text":260},{"id":269,"depth":98,"text":269},"SEO","2026-05-05","竞品写得好的页面你追不上，写得差的页面才有机会。我们按字数、数据、结构、更新时间给 400 多篇竞品文章打分，挑出最差 20 篇，客户做了 8 篇，6 篇进前 30。",{},"\u002Fblog\u002Fhit-competitor-weak-pages",{"title":215,"description":292},"blog\u002Fhit-competitor-weak-pages",[298,299,300],"竞品分析","内容策略","选题","0iDcvmAX-LUzu_xWfhl0SuVXFXe4fvHS7jECFFcLSjY",1794088106250]