聊抓取预算时,多數人會先數 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——但這個過程是渐進的,別指望改完第二天就看到曲线抬头。