Skip to content

perf: (Codex) 优化 RuntimeService.getScriptsForTab#1404

Draft
cyfung1031 wants to merge 18 commits into
mainfrom
perf/getScriptsForTab
Draft

perf: (Codex) 优化 RuntimeService.getScriptsForTab#1404
cyfung1031 wants to merge 18 commits into
mainfrom
perf/getScriptsForTab

Conversation

@cyfung1031
Copy link
Copy Markdown
Collaborator

@cyfung1031 cyfung1031 commented May 6, 2026

Checklist / 检查清单

  • Fixes mentioned issues / 修复已提及的问题
  • Code reviewed by human / 代码通过人工检查
  • Changes tested / 已完成测试

Description / 描述

本 PR 优化 RuntimeService.getScriptsForTab 的页面加载路径,并调整 Popup 对 disabled 脚本的匹配方式,减少 service worker 初始化和页面加载时的重复计算。同时修复了命名 @resource 使用 file:/// 本地资源时未按解析后的路径刷新资源的问题。

背景

原来的 getScriptsForTab 在每次页面加载时都会重新读取或解析脚本运行所需的多项静态资料,例如 compiled resource、resource、脚本代码、metadata、userConfig 和 URL match 规则。实际页面加载时经常只有脚本 value 需要保持最新,脚本代码、metadata、match 规则和 resource 等静态资料通常不会变化。

另外,service worker 初始化阶段原本会处理全部普通脚本,包括 disabled 脚本。对于安装脚本较多、但实际启用脚本较少的场景,这会带来不必要的启动成本。

修改内容

1. 为页面加载增加 service worker 内存缓存

新增 page-load cache,用于缓存单个脚本在页面加载时需要复用的静态资料:

  • scriptUrlPatterns / originalUrlPatterns
  • resource
  • code
  • metadataStr
  • userConfigStr
  • userConfig
  • 本地 file:/// resource 的 hash 快照

这些缓存只存在于当前 service worker 生命周期内,不写入持久化存储,也不改变 getScriptsForTab 的输入输出结构。

2. getScriptsForTab 复用静态资料,只刷新动态 value

新的页面加载流程会先通过 matcher 找到当前 URL 匹配的 enabled 脚本,再按脚本缓存 key 判断 page-load cache 是否可复用。

  • cache 命中时,复用 metadata、userConfig、resource、URL patterns 和 code 等静态资料;
  • 每次页面加载仍然重新读取脚本 value,保证 GM_setValue 等 value 更新可以及时反映;
  • cache 未命中时才重新构建 compiled resource、读取 resource、读取脚本代码并解析 metadata / userConfig。

cache key 覆盖会影响运行静态资料的字段,包括 metadataoriginalMetadataselfMetadatastatustypeupdatetime

3. 保持脚本执行顺序稳定

getScriptsForTab 现在会先按 matcher 返回顺序建立结果槽位,再将 cache hit 和 cache miss 的脚本回填到对应位置,避免异步处理 cache miss 时改变脚本执行顺序。

4. 更完整的 runtime cache 清理

新增统一的 runtime cache 清理逻辑,在脚本安装、更新、删除、启用或停用等场景中清理相关缓存,避免复用旧的 page-load cache、code cache 或 matcher pattern cache。

5. 保留 file:/// 本地资源热更新能力

page-load cache 会记录本地 file:/// resource 的 hash。页面加载时如果发现本地资源内容变化,会更新:

  • page-load cache 中的 resource;
  • 当前返回给 content / inject 的 resource;
  • 已注册 userScript 使用的注入代码。

同时修复 ResourceService.getScriptResources 中命名 @resource 的本地资源判断逻辑:现在使用解析后的 path 判断 file:///,而不是原始 uri,保证 @resource name file:///... 能正确触发本地文件刷新。

6. service worker 初始化只预热 enabled 普通脚本

waitInit() 改为:

  • 不再通过 compiledResourceDAO.all() 读取全部 compiled resource;
  • 使用 CompiledResourceNamespace 标记判断是否需要清理旧注册;
  • 只为 SCRIPT_TYPE_NORMAL && SCRIPT_STATUS_ENABLE 的脚本建立 matcher / compiled resource;
  • disabled 普通脚本不再在 service worker 启动阶段预热。

这样可以减少“安装大量脚本但只启用少量脚本”时的 service worker 启动开销。

7. Popup disabled 脚本匹配改为按需构建

Popup 获取当前页面脚本匹配结果时,改为调用专用入口:

getPopupPageScriptMatchingResultByUrl(url)

该入口会在 Popup 首次请求时按需构建 disabled matcher,后续 Popup 请求复用该 matcher。普通页面加载路径只维护 enabled matcher,不再被 disabled 脚本拖慢。

当脚本安装、更新、删除、启用、停用或排序变化时,会同步清理或更新相关 matcher / sorter 缓存,保证 Popup 结果仍能按 sort 顺序返回,并正确保留 effective / non-effective 状态。

8. 类型收紧

新增 RequireField<T, K> 工具类型,并将部分 userScripts 注册结构收紧为必须包含 js 字段,避免内部构造注册脚本时出现类型约束不明确的问题。

测试覆盖

本 PR 补充和调整了 runtime / resource 单元测试,覆盖:

  • page-load cache 命中时复用静态资料;
  • 每次页面加载仍然刷新 script value;
  • 全局停用、黑名单、无匹配脚本时直接返回 null
  • run-innoframesinject-into 等过滤和拆分逻辑;
  • cache hit / miss 混合时保持脚本顺序;
  • 脚本更新时间变化后重建 page-load cache;
  • file:/// resource 变化后更新缓存、返回结果和已注册 userScript;
  • 命名 @resource name file:///... 会立即刷新本地文件;
  • Popup 按需匹配 disabled 脚本,并复用 disabled matcher;
  • runtime cache 清理后 Popup disabled matcher 会重建;
  • Popup 合并 enabled / disabled 匹配结果,并保留 effective / non-effective 状态;
  • disabled 脚本按 sort 顺序返回;
  • 非普通脚本、enabled 脚本、无匹配规则的 disabled 脚本不会进入 disabled 扫描结果。

兼容性

  • 不改变 getScriptsForTab 的输入输出结构;
  • 不改变 content / inject 接收到的数据格式;
  • 不改变持久化数据结构;
  • 新增缓存均为 service worker 内存缓存,service worker 重启后会按现有流程重新建立。

Screenshots / 截图

@cyfung1031 cyfung1031 changed the title 优化 RuntimeService.getScriptsForTab (Codex) 优化 RuntimeService.getScriptsForTab May 6, 2026
@CodFrm
Copy link
Copy Markdown
Member

CodFrm commented May 6, 2026

越来越激进了,我觉得要做好自动化测试

@cyfung1031
Copy link
Copy Markdown
Collaborator Author

越来越激进了,我觉得要做好自动化测试

这个改动大。先放在这里做 draft PR
( 没 AI 根本改不动。尝试过手动改但很痛苦放弃了 )

会加测试

@cyfung1031 cyfung1031 changed the base branch from main to release/v1.4 May 8, 2026 21:50
@cyfung1031 cyfung1031 changed the title (Codex) 优化 RuntimeService.getScriptsForTab [1.4] (Codex) 优化 RuntimeService.getScriptsForTab May 8, 2026
@cyfung1031 cyfung1031 marked this pull request as ready for review May 8, 2026 21:53
@cyfung1031 cyfung1031 marked this pull request as draft May 9, 2026 01:46
@cyfung1031 cyfung1031 changed the base branch from release/v1.4 to main May 9, 2026 02:01
@cyfung1031 cyfung1031 changed the base branch from main to release/v1.4 May 9, 2026 02:03
@cyfung1031 cyfung1031 changed the base branch from release/v1.4 to main May 9, 2026 12:39
@cyfung1031 cyfung1031 changed the base branch from main to release/v1.4 May 9, 2026 12:40
@cyfung1031 cyfung1031 changed the base branch from release/v1.4 to main May 10, 2026 07:17
@cyfung1031 cyfung1031 marked this pull request as ready for review May 10, 2026 12:12
@cyfung1031 cyfung1031 changed the base branch from main to release/v1.4 May 10, 2026 12:13
@cyfung1031 cyfung1031 changed the title [1.4] (Codex) 优化 RuntimeService.getScriptsForTab perf: (Codex) 优化 RuntimeService.getScriptsForTab May 10, 2026
@cyfung1031 cyfung1031 changed the base branch from release/v1.4 to main May 10, 2026 12:15
@cyfung1031 cyfung1031 marked this pull request as draft May 11, 2026 03:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants