Skip to content

(Codex) 优化 RuntimeService.getScriptsForTab#1404

Draft
cyfung1031 wants to merge 2 commits intomainfrom
perf/getScriptsForTab
Draft

(Codex) 优化 RuntimeService.getScriptsForTab#1404
cyfung1031 wants to merge 2 commits intomainfrom
perf/getScriptsForTab

Conversation

@cyfung1031
Copy link
Copy Markdown
Collaborator

Checklist / 检查清单

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

Description / 描述

PR 描述

本 PR 优化 RuntimeService.getScriptsForTab 及相关初始化流程,目标是减少页面加载时和 service worker 首次启动时对脚本运行资料的重复计算,尤其针对“安装脚本很多,但实际启用脚本很少”的场景。

背景与问题

原本 getScriptsForTab 每次页面加载都会重新执行较多固定成本操作,包括读取脚本、读取 compiled resource、加载 resource、读取并解析 script code、解析 metadata/userConfig 等。

但这些资料大部分并不会因为 GM_setValue / value 更新而改变。常见情况下,脚本代码、metadata、resource、match 规则都没有变化,只有 value 变化。此时重复计算静态资料没有必要。

另外,原本 service worker 初始化时会处理全部普通脚本,包括 disabled 脚本。如果用户安装了大量脚本,例如 300 个脚本但只启用 30 个,初始化仍可能为大量 disabled 脚本建立 compiled resource / matcher cache,启动成本过高。

修改内容

  1. 为 page load 增加 service worker 生命周期内缓存

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

  • scriptUrlPatterns
  • originalUrlPatterns
  • resource
  • metadataStr
  • userConfigStr
  • userConfig
  • code

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

  1. getScriptsForTab 只刷新动态 value

重写后的 getScriptsForTab 会先根据 URL 匹配 enabled 脚本,然后检查脚本静态资料 cache 是否可用。

如果 cache 命中:

  • 复用 metadata / userConfig / resource / URL patterns / code
  • 只重新读取当前 script value

如果 cache 未命中:

  • 读取或生成 compiled resource
  • 加载 resource
  • 读取 code
  • 解析 metadataStr / userConfigStr / userConfig
  • 写入 page-load cache

这样 value-only 更新不会导致整套静态资料重新计算。

  1. 正确处理 cache 失效

cache key 基于会影响运行静态资料的脚本因素生成,包括:

  • metadata
  • originalMetadata
  • selfMetadata
  • status
  • type
  • updatetime

脚本安装、更新、删除时会清理相关 cache。启用/停用时会清理 page-load cache,避免状态变化后复用旧资料。

  1. 保留脚本执行顺序

getScriptsForTab 中 cache hit 和 cache miss 混合出现时,仍按 URL matcher 返回的顺序回填脚本列表,避免因为 cache miss 后追加而改变脚本执行顺序。

  1. 本地 file:/// resource 仍保持热更新

对于 file:/// resource,页面加载时仍会检查资源内容是否变化。

如果本地资源变化:

  • 更新 runtime cache 中的 resource
  • 使用 cache 中保存的原始 code 重新编译注入代码
  • 更新已注册的 userScript

因此优化不会破坏本地资源开发场景。

  1. service worker 初始化只预热 enabled 脚本

调整 waitInit()

  • 不再 compiledResourceDAO.all() 读取全部 compiled resource
  • 改用轻量的 compiledResourceNamespace flag 判断是否需要清理旧注册
  • 只对 SCRIPT_TYPE_NORMAL && SCRIPT_STATUS_ENABLE 的脚本建立 matcher / compiled resource

这样安装大量 disabled 脚本时,不会在 service worker 启动阶段为它们建立运行 cache。

  1. Popup 的 disabled 匹配改为按需计算

Popup 需要显示“当前页面匹配但 disabled 的脚本”时,不再依赖初始化时预先建立的 scriptMatchDisable cache。

新增按需查询流程:

  • 正常页面加载路径只使用 enabled matcher
  • Popup 请求时临时扫描 disabled 普通脚本
  • 临时计算当前 URL 是否匹配
  • 不写入 page-load cache
  • 不影响页面加载性能

兼容性

本 PR 不修改 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 根本改不动。尝试过手动改但很痛苦放弃了 )

会加测试

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