蜘蛛池知识

蜘蛛池入口页要不要上 JS 渲染:静态输出与前端渲染的取舍

蜘蛛池入口页到底要不要用 JS 渲染?本文对比纯静态 HTML、服务端渲染和客户端渲染三种方案,说明蜘蛛抓取与渲染队列之间的差别,并分析链接发现、渲染失败率、抓取预算等实际影响,最后给出一条简单可执行的判断标准。

蜘蛛池知识

蜘蛛池入口页要不要上 JS 渲染:静态输出与前端渲染的取舍

搭蜘蛛池的时候,入口页怎么生成是个绕不开的问题。有人图省事,直接套一个前端框架,页面内容全靠 JS 拉接口;也有人全部输出静态 HTML。两种做法蜘蛛都能遇到,但遇到的难度完全不一样。这篇文章只讨论一件事:入口页的内容,到底该在服务端就拼好,还是交给浏览器去渲染。

蜘蛛拿到 HTML 之后还要不要跑 JS

搜索引擎的抓取大致分两步:先抓 HTML,再决定要不要进渲染队列。渲染是有成本的,每个页面都要占计算资源,所以渲染队列通常比抓取队列慢得多,而且有配额。一个入口页如果关键内容、链接全在 JS 里,蜘蛛第一次拿到的其实是个空壳,只能排队等渲染。等得到算运气好,等不到就只留下一份内容稀薄的记录。

换句话说,静态输出是即时可见,JS 渲染是延迟可见。蜘蛛池入口页数量动辄几千上万,延迟一点点,整体效率就差很多。

静态 HTML 和前端渲染,差在哪几个地方

  • 可见时间:静态内容抓取当次就能读到,JS 内容要等二次渲染。
  • 链接发现:写了 a 标签的 URL 在 HTML 里就能被提取,靠 JS 拼接出来的链接往往要等渲染完才被发现,甚至永远发现不了。
  • 失败率:渲染会受接口超时、跨域、第三方脚本加载失败影响,任何一环出问题,页面在蜘蛛眼里就是空的。
  • 抓取预算消耗:渲染一个页面消耗的资源明显高于纯文本抓取,同样的预算能覆盖的页面数会变少。

三种常见方案怎么选

纯静态 HTML

入口页内容变化不频繁、主要目的是把链接和主题词递出去,静态就是最省事的方案。生成时把正文、标题、内链一次性写进 HTML,蜘蛛进来一次就能拿走全部信息,不需要排队渲染。

服务端渲染(SSR)

内容需要按参数变化、又不想放弃静态可见性时,可以在服务端把首屏拼好再返回。对蜘蛛来说,拿到的仍然是完整 HTML。代价是服务器压力更大,缓存没做好时 TTFB 容易变长,这一点要额外留意。

客户端渲染(CSR)加兜底

如果确实用了前端框架,至少要保证首屏关键内容直出,而不是依赖接口返回。剩下非关键部分再交给 JS,这样即使渲染失败,页面也不是一片空白。

坚持用 JS,也得守住几条线

  1. 入口页的主要链接必须写在 HTML 里,不要用 onclick 或 JS 跳转代替 a 标签。
  2. 标题、正文摘要这类核心内容尽量直出,不要等着接口返回再填。
  3. 少依赖第三方脚本、统计代码和外部字体,任何一个卡住都可能拖垮整页渲染。
  4. 不要用 JS 判断 UA 再决定给不给内容,容易误伤,也容易被当成作弊。
  5. 如果需要跳转,优先用标准 301 或 302,而不是 JS 里的 location.href。

几个常见的想当然

“搜索引擎都能渲染 JS,所以怎么写都行。”能渲染和一定渲染是两回事,渲染排期、配额、失败重试都要算进去。入口页数量一多,这个差别会被放大。
  • 以为页面在浏览器里显示正常,蜘蛛看到的就是同一份内容,其实首屏可能靠接口,接口你有、蜘蛛不一定等得到。
  • 以为把链接写在 JS 数组里也算内链,这更多是给用户看的,对 URL 发现帮助有限。
  • 以为渲染过的页面会被永久记住,重新抓取时如果 HTML 还是空壳,判断可能回到原点。

一个简单的判断标准

判断方法很朴素:把页面 HTML 源码里的 JS 全部关掉,看还剩多少内容。如果标题、正文、内链都还在,说明方案是稳的;如果关掉 JS 只剩一个空 div,那就要考虑改造成静态输出或者 SSR。蜘蛛池要的是被快速、稳定地读到,而不是页面做得多花哨。