第三方脚本拉进8个域名,只看HTML一个都看不到
本文目录
- 只读HTML,你能看到几个第三方?
- 1和8的差距
- 为什么这件事值得单独说
- 把第三方全部掐断,页面还剩什么?
- 实验怎么做的
- 先说一次尺子失效
- 正文基本还在
- 骨架一条不少
- 图片是唯一真塌的那一项
- 462个域,为什么两个站几乎不重合?
- 三分之二只出现一次
- 0.051这个数
- 权威大样本为什么看不到这条长尾
- 这些外部域,分别在干什么?
- 分类结果
- 最大的那一类,是“归不了类”
- 字节和数量完全不是一回事
- 一半的字节,不是你发出去的
- 中位数39.1%,四分之三分位90.7%
- 累计字节最大的那个域,跟你想的不一样
- 字节和抓取的关系
- 那这些第三方,会不会真的挂?
- 实测这一刻,基本都是活的
- 真正的风险在三个别的地方
- 这份清单该由谁来盘?
- 每一个都是有人添的,加起来没人认领
- 盘点的正确姿势是按域,不是按脚本
- 盘完之后,哪些该动哪些不必
- 先按三个维度排一遍
- 把掐断测试做成常态检查
- 常见问题解答
- 第三方域多是不是就一定不好?
- 为什么只读HTML看到的第三方那么少?
- 掐断第三方之后图片全没了,这算问题吗?
- 行业整理的第三方脚本清单能直接用吗?
- 那些大规模统计报告的数字,跟自己测出来的对不上怎么办?
- 第三方经常挂吗?
- 用内容安全策略把第三方管起来,可行吗?
- 这次的数字能不能套到我的站上?
- 权威参考资料
摘要:131个海外独立站的首页,只读HTML的时候能看到的外部域名中位数是1个;等脚本跑完,这个数变成8个,最多的一个站41个。26个站(20.5%)从“看起来只依赖两三家”变成“实际连着十五家以上”。把所有第三方请求全部掐断再跑一遍:正文中位数还剩94.6%,链接和结构化数据几乎一条不少,但图片只有5.5% 能加载出来,78.4% 的站七成以上的图挂掉。更值得记的是那462个不同的第三方域——其中295个只出现在一个站上,任取两个站,它们的第三方清单重合度平均只有0.051。
做前两篇实测的时候,网络面板一直在旁边开着。有个画面反复出现:地址栏里是一个域名,请求列表里是二三十个。
这件事本身不新鲜,做前端的都知道页面会加载外部资源。真正让人想量一量的是另一层:这些依赖,在你只读HTML的时候,几乎一个都看不出来。
这是同一批数据的第三个侧面。前两篇分别问的是“不执行脚本还剩多少内容”和“执行完之后用户能看到多少”,答案见关掉脚本之后还剩多少字的实测与隐藏内容的可读性裁决表。这一篇问的是:页面跑起来的时候,到底有多少家外部公司参与其中。
只读HTML,你能看到几个第三方?
先把口径说清楚。这里的“第三方”指的是与站点主域不同的注册域(也就是常说的顶级域加一级),子域不算,比如 cdn.example.com 仍然算自己家的。这个口径偏保守,会把不少实际由外部公司运营的资源算成第一方。
1和8的差距
同一批站跑两轮:一轮把脚本关掉,一轮让它正常执行,其余条件全部相同。数出每轮实际发生请求的外部域名个数。
| 指标 | 关掉脚本 | 脚本跑完 |
|---|---|---|
| 第三方域数中位 | 1 | 8 |
| 全站请求数中位 | 50 | 129 |
脚本给页面新增的第三方域,中位数是6个,最多的一个站新增38个。
更能说明问题的是这组:有26个站(20.5%)在只读HTML时最多只能看到2个外部域,脚本跑完之后变成15个以上。brooklinen从1涨到33,graza从1涨到30,reebok从1涨到29,ice-watch从0涨到23。
为什么这件事值得单独说
因为大量安全与合规检查是在HTML层做的:扫一遍源码里的 <script src>,列出外部域,做成一份依赖清单。这个做法在十年前是够用的。
现在不够了。一个标签管理器、一个应用市场的插件加载器,本身只占HTML里的一行,跑起来之后会按配置去拉十几个别的域。那一行代码是你审过的,它拉进来的十几个域不是。
这种“一行代码带进一串依赖”的模式,web.dev关于第三方JavaScript的说明里讲得比较系统:外部脚本除了自身体积,还会带来额外的连接建立、执行阻塞和后续请求,而这些成本在引入的那一刻通常没人算过。
依赖清单的分布也印证了这一点:
| 第三方域数 | 站数 | 占比 |
|---|---|---|
| 0到1个 | 4 | 3.1% |
| 2到5个 | 33 | 26.0% |
| 6到10个 | 37 | 29.1% |
| 11到20个 | 27 | 21.3% |
| 21个以上 | 26 | 20.5% |
分母127。四分之一分位是3个,四分之三分位是16个,最多的一个站41个。
把第三方全部掐断,页面还剩什么?
知道有多少个依赖之后,下一个问题自然是:万一它们不在了呢。这个问题不用等意外发生,可以直接造出来。
实验怎么做的
在浏览器里给每个站装一条路由规则:凡是目标域与站点主域不同的请求,一律中断。然后正常访问首页,等3.5秒,量正文、链接、图片、结构化数据。
这个做法模拟的不是“某一家第三方挂了”,而是一个极端场景:所有外部依赖同时不可达。现实里更常见的是其中一两家慢或者挂,但极端场景能把依赖的骨架照出来。
先说一次尺子失效
第一版跑完的结果是:33.6% 的站掐断第三方之后连页面都打不开。这个数字很吓人,差点就写进结论了。
去看失败原因才发现分成两类。一类是超时,那是真的;另一类的错误信息长这样:请求主文档时直接失败,而这些站的最终地址是 braun.com.cn、casetify.cn、uniqlo.cn、philips.com.cn。
原因很清楚:这些站会把访问者重定向到另一个国家的域名,而那个域名的注册域跟原域名不一样,于是被我自己的规则当成第三方拦掉了。被拦的是主文档本身,页面当然打不开——这跟第三方依赖毫无关系。
修法是给路由规则加一个前置判断:主文档请求及其重定向链一律放行。改完重跑,打不开的站从44个降到9个(6.9%)。
这类错误的可怕之处在于它给出的是一个“看起来很有新闻价值”的数字。33.6% 比6.9% 好看得多,而且完全说得通。凡是跑出一个特别符合预期的数字,先去看它的失败样本长什么样。类似的教训之前记过一次,那回是把噪声当成了差异,写在页面抖动基线与差异误报里。
正文基本还在
修正之后,109个可比对的站,掐断第三方后正文的保留比例:
| 正文保留比例 | 站数 | 占比 |
|---|---|---|
| 0.99以上 | 41 | 37.6% |
| 0.90 ~ 0.99 | 20 | 18.3% |
| 0.50 ~ 0.90 | 29 | 26.6% |
| 0.05 ~ 0.50 | 14 | 12.8% |
| 0.05以下 | 5 | 4.6% |
中位数是0.946。也就是说,把所有外部依赖同时掐掉,一半以上的站正文只少了不到6%。25% 分位是0.711,10% 分位是0.208。
掉得最狠的几个:bigcommerce和bolia归零,uniqlo归零,sostrenegrene从31052掉到375,joolz从51756掉到5834,bugaboo从64784掉到13458。
另一头有48个站(44.0%)几乎不受影响,差异不到5%。这批站就是这次的对照组——它们证明拦截规则本身没有误伤第一方资源,否则所有站都该出现落差。给每次对比配一组本该没有差异的样本,这条在给建议配一个注定无效的对照组里单独讲过。
骨架一条不少
结构件那一组的结果更干脆:
- 链接:掐断后保留比例中位0.986,完全归零的站只有4个。
- 结构化数据:保留比例中位1.000,一个归零的都没有。
- 页面主标题:保留比例中位1.000,只有1个站归零。
这三条负结果放在一起,指向同一个判断:一个页面能不能被机器读懂,跟它连着多少家第三方基本无关。那些外部依赖承担的是别的工作。
顺带一提,掐断之后有6个站的页面标题变了,其中glossier的标题直接变成空的。标题这种最基础的东西也可能挂在外部脚本上,而它一旦为空,社交分享和搜索结果里的呈现就全乱了。首页各处自我描述本来就常常对不上,那一层量在首页六份自我描述的实测里。
图片是唯一真塌的那一项
接下来是这次最刺眼的一个数。
掐断第三方之后,页面上真正加载出来的图片占比中位数只有0.055,25% 分位是0。换句话说,超过四分之一的站,一张图都出不来。
78.4% 的站有七成以上的图片加载失败。anker的109张图一张没出来,babybjorn的107张一张没出来,aboutyou的104张一张没出来。
原因不难理解:图片托管在图像处理与分发服务上,域名跟主站不同。这本身是合理的技术选择,性能上也是对的。但它意味着一个页面的视觉,几乎完全押在自己不控制的域名上——文字还在,版式还在,图全是空的。
这里要说清楚一个口径:如果只按注册域算,很多用了自定义域名(比如 img.example.com 指向外部服务)的站会被算成第一方,实际控制权仍在外面。所以这个78.4% 是下界,真实的依赖程度更高。
462个域,为什么两个站几乎不重合?
把127个站的第三方域全部合起来去重,得到462个不同的域。这个数字本身不奇怪,奇怪的是它们的分布。
三分之二只出现一次
| 出现范围 | 域的个数 | 占462的比例 |
|---|---|---|
| 只被1个站用到 | 295 | 63.9% |
| 只被1到2个站用到 | 360 | 77.9% |
| 被10个站以上用到 | 26 | 5.6% |
| 被30个站以上用到 | 5 | 1.1% |
被30个站以上用到的那5个是电商平台自己的域、它的支付入口、一家邮件营销服务和一个字体接口。除此之外,再没有任何一个第三方域出现在超过四分之一的站上。
0.051这个数
顺着这个分布做了一次两两比对:任取两个站,看它们的第三方域清单重合多少。用交集除以并集来算,127个站两两配对的平均重合度是0.051。
这个数说人话就是:你和隔壁那家同类电商,第三方依赖清单里能对上的部分,大约二十分之一。
这带来的实际后果是,有一整类工作没法靠行业经验代劳:
- 别人整理的“常见第三方脚本清单”对你基本没用,因为你那份清单里三分之二的域不在任何一份公开清单上。
- 按行业惯例配置的内容安全策略白名单,大概率会漏掉你自己那部分长尾。这一层配错了会静默拦掉资源,之前实测过一批支付页的策略配置,情况相当糟,记在支付页脚本策略实测里。
- 供应商评估、数据处理协议这类合规工作,清单得自己盘,抄不来。
权威大样本为什么看不到这条长尾
这里有个有意思的对照。Web Almanac 2024年的第三方章节是这个领域样本量最大的公开分析,覆盖数百万个页面。但它在方法论里写明了一条筛选规则:只有在数据集里至少50个不同页面上出现过的域,才被计为第三方。
这条规则完全合理——它把偶发的、一次性的域挡在外面,让分类统计更稳。但它同时意味着:我这次发现的那295个只出现一次的域,在那套口径下根本不会被算进来。
两边不矛盾,量的是不同的东西。大样本量的是“生态里有哪些主要玩家”,小样本贴着单站量的是“你这一个站实际连着谁”。做自己站的盘点时,需要的是后者,而后者只能自己跑。
这些外部域,分别在干什么?
光知道个数没法行动,还得知道它们各自在干嘛。所以写了12条分类规则,覆盖标签管理、分析、广告、邮件营销、同意管理、客服、评价、电商平台、内容分发、字体、支付、风控这些常见类别,然后把128个站的第三方域逐个归类。
分类结果
| 用途 | 用到它的站 | 域次 | 累计字节 |
|---|---|---|---|
| 归不了类 | 108(84.4%) | 512 | 69 MB |
| 电商平台与插件 | 72(56.3%) | 255 | 727 MB |
| 内容分发 | 63(49.2%) | 104 | 138 MB |
| 邮件与短信营销 | 54(42.2%) | 75 | 9 MB |
| 字体与图标 | 52(40.6%) | 81 | 5 MB |
| 同意与隐私 | 48(37.5%) | 67 | 5 MB |
| 分析与监测 | 47(36.7%) | 59 | 1 MB |
| 评价与内容 | 39(30.5%) | 46 | 7 MB |
| 广告与再营销 | 29(22.7%) | 50 | 不足1 MB |
| 在线客服 | 22(17.2%) | 39 | 4 MB |
| 风控与验证 | 17(13.3%) | 17 | 不足1 MB |
| 支付与分期 | 14(10.9%) | 15 | 不足1 MB |
| 标签管理 | 14(10.9%) | 15 | 1 MB |
单个站踩中的类别数,中位是4个,最多的一个站占了12类。
最大的那一类,是“归不了类”
这张表真正的内容在第一行。12条分类规则跑完,仍然有345个去重域归不了类,涉及84.4% 的站,而这345个里有252个只出现过一次。
这些域长什么样?出现最多的是社交平台的像素脚本(15个站)和一个A/B测试服务(9个站),再往下就全是4个站以下的:退换货服务、店内导购机器人、退货保险、归因分析、价格实验、前端加速代理、无障碍插件、愿望清单、功能开关平台、联盟推广。
这些名字多数人没听过,但它们各自是一个真实存在的公司,各自在页面上执行代码,各自能读到用户在页面上的行为。做一份分类表最大的收获,往往不是那些能归类的,而是发现归不了类的比能归类的还多。
字节和数量完全不是一回事
把字节那一列单独看一眼:电商平台与插件那一类727 MB,占绝对大头;内容分发138 MB;剩下十一类加起来不到100 MB。
而广告、风控、支付这三类,用到的站不少,累计字节都不足1 MB。它们的成本不在流量上,在别处——执行时间、隐私合规、以及页面对它们的可用性依赖。
按数量盘点会高估广告脚本、低估平台自带的东西;按字节盘点则正好反过来。两个维度都要看。这些外部资源具体拖慢了多少,可以用Lighthouse的第三方资源摘要按实体分组量一遍,它会把同一家公司的多个域合并计算耗时。
一半的字节,不是你发出去的
依赖数量之外,还有一笔字节账。
中位数39.1%,四分之三分位90.7%
按响应头声明的长度统计,第三方资源占页面全部字节的比例,中位数是39.1%。25% 分位8.2%,75% 分位90.7%——这个分布散得非常开。
有44.9% 的站,过半字节来自第三方。
这个数是保守的:没有声明长度的响应按0计。实际比例只会更高。
想给自己的数字找个参照系,HTTP Archive的Web现状报告有页面请求数与传输字节的长期趋势,能看出你这一档处在什么位置。不过要注意它统计的是全网抽样,电商站普遍高于中位水平。
累计字节最大的那个域,跟你想的不一样
把所有站的第三方字节按单个域累加(注意跟上面那张按类别汇总的表不是一回事),排第一的是电商平台自己的主域:67个站合计726 MB,2334次请求。这不意外。
意外的是第二名:一个图像优化服务,累计100 MB,但只有1个站在用。第四名是一家电商技术服务商,11 MB,也只有1个站在用。
这说明字节这件事上,“多少个站在用”和“吃掉多少流量”是两回事。一个只有你在用的第三方,完全可能是你页面上最大的那一块。盘点的时候按域名个数排序会漏掉它,得按字节排。
字节和抓取的关系
顺带说一层不太被提起的关系。抓取器对单个页面有取回上限,超了就截断,而截断是从后往前丢的。第三方资源虽然多数不计入主文档字节,但它们撑大的是整体加载负担和渲染时间,间接影响抓取那一侧愿意在这个页面上花多少资源。主文档自身的字节预算怎么算、超了会丢什么,之前单独量过一轮,见页面字节预算与抓取截断实测。
那这些第三方,会不会真的挂?
前面造的是极端场景。现实里第三方到底稳不稳定,得单独看。
实测这一刻,基本都是活的
统计每个站的第三方请求里有多少返回了4xx或5xx:127个站里只有12个(9.4%)出现过,而且几乎都只是零星一两条。最多的一个站是90次请求里2次失败。
会返回错误的第三方域一共11个,最多的一个也只出现2次。
这是一条负结果,但很重要:第三方依赖的风险不在“它今天会不会挂”,而在别处。拿单次快照去论证可用性风险是站不住的。
真正的风险在三个别的地方
第一是慢,不是挂。掐断实验里那9个加载不完的站,问题不是资源返回错误,是等待。一个阻塞性的外部脚本响应慢,整个页面就卡在那儿。慢到什么程度会真的影响抓取那一侧,之前按服务器响应时间量过一轮,见服务器变慢与抓取速率。
第二是变。第三方脚本的行为会自己改,不需要你更新任何代码。之前连续观测过两天半,就有四分之一的站上第三方脚本的默认行为发生了变化,记在第三方脚本默认值的静默漂移里。
第三是没了。域名过期、服务关停之后,页面上那条指向它的声明还在。之前扫过一批预连接声明,其中有几个指向的域名已经不存在了,细节在预连接指向的死域名实测里。
这份清单该由谁来盘?
数据说到这儿,剩下的是个组织问题。
每一个都是有人添的,加起来没人认领
把一个站的20多个第三方域拆开看,来路大同小异:建站时模板自带几个,市场部装了分析和广告的,客服团队装了在线咨询,运营装了评价和弹层,法务要求装了同意管理,前端为了性能引了个图像服务。
每一次添加都有明确的理由和明确的负责人,但没有任何一个环节负责这份清单的总量。而总量恰恰是决定页面表现的那个数。
盘点的正确姿势是按域,不是按脚本
常见的做法是列一份“我们用了哪些工具”的清单。这份清单通常是准的,但它不等于依赖清单,因为一个工具会拉进来好几个域。
正确做法是打开网络面板,按域名分组,把实际发生请求的域全列出来,逐个回答三个问题:这是谁、谁装的、去掉会怎样。有一批URL要批量提根域的话,站内有个域名提取器可以直接跑。
按这次的数据,你大概率会在这份清单上看到几个自己不认识的域。那几个就是标签管理器或者插件市场带进来的。
盘完之后,哪些该动哪些不必
先按三个维度排一遍
清单列出来之后别急着删。先给每个域标三样东西:它是不是阻塞主文档解析的、它吃掉多少字节、掐断它页面会不会塌。这三样对应三种完全不同的处理,混在一起看就没法排优先级。
| 发现什么 | 怎么判断 | 动作 |
|---|---|---|
| 没人认领的域 | 问一圈没人知道 | 直接去掉,观察一周 |
| 阻塞主文档解析的 | 看它有没有async或defer | 改成异步,或延后加载 |
| 吃掉大量字节的 | 按字节排序看前三 | 换配置或换供应商 |
| 图片托管在外部 | 掐断测试后图全空 | 正常,但要有备用方案 |
| 只是数量多但都很小 | 字节和阻塞都不显著 | 不必动,记进清单就行 |
第二行那个动作是收益最确定的:把阻塞式引入改成异步或延后,页面不用等外部服务器就能先渲染出来。具体几种改法的适用场景与代价,web.dev关于第三方脚本加载优化的那篇列得比较全,照着对一遍就行。
把掐断测试做成常态检查
这次这个实验很容易接进流水线:给关键页面各跑一次“拦掉所有外部域”的加载,记三个数——正文保留比例、图片成功率、能不能在合理时间内加载完。
顺带说一句,这类脚本的行为不只会挂,还会被别的机制静默拦住——比如自己配的完整性校验哈希过期了,脚本下载完却一行都不执行,这个坑记在完整性校验与第三方脚本更新里。
三个数各自对应一类问题:正文掉了说明内容依赖外部服务,图片全空说明视觉依赖外部服务,加载不完说明存在阻塞性依赖。第三个是最该盯的,因为它在正常情况下完全隐形,只在对方慢的时候才发作。
顺便记得:主文档请求要放行,否则你测的是自己的规则,不是站点的依赖。这个坑本文前面栽过一次。
常见问题解答
第三方域多是不是就一定不好?
不一定。这次实测里第三方域数量与正文可读性、链接完整性、结构化数据都没有直接关系,掐断之后这三样基本不受影响。数量本身不是问题,问题在于有没有人知道这份清单、里面有没有阻塞性依赖、以及有没有没人认领的域。
为什么只读HTML看到的第三方那么少?
因为绝大多数第三方是脚本运行时拉进来的。一个标签管理器在HTML里只占一行,跑起来之后会按后台配置去请求十几个域。实测中位数是关掉脚本看到1个、脚本跑完看到8个,有26个站从最多2个涨到15个以上。
掐断第三方之后图片全没了,这算问题吗?
算正常现象,不算缺陷。把图片放在专门的分发服务上是对的技术选择。但它意味着页面的视觉完全依赖一个你不控制的域,所以需要两件事:一是知道这个依赖存在,二是想清楚对方长时间不可用时的表现,至少别让布局塌掉。
行业整理的第三方脚本清单能直接用吗?
参考可以,照搬不行。这次实测的462个第三方域里有295个只出现在一个站上,任取两个站的清单重合度平均只有0.051。公开清单覆盖的是那些高频出现的主流服务,而你的长尾部分只能自己盘。
那些大规模统计报告的数字,跟自己测出来的对不上怎么办?
先比口径再比数字。举个具体的:一份广为引用的大样本分析规定,只有在至少50个不同页面上出现过的域才算第三方,这条规则会把只出现一两次的长尾整个排除掉。两边量的东西不同,结论自然不同,不存在谁错。
第三方经常挂吗?
这次快照里不常挂,127个站里只有12个出现过第三方请求返回错误,而且都是零星一两条。但这不能证明可用性没有风险,因为单次快照测不出稳定性。实际更常见的风险是慢、是行为悄悄变了、是域名早就废弃但声明还留着。
用内容安全策略把第三方管起来,可行吗?
方向是对的,但要注意两件事。一是白名单必须基于自己站的实测清单,抄行业模板会漏掉长尾;二是配错了会静默拦掉资源,页面不报错但功能失效,所以上线前要用报告模式跑一段时间。
这次的数字能不能套到我的站上?
不能。样本是海外电商与品牌独立站,第三方使用强度明显高于内容型站点,也高于国内站点常见的技术栈组合。方法可以直接抄,数字要自己量。
权威参考资料
本文标题:《第三方脚本拉进8个域名,只看HTML一个都看不到》
本文链接:https://zhangwenbao.com/third-party-domain-dependency-invisible-in-html-audit.html
版权声明:本文原创,转载与引用请注明作者与原文链接。许可协议: CC BY 4.0
← 上一篇
隐藏内容机器算不算?16种藏法的实测裁决表下一篇 →
没有了