很多站点用前端框架重构之后会遇到同一类问题:页面在浏览器里打开是完整的,标题、正文、内链都在,但在收录上却明显变慢,甚至长期停在“已发现”或“已抓取,未编入索引”。这时候先别急着改内容,多数情况下问题出在一个更靠前的环节——搜索引擎拿到的页面版本,和你用浏览器看到的版本不是同一份东西。
为什么 JS 渲染的页面容易卡在入口
传统页面把内容写在 HTML 里,抓取程序拿到响应就能直接读到全文。而 JS 渲染的页面,初始 HTML 往往只有一个容器和几个脚本文件,真正的文字、链接是浏览器执行脚本之后才出现的。搜索引擎要读到这些内容,需要额外走一步渲染,而渲染本身有成本:要排队、要执行脚本、要等接口返回。不同引擎的渲染能力和调度策略不同,出现延迟、部分渲染甚至跳过渲染,都属于正常范围内的波动。
结果就是:页面对人没问题,对抓取程序却像一张空壳。空壳页面很难被判断为有价值内容,收录节奏自然就慢。
先确认三件事,再动手改
1. 查看源代码,而不是开发者工具里的元素面板
开发者工具的元素面板显示的是渲染后的 DOM,容易造成“内容明明在页面上”的错觉。要看的是右键“查看网页源代码”得到的那份 HTML。如果里面搜不到正文关键词、搜不到主要链接,说明内容依赖脚本生成。
2. 检查 JS 和 CSS 有没有被 robots.txt 拦住
有些人为了“减少抓取消耗”,在 robots.txt 里屏蔽了 js、css 目录。对渲染型页面来说,这几乎等于把内容一起屏蔽了:脚本拿不到,渲染出来还是空壳。这类误封很隐蔽,因为页面在浏览器里完全正常,控制台也不会报错。
3. 渲染后的内容里,链接是不是真的链接
导航和列表项应该是带 href 的 a 标签;如果只是给 div 绑了点击事件、点了才跳转,抓取程序没有“点击”这个动作,站内入口等于不存在,页面之间的发现路径也就断了。
常见的几类“渲染不出来”
- hash 路由:地址中 # 后面的部分不会发给服务器,多个路由在抓取程序看来是同一个 URL。
- 内容依赖接口且需要登录态或特殊请求头:渲染程序拿不到数据,页面就是空的。
- 无限滚动:只加载首屏,后面的内容必须滚动才出现。
- 点击展开、悬停显示:正文藏在交互之后,初始状态不可见。
- 渲染超时:脚本体积太大、接口太慢,渲染任务在拿到内容前就结束了。
- 文字画在 canvas 或图片里:人能看到,但机器读不到文本内容。
改动顺序:从低成本到高成本
- 先把关键内容直出:标题、正文主体、面包屑、主要内链尽量写进初始 HTML,交互效果在直出基础上做增强。
- 清理渲染阻塞项:robots.txt 是否拦截脚本、接口是否需要鉴权、首屏请求数量是否过多、脚本能否再压缩。
- 如果整站都是客户端渲染,考虑对内容型页面做服务端渲染或静态生成,至少覆盖栏目页和文章页。
- 暂时改不动架构的,可以对重点 URL 做预渲染,把渲染后的完整 HTML 返回出去。
顺序上不要反过来:先保证 HTML 里读得到内容,再谈提交和加速。
一份快速自查清单
- 查看源代码时,能否搜到本页的核心关键词。
- robots.txt 是否拦截了 js、css 或数据接口路径。
- 主要导航是否为 a 标签,href 是否指向可直接访问的地址。
- 页面是否需要登录、点击、滚动才能看到正文。
- 渲染所依赖的接口是否稳定,是否有限流或超时。
抓取和收录是两件事:抓取只说明程序来过,能不能进入索引,还要看它到底读到了什么。JS 渲染带来的问题,多数不是内容质量不够,而是内容没有被完整交付。