聊抓取预算时,多数人会先数 URL:Sitemap 有多少条、内链能到几层、日志里被请求了多少次。这只是其中一半。另一半是每个请求的代价——蜘蛛在单位时间里能取回并解析多少页面,既取决于它分配给站点的并发,也取决于每个页面要花掉多少时间和带宽。页面越重,这个成本越高,同一段时间里能跑完的 URL 就越少。
一次抓取请求,时间都花在哪
一次普通的 GET 要经过几段:域名解析、建立连接、等待首字节、传输响应体、解析内容并抽取链接。前几段主要受 DNS、网络和服务端影响;后两段和页面体积直接相关,也是站点自己最能控制的部分。
还有一个容易忽略的点:单个连接同一时刻只能处理一个请求。某个页面多花 800 毫秒,就意味着同一队列里少跑一个页面。
HTML 体积最容易被忽略
首屏 HTML 的膨胀,通常来自几个固定方向:把 CSS 和 JS 直接内联进模板、把接口返回的 JSON 整块塞进页面、重复的导航与页脚结构、被忽略的注释与空白,以及用 Base64 编码的图片。
这些内容在浏览器里可能感知不强,但对抓取来说,它们每次都要重新传一遍、解析一遍。
压缩:传输体积不等于解析成本
- 开启 gzip 或 brotli 后,文本类页面的传输体积通常能降到原来的两三成,这是投入产出比最高的一步。
- 静态文件交给 CDN 边缘压缩,动态页面在应用层压缩,注意别为了压缩明显拉高首字节时间。
- 压缩只解决传输这一段,解压和 DOM 解析的成本依然存在,内部冗余该删还是要删。
内联资源的两难
内联能减少请求数,但前提是这段资源只在一个页面上用。如果是全站共用的样式或脚本,内联意味着每个被抓取的页面都重复携带一份,抓取量越大,浪费越明显。拆成可缓存的外部文件通常更划算,前提是不要在 robots.txt 里挡住这些文件。CSS 和 JS 被挡住时,渲染环节可能拿不到完整页面,链接抽取也会受影响,省下来的体积得不偿失。
图片和媒体别拖住 HTML
- 图片走独立域名或 CDN,让 HTML 先返回。
- 避免在 HTML 里写 Base64 图片,它比二进制大约多出三分之一,而且无法被单独缓存。
- 首屏之外的图片用懒加载,控制 DOM 里同时存在的图片节点数量。
- 给图片设置明确的宽高,避免布局反复计算。
怎么自查
- 如果 Web 日志带有响应字节字段,按模板或目录分组算出平均响应体积,找出明显偏大的几类页面。
- 把响应时间和响应体积放在一起看。体积不大但耗时长的页面,问题通常在服务端而不是前端。
- 挑几个最大的页面,对比压缩后与未压缩的体积,判断压缩有没有真正生效。
- 抽样统计页面里内联 CSS/JS 的总量,以及它们在多少个页面上重复出现。
可以按这个顺序动手
- 确认全站压缩已开启,检查 CDN 与源站是否有一层漏掉压缩。
- 把全站共用的样式和脚本外链化,只保留必要的首屏内联。
- 清理模板里残留的注释、调试代码和不再使用的组件。
- 接口数据按需注入,不要整块塞进页面。
- 图片外置、加尺寸、懒加载。
- 改完后隔一段时间再对比日志里的响应体积与抓取量,观察变化。
几个容易踩的坑
- 不要给蜘蛛返回精简版、给用户返回完整版。同一 URL 出现两套内容,容易引起判断混乱。
- 不要为了减小体积,把正文改成必须执行 JS 才出现。体积省下来了,内容却要排队等待渲染。
- 压缩与合并时注意结构化数据、JSON-LD 的完整性,格式坏了反而多出问题。
- 体积变小不等于抓取量一定上升,它影响的是单位时间的吞吐上限。内容质量、站点结构、服务器稳定性同样是变量。
把每个页面做轻一点,本质上是在给蜘蛛省时间。省下来的时间,它可能会用来发现和重访更多 URL——但这个过程是渐进的,别指望改完第二天就看到曲线抬头。