HTML注释没人读,它却记着你的构建日期和供应商名单
本文目录
- 一个电商首页里,注释占掉了多少字节?
- 为什么一半以上的注释里连一个字都没有?
- 剩下那四千多条,写的是些什么
- 注释能不能看出这个站上次动的是哪一块?
- 注释里的文件名,把整套模板的目录画了出来
- 供应商名单为什么在注释里比在脚本里更全?
- 被注释掉的那些代码,浏览器还下不下载?
- 内部工单号是怎么跑到首页上的?
- 2026年了,还有谁在页面里留IE条件注释
- 这些字节到底该不该删?
- 自己站上的注释,十分钟怎么查一遍
- 常见问题解答
- HTML注释会不会影响SEO排名?
- 被注释掉的script标签,浏览器会不会还去下载那个文件?
- 为什么我的页面里有几百条空注释,删不掉?
- Shopify的app block注释能不能关掉?
- 怎么判断一条注释是自动生成的还是人写的?
- 把注释里的内部信息删掉,会不会影响团队协作?
- 竞争对手真的会看这些注释吗?
- 这次的数字能不能直接套到我的站上?
- 权威参考资料
摘要:把131个海外电商首页的源码拉下来数注释,125个站里一共10185条,其中5683条(55.8%)根本不是人写的,是前端框架用来标记流式渲染位置的空壳。剩下4502条才是真正有内容的那部分,分布在91个站上。这批注释里能读到的东西包括:宜家首页四个构件的构建日期,最老的那块停在7月7日;52个站把自己装了哪些第三方应用逐条列了出来,一共108款;3个站把内部工单号印在了首页上;8个站还留着给IE6准备的条件注释。
9月1日中午12点39分27秒,graza.co的首页被重新生成了一次。一分44秒之后,untuckit.com那边也生成了一次。这两件事没写在任何一份SEO报告里,也不在响应头、结构化数据或者sitemap的lastmod里。它们写在页面源码的一条注释里,夹在一堆脚本标签中间,被浏览器跳过,被爬虫跳过,被所有做页面体检的工具跳过。
注释是HTML里唯一一段被明确规定不要读的内容。HTML标准对注释语法的定义很短,核心意思就是从<!--开始到-->结束,中间的东西不进文档树、不参与渲染、不影响任何解析结果。
这句话还有一层没人细想的后果:做页面检查的所有工具,检查对象都是解析结果。SEO工具读的是文档树,性能工具读的是资源清单,可访问性工具读的是无障碍树,安全工具看的是发出去的请求。注释按定义不出现在这四样东西里的任何一样中。所以它不是“大家忘了检查”,是整条工具链在设计上就够不着它。
没人读,也就没人删。于是它慢慢变成了一份档案。
一个电商首页里,注释占掉了多少字节?
先说采样。9月2日凌晨,我按之前几批一直在用的那份131个海外品牌站清单,逐个拉首页原始HTML——注意是原始HTML,不执行脚本。这一点必须说死:注释只在源码里,脚本跑起来之后有些会被框架移除、有些又会被插件插进来,两个口径的数字对不上。要看的是发给爬虫和用户的那份原始文档,就只能取原始响应。这跟上次做JS渲染前后对比时的取数逻辑正好相反,那次要的是渲染之后的结果,这次要的是渲染之前。
131个站里成功取到125个。取不到的6个各有各的原因:farfetch和madewell返回403,govee读超时,notino连接失败,underarmour返回418(这个状态码的字面意思是“我是一只茶壶”,实际上是它的防护层在委婉地说不欢迎你),braun返回的首页只有一个待水合的空壳、正文全靠脚本拼。这6个站从所有分母里剔除,下面每一个百分比的分母都是125。
总量是这样的:
| 口径 | 数值 |
|---|---|
| 125个首页里的注释总条数 | 10185条 |
| 其中框架水合标记(无实义) | 5683条,占55.8% |
| 有实际内容的注释 | 4502条 |
| 至少有一条有内容注释的站 | 91个(72.8%) |
| 一条都没有的站 | 34个 |
| 有内容注释条数的中位数 | 35条 |
条数最多的是reebok.com,437条;字节最多的是nativecos.com,22354字节。但真正值得看的是占比:materialkitchen.com的注释占了整个HTML的4.122%,theordinary.com是3.520%,joolz.com是2.810%,canyon.com是2.477%,segway.com是2.026%。也就是说,这几个站每传输100个字节的首页,有2到4个字节是写给人看、而且没有人在看的。
这个量级本身不吓人。真正有意思的是这些字节里写了什么。
为什么一半以上的注释里连一个字都没有?
第一版脚本跑出来的时候,排名榜是这样的:on.com 824条,ikea.com 654条,warbyparker.com 64条。我盯着on.com那个数看了一会儿,觉得不对——一个首页写824条注释,得是什么样的团队文化。
把原文抽出来一看,824条里绝大多数长这样:
<!--$?-->
<!--/$-->
<!--[-->
<!--]-->
<!---->这不是注释,这是React服务端流式渲染留下的位置标记:$?表示这里有个Suspense边界还在等数据,/$表示这一段结束了,Vue用[和]标记片段的头尾。浏览器需要它们才能把服务端先发过来的HTML和后到的脚本对上号。它们是运行时协议的一部分,跟“注释”这个词的日常含义没什么关系。
把这一类剔掉之后,排名彻底变了:
| 站点 | 原始条数 | 框架标记 | 真实注释 |
|---|---|---|---|
| on.com | 824 | 824 | 0 |
| ikea.com | 654 | 624 | 30 |
| warbyparker.com | 64 | 44 | 20 |
| gymshark.com | 23 | 23 | 0 |
| reebok.com | 437 | 0 | 437 |
这一步是整套统计里最关键的一步。不做的话,得到的结论会是“注释最多的是用React的站”,而这个结论毫无信息量——它量的是框架,不是人。做完之后才能问出真正的问题:人和工具往页面里写了什么。
顺带说一句,这条尺子我修得挺狼狈。第一版判据是“长度小于等于3且不含字母”,结果把几条真注释误杀了;最后收成正则匹配,只认由斜杠、美元符、方括号、问号、叹号、数字和空白组成的整条注释,再加一份字面量白名单兜底。改完之后随机抽了三个站逐条对,才敢往下走。凡是某个数字大得出奇或者小得出奇,先怀疑尺子,别急着怀疑世界——这条经验在这批数据里又验证了四次,后面还会遇到。
剩下那四千多条,写的是些什么
把4502条按内容打标签,按站统计(一个站有一条算一站,避免大站的重复模板淹没小站):
| 类型 | 站数 | 占比 | 条数 |
|---|---|---|---|
| 第三方服务名(含埋点、评价、客服、同意管理) | 67 | 53.6% | 305 |
| 平台或建站技术名 | 62 | 49.6% | 353 |
| 应用块起止标记 | 52 | 41.6% | 307 |
| 被注释掉的代码 | 21 | 16.8% | 75 |
| 日期戳 | 12 | 9.6% | 17 |
| 源码文件路径 | 12 | 9.6% | 462 |
| 构建标记(版本号、生成时间) | 10 | 8.0% | 28 |
| IE条件注释 | 8 | 6.4% | 92 |
| 开发者留言(TODO、临时方案、警告) | 6 | 4.8% | 6 |
| 内部标识(工单号、实验号) | 3 | 2.4% | 10 |
| ASCII点阵字 | 1 | 0.8% | 1 |
把所有注释文本做一次归一化(把UUID和数字都替换成占位符)再数频次,前几名是这样的:END app block出现307次,/snippets/nav-item-mobile.liquid出现297次,END app snippet226次,not empty119次,Open a new column102次,Content injected dynamically94次。
看出规律了吗——排在最前面的全都是模板系统自动吐出来的。人手写的那部分藏在长尾里,一共也没几条。这跟皮尤研究中心8月20日发布的那份网页AI写作痕迹调查形成了一个有意思的对照:那份研究拿近50万个网页跑检测器,靠破折号频率、牛津逗号、特定用词这些统计特征去推断正文是不是AI写的,最后给出10%这个数,而在有明确发布日期且晚于ChatGPT上线的页面里这个比例升到35%。SEJ对这份研究的解读里还补了一个细节:.com域名的检出率大约是.edu和.gov的十倍。
把两件事并排放着看就很清楚了:正文那一层要靠概率去猜谁写的,注释这一层是白纸黑字。谁装的、什么时候装的、文件叫什么名字,全是明写的,一个统计模型都不需要。
注释能不能看出这个站上次动的是哪一块?
能,而且比你想的准。
宜家的首页在源码里放了四条构建标记,一块构件一条:
build-nr: 20260901.113.1, template-id: 2, ref: 081ee13a7d, collection: fragment-common
build-nr: 20260821.45.1, template-id: 381, ref: 71db453546, collection: startpage
build-nr: 20260820.32.1, template-id: 1, ref: 518ca9df4e, collection: fragment-header
build-nr: 20260707.1249.1,template-id: 27, ref: a9de7f8275, collection: fragment-footer翻译一下:公共片段是9月1日构建的,首页主体8月21日,页头8月20日,页脚停在7月7日。同一个首页,四块拼图的构建日期横跨了8周。这说明它们是分开发布的独立构件,页脚那块从7月初到9月初没有重新构建过。
更精确的一份在theordinary.com(Deciem旗下)。它的静态资源路径写成这样:
/on/demandware.static/Sites-deciem-Site/-/en_CA/v1788273103316/js/main.js中间那个v1788273103316是毫秒级的Unix时间戳,换算过来是2026年9月1日14点31分43秒(UTC)。这是这套静态资源的构建时刻,精确到秒。顺带还能读到站点标识Sites-deciem-Site和语言区en_CA;同一批注释里的另一条路径是apps.bazaarvoice.com/deployments/deciem/main_site/production/en_CA/bv.js,连环境名production都写在地址里。
第三类是带时区的生成时间。graza.co写的是generated: 2026-09-01 12:39:27 -0400,untuckit.com写的是generated: 2026-09-01 12:41:11 -0400。我一开始以为找到了什么共同的服务商,把两条注释周围的上下文都翻出来看了:graza那条挨着的是Shopify的应用块起止标记和一个GDPR同意插件,untuckit那条挨着的是一段标着LOOMI SDK和DO NOT EDIT的代码。结论是它们不是同一个东西生成的,只是恰好都用了带时区的时间戳格式,又恰好都在那个中午重新发布过。差一点就把一个巧合写成了发现——这是本批第二次尺子失效,代价是二十分钟。
第四类更隐蔽:6个站的注释里有形如2026-06-03T13:32:57.1315079Z的时间戳,小数点后7位,这是.NET平台的时间精度特征。fromourplace、getquip、liquiddeath、outdoorvoices四个站的日期都落在2026年6月3日,dreametech是5月11日,snowpeak是5月7日。同一天出现在四个互不相干的品牌站上,指向的是某个共同的应用在那天推过一次更新。
最后一类是化石。avocadogreenmattress.com和magicspoon.com的页脚附近,各有一条一模一样的注释:
Subscription Theme Footer http://rechargepayments.com: v2 Updated: 2017/09/12一个订阅制插件在2017年9月12日更新过的主题版本标记,2026年了还原样躺在两个品牌的首页上。九年。
把这些拼起来,一个不写代码的人也能对一个站的维护节奏做出判断:哪一块在动,哪一块没人管,上一次大改是什么时候。这件事跟sitemap里那个lastmod诚不诚实是同一个问题的两面——一边是站点主动申报的更新时间,一边是它无意中留下的更新时间,而后者不会撒谎。做内容新鲜度那套判断的时候,这是一个免费且诚实的交叉验证源。
注释里的文件名,把整套模板的目录画了出来
源码路径那一类只有12个站命中,条数却有462条,是所有分类里单站密度最高的。原因很简单:模板引擎在渲染每一个片段时都会插一条注释标明这段来自哪个文件,一个首页有几十个片段,就有几十条。
reebok.com那27条把主题的目录结构画得清清楚楚:
/snippets/social-meta-tags.liquid
/snippets/css-variables-color.liquid
/snippets/css-variables-typography.liquid
/snippets/css-variables-layout.liquid
/sections/announcement.liquid
/sections/header.liquid
/snippets/nav-item-mobile.liquid
/snippets/cart-drawer.liquid
/snippets/cart-empty.liquid
/snippets/cart-subtotal.liquid看得出这套主题的设计习惯:section和snippet分两个目录,CSS变量按颜色、字体、布局拆成三份,购物车抽屉、空车状态、小计各占一个文件。对一个想仿照这套结构做主题的人来说,这份目录比任何教程都直接。
sulwhasoo.com那11条更进一步,列出来的是页面地址而不是模板文件:
/spa/introduction/introduction.html /spa/programs/programs.html
/spa/reservation/reservation.html /spa/location/location.html
/flagship/bukchon/index.html /flagship/dosan/index.html
/product/list.html /product/detail.html
/product/add_basket.html /product/basket_option.html水疗预约、门店介绍、北村和岛山两家旗舰店、商品列表与详情、加购物车和选规格——整个站的功能地图,十一行写完。这类信息对做站点结构分析的人价值极高,因为它给的是内部命名,不是你从导航上推测出来的命名。
这一块和竞品逆向那套方法接得很紧。传统做法要爬全站、聚类URL、猜模板边界,忙半天得到一个近似的结构图;而这12个站直接把内部路径印在首页上了。方法上的启示是:做竞品结构分析时,先搜一遍对方源码里的注释,可能比爬两千个URL更快。
供应商名单为什么在注释里比在脚本里更全?
52个站(41.6%)的首页里有成对的应用块起止标记,写法是这样的:
<!-- BEGIN app block: shopify://apps/klaviyo-email-marketing-sms/blocks/klaviyo-onsite-embed/2632fe16-... -->
...
<!-- END app block -->这是Shopify的主题应用扩展机制的产物:商家在后台勾选启用某个应用,主题渲染时就在对应位置插一段代码,并且自动加上起止注释,方便调试时定位。这套设计本身很合理,问题在于注释里带着应用的完整标识符。
52个站一共列出108款不同的应用。装机量前十二名:
| 应用 | 站数 | 干什么的 |
|---|---|---|
| klaviyo-email-marketing-sms | 41 | 邮件与短信营销 |
| elevar-conversion-tracking | 26 | 转化数据层 |
| attentive | 13 | 短信营销 |
| yotpo-product-reviews | 12 | 商品评价 |
| triplewhale | 10 | 归因分析 |
| gorgias-live-chat-helpdesk | 10 | 客服工单 |
| microsoft-clarity | 9 | 会话录制 |
| okendo | 8 | 评价与UGC |
| impact-com | 7 | 联盟营销 |
| pandectes-gdpr | 7 | 同意管理 |
| consentmo-gdpr | 7 | 同意管理 |
| onetrust-consent-management | 6 | 同意管理 |
为什么说这比看脚本更全?因为很多应用的实际请求要等用户交互才发出,或者被同意管理拦在前面,你在网络面板里蹲半天也不一定看得到。而注释是渲染时就写死的,不管那个应用的脚本最后跑没跑,它的名字都在源码里。上周测第三方域名依赖那次用的是抓请求的办法,两种方法各有各的盲区,合起来才是完整的一张表;而第三方脚本自己会悄悄变这件事,也让“今天抓到的请求”这个口径天然不稳定,注释反而更适合做基线。
装得最多的三个站:misen.com 14款,beistravel.com 13款,jackery.com 12款。清单本身也有信息量。misen那份里有trynow-try-before-you-buy(先试后买)和prettydamnquick-pdq(结账加速),说明它把力气花在转化率而不是流量上;jackery那份里有zipchat-ai-chatbot和noumena-attribution,还有一个叫jk-seoai2的——前缀是品牌名缩写,后面跟着版本号2,这大概率是自研或定制的SEO工具第二版。beistravel那份里同样有一个playbook-beis-travel,名字里直接带着品牌名。
换句话说,一个竞品分析师不需要任何工具,看一眼源码注释就知道对手的技术采购清单,连自研项目的代号都送上门了。这跟用浏览器扩展去检测网站技术栈比起来,准确度只高不低,因为它不靠指纹推断,是原文照抄。
被注释掉的那些代码,浏览器还下不下载?
21个站(16.8%)的注释里包着完整的HTML标签。这一类值得单独拎出来,因为它涉及一个常见的误解。
先把结论说清楚:被注释掉的代码,浏览器不会执行,也不会去下载里面引用的资源。预加载扫描器在遇到注释时会跳过,不会对里面那个script的src发起请求。所以“注释掉的追踪脚本还在偷偷发请求”这种担心,是不成立的。
但它仍然要传输。整段注释连同里面的代码一起,按字节走网络、进缓存、算进HTML体积。这就和页面体积那件事接上了——那次实测里有4个站的商品链接因为文档太大被截断在抓取上限之外。注释不是主犯,但它是那种完全没有理由存在的重量。
被注释掉的代码里都有谁?从里面提取外链域名,得到的名单是:sulwhasoo的三个地区站地址、两个站注释掉的Shopify官方“powered by”推广链接、joolz的产品页地址、Stripe的支付脚本、Facebook和Instagram的分享按钮、一个叫browsehappy.com的浏览器升级提示页(那是IE时代的产物)、还有ninebotapp.wjx.cn和cjs.ltwebstatic.com这种一看就是内部或区域服务的地址。
这些东西讲的是同一个故事:某年某月有人做了一次改版,把不要的模块用注释包起来先留着,想着下个版本再删。然后就没有下个版本了。
顺便厘清一个容易混的边界:注释掉的内容和“隐藏内容”是两码事。用CSS藏起来的文字仍然在文档树里,机器读得到,判定规则也复杂得多;而注释根本不进文档树。之前那次隐藏内容的实测里排过十六种藏法,注释不在其中任何一种里面——它不是藏,是根本没有进入那个世界。
内部工单号是怎么跑到首页上的?
这是全批数据里我最没想到的一块。3个站(2.4%)的首页注释里,直接印着内部系统的编号。
liquiddeath.com有两条:
FOXH-171: Live region for screen reader announcements - unique ID to avoid Rebuy conflicts
FOXH-137: Live region for free shipping progress announcementsFOXH是项目前缀,171和137是工单号,后面那句话说明这两处改动是为了给屏幕阅读器加实时播报区域,并且要避开某个购物车插件的冲突。写得很专业——这本来是提交信息该待的地方。
mackweldon.com有四条,全部以@experiment开头:
@experiment ECOM-3951 added view toggle listener and passed plpImageView
@experiment ECOM-3975 added buttonMetric method calls to click handlersECOM-3951和ECOM-3975是两个正在跑的实验。前一个在类目页加了视图切换,后一个在按钮点击上加了指标埋点。这等于告诉所有人:这个站现在正在测两件事,分别是什么。
thirdlove.com有一条Yotpo Reviews SEO Page loader (TLDEV-510),TLDEV是它的开发项目前缀。
再往下一层是开发者留言,6个站各有一条,每一条都值得读:
| 站点 | 注释原文 | 它说明了什么 |
|---|---|---|
| dreametech.com | TODO use theme settings from the variables | 硬编码了本该走主题配置的值 |
| fahertybrand.com | Temporary: re-enable Yottaa loader for A/B speed validation | 为了做速度对比,临时把一个加速器又打开了 |
| getquip.com | TODO: Shoplift Test | 某个A/B测试工具的接入还没做完 |
| lookfantastic.com | TODO: deprecate customFont (singular) | 一个字体字段要废弃但还没废 |
| misen.com | ADDED AUTOMATICALLY - PLEASE DO NOT REMOVE OR MODIFY WHILE SPEEDSIZE'S APP IS ENABLED! | 图片优化服务的自我保护声明 |
| stanley1913.com | WARNING: The JSON data in #block-data is directly coupled to the CountdownModule component. Do not remove or alter the structure of this JSON | 倒计时组件与数据结构的耦合警告 |
mackweldon还有一条更长的,把一个前端坑完整写了下来:某个加载指示卡片必须用x-if不能用x-show,因为用后者时元素虽然display为none却仍留在文档树里,轮播组件照样把它算成一张卡,并给每一张卡都盖上间距。这是一段合格的排障笔记,只不过发布地点选在了首页。
严格说,这些都不算安全事件。工单号本身不能登录任何系统,TODO也不会泄露密钥。但它们合在一起构成一个信息面:这个团队用什么工具管任务、项目怎么分前缀、现在正在测什么、哪里有已知的债。对一个想挖竞品动向的人来说,这比大多数付费情报工具给的东西还要新鲜。
保哥去年接手过一个换过两拨外包的独立站,第一件事不是看GA也不是看GSC,是把首页源码从头拉到尾读了一遍。那份注释里留着上一任团队用的任务系统前缀和三个被注释掉的追踪脚本,顺着前缀去问甲方,把两年前的需求文档要了回来——比对着代码猜快多了。接手一个来历不明的站,注释是成本最低的一份交接材料。
2026年了,还有谁在页面里留IE条件注释
8个站,92条。分布是这样的:swarovski.com 66条,magicspoon.com 6条,casetify.com 5条,aloyoga.com和bellroy.com各4条,gymshark.com和theordinary.com各3条,uniqlo.com 1条。
条件注释是IE独有的一套语法,写成<!--[if lt IE 9]>...<![endif]-->,让IE按版本号加载不同的代码,其他浏览器一律当普通注释跳过。微软从IE10起就不再支持它,而IE本身在2022年6月已经停止服务。也就是说,这92条代码分支从四年前起就再没有任何一个浏览器会走进去。
casetify那5条尤其经典,判断的是IE7和IE8:
<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]-->
<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]-->
<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]-->这是HTML5 Boilerplate那套模板的经典写法,流行于2011年前后。它今天出现在一个卖手机壳的站上,唯一的作用是每次请求多传几百个字节,外加提醒你这套主题的基础模板是哪一年选的。这跟上次数过时HTML标签时看到的规律一致:老代码不会自己消失,它只会随着平台换代换一批花样继续待着。
说到casetify,它还贡献了全批唯一一条故意写给人看的注释——一幅ASCII点阵拼出来的“We are hiring”,下面跟着一句“Dear rule breakers, questioners, straight-A students who skipped class: We want you.”,再附一个招聘页链接。4502条注释里,只有这一条知道自己会被人看到,并且为此做了准备。剩下4501条,都是无意留下的。
这些字节到底该不该删?
到这里该给判断了。我的看法是分三类处理,别一刀切。
第一类,该删,而且现在就能删:IE条件注释、被注释掉的旧代码、九年前的插件版本标记。这些没有任何一个当代浏览器或爬虫需要,删掉零风险。删之前只有一件事要确认:那段被注释掉的代码是不是有人准备恢复。问一句比猜半天快。
第二类,该改口径,不是该删:内部工单号、实验编号、TODO、带内部路径的排障笔记。这些内容本身是有价值的工程记录,问题只在于它们出现的位置。正确的地方是提交信息、代码仓库里的注释、工单本身——那些地方的注释在构建阶段就会被剥掉,不会跟着HTML走到公网上。所以这一类的修法不是让工程师少写注释,是把构建流程里那道剥离注释的工序打开。压缩与混淆那类工具基本都带这个开关,只是默认状态五花八门,得逐个确认。
第三类,别动:框架的水合标记,以及应用块的起止标记。前者删了页面会坏,后者是平台机制的一部分、你也删不掉。它们确实携带信息,但代价和收益不成比例。真在意供应商清单暴露的,该做的是精简应用数量本身,而不是跟注释较劲。
那么第一类和第二类值多少钱?看占比:中位数的站,有内容的注释是35条,字节量在1到2KB之间;最重的几个站在4%上下。对绝大多数站,这不是性能问题,删它的理由是干净,不是快。真正到了要算抓取预算里那些没被压缩的字节那一步的大站,注释才值得进优化清单,而且排在压缩配置和模板冗余后面。想省字节,整体压缩HTML的收益比单独删注释大一个数量级。
还有一个反方向的考虑:注释在调试时是真有用的。Shopify那套起止标记,排查“这段代码是哪个应用插进来的”时能省半小时。所以合理的目标不是零注释,是生产环境里只留下有明确用途、且不含内部信息的那些。
为什么这件事长期没人做?因为它不属于任何一个岗位。前端关心的是构建产物能不能跑,SEO关心的是文档树里有什么,安全关心的是有没有可利用的入口,性能关心的是资源加载。注释一样都不沾,于是它在四张检查表的缝里活了下来。要让它被处理,只能把它明确挂到某一张表上——挂哪张不重要,挂上就行。
自己站上的注释,十分钟怎么查一遍
不用装工具。浏览器打开自己的首页,按下面四步走。
第一步,数总量。在控制台里跑一段就够了:
fetch(location.href).then(r=>r.text()).then(h=>{
const m = h.match(/<!--[\s\S]*?-->/g) || [];
const real = m.filter(c => !/^<!--[\s\/\$\?\!\[\]\-~\d]*-->$/.test(c));
const b = real.reduce((a,c)=>a+c.length,0);
console.log('总条数', m.length, '有内容', real.length,
'字节', b, '占比', (b/h.length*100).toFixed(2)+'%');
console.log(real.map(c=>c.slice(0,120)).join('\n'));
});注意这里用的是fetch拿原始HTML,不是读文档树。原因前面说过:两个口径的数字对不上,而你要查的是发出去的那份文档。抓取与渲染分几步这件事在这里同样适用——搞混了阶段,量出来的东西就不是你以为的那个。
第二步,搜四类关键词。把源码搜一遍这几个:TODO、FIXME、staging、localhost,再加上你们公司工单系统的项目前缀(比如ECOM-这种两到六个大写字母加短横线的形式)。命中任何一条,都属于上面说的第二类,要往构建流程上改,不是手工删完了事。
第三步,看有没有日期。搜20开头的年份,以及build、generated、version这几个词。找到了不一定要删,但你得知道它在那儿,也得知道它暴露的是哪一块的构建时间。如果某个模块的日期老得让你自己都吃惊,那说明的不是注释的问题,是那个模块很久没人碰了。
第四步,把这一步接进上线检查。大部分构建工具都有剥离HTML注释的选项,但默认往往是关的;而且很多模板引擎自己的注释语法(比如Liquid的{% comment %}、Twig的{# #})在渲染阶段就不输出,跟HTML注释是两回事,不要混为一谈。可靠的做法是在部署前对产出的HTML跑一次上面那段检查,把“有内容注释的字节数”当成一个门槛值盯着,超了就报警。这跟把服务器层的治理项固化成检查清单是同一个思路:一次性清理没意义,能守住的才叫治理。
最后提一句边界:这套检查只覆盖首页。商品页、类目页、结账页各有各的模板,注释情况可能完全不同——尤其是结账相关的页面,那里的第三方脚本最多,也最可能留下埋点相关的内部标记,做支付页脚本策略那一层治理时可以顺手一起看。查完首页把这三类页各抽一个跑一遍,成本很低。
常见问题解答
HTML注释会不会影响SEO排名?
不会直接影响。搜索引擎的解析器和浏览器一样跳过注释内容,注释里的关键词不参与任何相关性判断——想靠在注释里堆词做排名,二十年前就没用了。它唯一可能产生的间接影响是字节:如果你的页面已经大到接近抓取上限,注释和其他冗余一起把重要内容挤到了后面,那就是实打实的损失。判断标准很简单,看注释字节占HTML的比例,超过2%再考虑,低于1%不用管。
被注释掉的script标签,浏览器会不会还去下载那个文件?
不会。预加载扫描器在扫描过程中会跳过注释区段,不会对里面的src发起请求。所以注释掉一个追踪脚本是有效的禁用手段,它确实不再执行、不再联网。唯一的代价是那段代码仍然占字节、仍然进传输和缓存,并且把你曾经用过什么告诉了所有看源码的人。
为什么我的页面里有几百条空注释,删不掉?
如果你用的是React、Vue、Astro这类框架的服务端渲染或流式渲染,那些形如<!--$?-->、<!--[-->、<!---->的空注释是水合标记,客户端脚本要靠它们定位服务端已经渲染好的片段。删了页面会出问题。本次实测里它们占了全部注释条数的55.8%,属于正常现象,不用管。
Shopify的app block注释能不能关掉?
不能。那是平台在渲染主题应用扩展时自动加的,商家侧没有开关。要减少这类注释,唯一的办法是卸载不再使用的应用——顺带也能减少脚本数量和请求数,那个收益比省几百字节大得多。本次125个站里有52个带这类注释,装得最多的一个站列出了14款应用。
怎么判断一条注释是自动生成的还是人写的?
三个特征:自动生成的注释高度重复(同一句话在一个页面里出现几十次)、结构工整(键值对形式,或者成对的BEGIN/END)、常带UUID或版本号。人写的注释相反——只出现一次,句子不完整,经常有第一人称和口语。实操上不必精确分类,直接搜TODO、FIXME、工单前缀这几个关键词,命中的基本都是人写的。
把注释里的内部信息删掉,会不会影响团队协作?
不会,因为该删的不是注释本身,是它出现在生产环境HTML里这件事。同样一句话写在代码仓库、提交记录或者工单里,团队照样看得到,检索还更方便。真正要改的是构建流程:让源码里的注释在打包时被剥离,而不是要求工程师写代码时少说话——后一种要求既不合理也守不住。
竞争对手真的会看这些注释吗?
做竞品技术分析的人会,而且这是他们的常规动作之一,成本极低。本次实测里能读到的东西包括:对方装了哪108款第三方应用、自研工具叫什么代号、页面各构件的构建日期、主题的目录结构、正在跑哪几个实验。这些信息单条看都不致命,合起来能拼出一份相当完整的对手技术画像。当然反过来也成立——你也可以这么看别人。
这次的数字能不能直接套到我的站上?
不能。样本是131个海外品牌电商站里取到的125个,平台以Shopify为主,所以应用块注释的占比明显偏高。如果你的站是WordPress或者自建,注释的构成会完全不同,通常是主题和插件留下的版本标记更多。数字不能照搬,能照搬的是方法:先剔除框架水合标记,再按内容分类,最后只处理第一类和第二类。
权威参考资料
本文标题:《HTML注释没人读,它却记着你的构建日期和供应商名单》
本文链接:https://zhangwenbao.com/html-comment-internal-traces-audit.html
版权声明:本文原创,转载与引用请注明作者与原文链接。许可协议: CC BY 4.0
← 上一篇
48个站对手机系统声明我没有App,这句话不是他们写的下一篇 →
没有了