技术解读

以下内容由 GitRead 中文社区 编辑团队基于项目 README 与官方资料整理, 结合中文开发者的常见使用场景补充技术选型建议。具体以项目官方文档为准。

wBlock 深度技术分析:把 75 万条规则塞进 Safari 的工程取舍

项目背景与痛点

iOS 和 iPadOS 上的广告拦截一直是个尴尬领域。系统层面不给代理权限,App Store 又不允许把完整的 uBlock Origin 搬进来——你只能走 Safari Content Blocker 这条路。Apple 给出的模型很朴素:把规则编译成一份声明式 JSON,交给 Safari 的 WebKit 在渲染管线里做匹配,扩展本身不参与每一次请求。

这个模型的好处是快、省电,不需要常驻进程;代价是规则表达能力受限、单份规则文件体积有硬性上限、正则语法被裁剪得只剩一个子集。商业产品(AdGuard、1Blocker)大多选择订阅制来覆盖维护成本,于是社区长期缺一个“规则拉满、免费、开源”的选项。wBlock 的定位正是这条空档:用工程手段逼近声明式规则的上限,同时不向用户收订阅费。

核心技术揭秘

wBlock 的技术含量不在“能拦截广告”,而在“怎么把 Adblock Plus 生态的语法翻译成 Safari 能消化、又不会拖垮 WebKit 的形式”。这不是简单的字段映射,而是一条需要反复裁剪的编译流水线。

graph TD A[上游过滤列表:EasyList / 自定义订阅] --> B[下载与本地缓存] B --> C[规则解析器] C --> D{"规则分类"} D -->|"网络请求拦截"| E[转译为 Safari trigger 与 action] D -->|"外观过滤"| F[转译为 css-display-none 规则] D -->|"脚本与样式注入"| G[交由 Web Extension 注入引擎] E --> H[规则分片与体积裁剪] F --> H H --> I[多份 Content Blocker JSON] I --> J[写入 App Group 共享容器] J --> K[Safari 加载各拦截器] G --> K

第一层是语法降维。 ABP 语法里的 $third-party、$domain=、##.ad-banner 各自对应 Safari JSON 里不同的 trigger / action 组合:域名限定拆成 if-domain 与 unless-domain,资源类型映射到 resource-type 枚举,元素隐藏规则只能压成 css-display-none 加 selector 数组。凡是 Safari 表达不了的(比如脚本注入类规则、复杂的重定向),必须识别并丢弃,否则整份 JSON 会被 WebKit 拒绝加载——一个语法错误就足以让整片规则失效,这是最容易踩的坑。

第二层是体积与复杂度裁剪。 单份 Content Blocker 的规则数与文件体积都有上限,75 万条规则显然不可能塞进一个容器。合理解法是把规则集切成多份 Content Blocker Extension Target,各自独立编译、独立注册,Safari 并行加载。副作用是规则去重与跨分片的一致性变复杂:同一条域名限定规则不能既在 A 片又在 B 片重复生效。

第三层是正则的性能红线。 Safari 对 url-filter 的正则复杂度有隐性约束,含大量回溯分支的表达式要么被静默丢弃,要么直接拖慢页面首屏。成熟的编译器会做正则合并与简化,把 .* 泛滥的写法收敛成前后缀匹配,这一步的质量直接决定了“750,000 条规则”到底是真实战力还是账面上的数字。

第四层是脚本与样式的注入通道。 userscripts / userstyles 走不了声明式规则,需要 Safari Web Extension(manifest v3)的 content script 通道,在页面上下文里做 DOM 操作。这意味着 wBlock 大概率是双引擎并存:声明式规则处理绝大多数网络请求,Web Extension 补足声明式模型够不着的部分,两条链路在同一个 App Group 容器里共享规则与配置。

功能亮点与差异

  • 规则量级:75 万条的上限,比多数同类产品高一到两个数量级,且完全免费。这背后是分片编译能力,而非单纯堆数量。
  • 自定义过滤列表:允许直接贴 EasyList 生态的订阅地址,而不是只能在预设开关里打勾,这对重度用户是刚需。
  • userscripts / userstyles:把“拦截器”扩展成了轻量的页面改造工具,接近桌面端扩展的使用心智。
  • 多平台统一:macOS、iOS、iPadOS、visionOS 一套代码基线,visionOS 的支持在同类项目里几乎绝迹,说明作者把多平台 target 当作一等公民在维护。

应用场景与落地建议

适合三类人:对隐私敏感、不愿为拦截付费的普通用户;需要把公司内网或特定站点的元素隐藏规则固化下来的团队;以及把 wBlock 当作规则编译参考实现来研究 Safari 扩展边界的开发者。

落地时有几点值得注意:

  1. 规则数量与首屏延迟是负相关的。开启全部列表后,建议实测目标站点的加载曲线,必要时按站点裁剪订阅。
  2. 自定义列表要当成依赖来管。上游列表随时可能引入 Safari 无法编译的语法,一旦编译失败,需要能快速回滚到上一份可用规则。
  3. 不要指望它替代网络层拦截。App 内 WebView、原生客户端的广告它管不到,这是 Content Blocker 模型的天然边界。
  4. 脚本注入属于高权限面,第三方 userscript 务必审阅来源,扩展本身无法替你兜底。

综合评价

优点:规则规模与免费策略的组合在 Safari 生态里相当少见;多平台覆盖完整;双引擎架构在声明式模型的硬约束下做出了尽可能大的表达空间;开源意味着规则编译逻辑可审计,比闭源商业产品更值得信任。

缺点:声明式模型的天花板摆在那里,视频贴片广告、部分反拦截站点它无能为力;大规则集带来的编译耗时与更新链路比轻量竞品更重;相比 uBlock Origin 的完整能力,它终究是“在 Apple 画好的圈里做到最好”,而不是突破这个圈。

一句话总结:它不是最强的广告拦截器,但很可能是 Safari 平台约束下,免费方案里工程完成度最高的那一个。

关于

GitHub 原始描述(英文)

Free, open-source Safari ad blocker for macOS, iOS, iPadOS and visionOS. Up to 750,000 rules, custom filter lists, userscripts and userstyles. No subscription.

描述取自 GitHub 官方 API,保持仓库作者书写的原文。

简要分析

热度分
3371
价值分
1952
活跃状态
活跃

语言占比

C
CSS
HTML
JavaScript
Objective-C
Python
Rust
Shell
Swift
TypeScript

Release