Skip to content

[perf] adblock 状态变更失效粒度过粗:任意 mutation 触发全量重解析 + trie 重建 + DNS 缓存清空 #224

Description

@flyhigher139

来源:2026-09-28 性能复审(基于 master@b2ac639),#199/#213/#215/#222 新增代码的审计发现。

问题

src-tauri/src/commands/adblock.rs:294-343 的 persist_and_reload 被所有 mutator 调用,包括完全不影响规则集的:

无关 mutator 位置
set_ad_block_refresh_interval adblock.rs:1257
set_ad_block_auto_refresh_enabled adblock.rs:1285
set_ad_block_source_rules_limit_override adblock.rs:1606(注释自己写着 "Rule sets don't change here")
reorder_ad_block_source_impl(#215 排序) adblock.rs:1568

每一次都执行完整的失效链:

  1. classify_rules(adblock.rs:349-383)重新读盘 + 解析全部 enabled source 的缓存文件(单源可达 50 万域名),逐域名 to_lowercase() 分配;
  2. AdBlockEngine::rebuild(mhost-dns/src/adblock.rs:164-185)重建 3 棵 trie;
  3. reload_ad_block_rules(server.rs:361-372)清空整个 DNS LRU 缓存 → 刷新后上游查询风暴(最多 cache_size=1000 条/次)。

即:拖拽一下 source 排序 = O(全部规则) 的 2 次解析 + 全量 trie 重建 + 缓存清空。单 source 手动刷新(adblock.rs:1704-1719)同样触发全量 classify + 全 trie 重建 + LRU 清空。

影响

用户感知为 adblock 页面每次点击卡顿(mutation 在 spawn_blocking 中跑,不阻塞查询,但延迟明显),以及刷新后短时间的 DNS 解析突刺。

建议修复

  1. 纯设置类变更(interval / auto_refresh / rules_limit_override / reorder)跳过 reload——它们不改变规则集;reorder 只影响优先级时可考虑仅调整 trie 遍历顺序或重建优先级索引;
  2. classify 结果按 source 缓存(source 内容 hash 不变则跳过重解析);
  3. trie 支持按 dirty source 增量重建,而非每次全量;
  4. 规则集未变时不清 DNS LRU(或只清受影响域名)。

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    dns-modeDNS mode (本地 DNS server) 相关问题perfPerformance issue

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions