Conversation
getAllScripts 整体放在 CLOUD_SYNC_QUEUE_KEY 里执行,网盘推送慢或重试时 脚本列表与编辑页会长时间空白。只把 sort 归一化写入留在队列里(入队后重新读取), 读取直接返回。
chrome.userScripts 批量注册是原子的,任一脚本的 matches/excludeMatches 含 edge://、chrome:// 等 scheme 都会让整批失败并退回逐个注册。 - getApiMatchesAndGlobs 输出时过滤 matches;过滤后为空则不注册,不会退回 *://*/* - 脚本与黑名单的 excludeMatches 同样过滤,黑名单判断仍保留原规则 - 更换 CompiledResourceNamespace,让旧缓存里的 matches 重建 - 设置页添加匹配时标出无法注册的规则且不写入
- 脚本列表返回前编辑区显示加载状态 - 脚本设置请求中显示加载状态,失败时展示错误详情与重试(原先一律 return null)
Collaborator
|
已完成这次 PR #1765 的 rework audit,并按两个独立问题补上修正。PR 标题和正文未改动。
验证结果:
本次没有重新执行慢 WebDAV/浏览器扩展运行时探针;附件中关于原 PR head 的运行时证据仍按审计材料记录,不能作为本次新增代码的独立运行时证据。云文件系统请求超时和 最终发布 head: |
cyfung1031
reviewed
Sep 22, 2026
| return { | ||
| matches: apiMatches, // primary | ||
| // 放在最后过滤:过滤后为空时调用方会不注册该脚本;若提前过滤,上面的逻辑会把空列表当成「无 match」退回 *://*/* | ||
| matches: apiMatches.filter(isApiSupportedMatchPattern), // primary |
Collaborator
There was a problem hiding this comment.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Checklist / 检查清单
背景
开启云同步后,在脚本设置里删除或重置网站匹配,再 F5 刷新编辑页,页面会长时间空白:脚本列表显示 0,编辑区为空,也没有报错。过一段时间后才恢复。关闭云同步后恢复正常。
根因是
getAllScripts整体放在CLOUD_SYNC_QUEUE_KEY串行队列里执行(#1690 引入)。这条队列里同时还有每次脚本变更触发的推送和整轮syncOnce,而这些任务都要等网络 I/O。修改 match 会触发推送;网盘慢或重试时,刷新后的列表请求排在推送后面,页面只能干等。排查时还发现两个会放大问题的点:
@match edge://settings/*这类浏览器不支持的 scheme,会让chrome.userScripts.register的整批注册失败(批量注册是原子的),然后退回逐个注册。excludeMatches(包括黑名单拼入的部分)同样会被拒绝,所以黑名单里只要有一条edge://,所有脚本都会注册失败。return null,失败后也不重试。所以不管是在等待还是出错,看到的都只是空白。本次改动
分三个提交,可以分别审查:
🐛 获取脚本列表不再排在云同步队列后面getAllScripts直接读取、排序后返回(返回浅拷贝,不改 DAO 缓存对象)。sort不连续时,才把归一化写入入队;入队后在队列里重新读取再写,保留 🐛 修复多设备同步脚本排序错乱 #1690 对排序写入的串行保护。docs/cloud-sync.md队列一节:过时的常量名,以及补充「页面依赖的读取不得进入这条队列」。🐛 注册脚本时丢弃浏览器不支持的 match schemegetApiMatchesAndGlobs在输出处过滤matches,只保留*/http/https/file/ftp。过滤放在最后:如果提前过滤,前面的逻辑会把空列表当成「没有 match」而退回*://*/*。过滤后为空时,走 runtime 已有的「不注册」分支,对应日志从 error 降为 warn。excludeMatches同样过滤;blackMatch仍保留原规则参与黑名单判断。CompiledResourceNamespace,让已缓存的旧matches在下次启动时重建。💄 编辑页与脚本设置加载时不再留白LoadingState。LoadingState;失败时用StateScreen展示错误详情和重试按钮。未保存脚本(data === null)维持原有行为。新增文案
bulk_status_invalid、settings_load_failed、retry,10 个 locale 都已补齐。日语「无效」用「不正」,因为术语规范中「無効」固定表示「禁用」。已知限制
fetch没有signal;limiter.ts对读操作的重试退避最长约 6 分钟)。请求挂住时,推送和syncOnce仍可能长时间占用队列。现在这只会推迟sortScript/pinToTop的完成时间,不再阻塞页面读取。超时时长和syncOnce的锁粒度需要单独设计,另开 PR。getAllScripts如果直接 reject,useScriptDataManagement不会退出加载态(原有行为,未改)。建议审查重点
script.ts的getAllScripts/normalizeScriptSort:读取不再与同步互斥,确认没有调用方依赖「返回时归一化已经落盘」。已有测试改成等队列清空后再断言落盘,就是这个契约变化。url_matcher.ts中过滤的位置:过滤后为空时,必须走「不注册」分支,不能退回全站匹配。CompiledResourceNamespace的代价:升级后首次启动会清理旧注册并全量重建一次。验证
本地 base
61cc2481(origin/main),head8016524a。fix/mobile-script-drag-swipe的构建产物):用每个请求延迟 8 秒的本地 WebDAV 模拟慢网盘,开启同步后改 match,再刷新编辑页。推送进行中getAllScripts耗时 125.9s,findInfo只要 22ms,截图与用户描述一致(列表 0、编辑区空白)。改 match 用的是和 UI 相同的resetMatch消息,不是点击按钮。pnpm run build):推送进行中getAllScripts耗时 26ms,编辑页正常显示 32 个脚本和代码。已通过 WebDAV 服务日志确认推送请求与这次读取在时间上重叠。@match edge://settings/*脚本):没有batch registration error和Invalid scheme,其余脚本和scriptcat-inject都已注册,edge://脚本未注册。excludeMatches: ["edge://settings/*"]、about:blank、urn:*、ws://都会抛Invalid scheme。script.test.ts、url_matcher.test.ts、utils.test.ts、runtime.test.ts、SettingsPane.test.tsx、ScriptEditor/index.test.tsx。pnpm run typecheck、pnpm run check:i18n、改动文件的 eslint 和 prettier 都通过。pnpm test:第一次全量有 3 个失败,都在未改动的eslint-rules/harness.test.mjs和src/pages/install/useInstallData.test.ts;这两个文件单独跑能通过(88/88),第二次全量 373 个文件、4848 个用例全部通过。推测是并行负载导致的偶发失败,未进一步定位。git diff origin/main...HEAD只涉及上述源码、测试、docs/cloud-sync.md和 10 个editor.json。Screenshots / 截图
未附截图。修复前后的截图是在本地验证会话里拍的。新增的加载态和错误态复用了现有的
LoadingState/StateScreen组件和设计令牌,但暗色主题下没有单独截图确认。