Merge remote-tracking branch 'origin/main' into feat/export-service
# Conflicts: # .gitignore # backend/app/main.py
This commit is contained in:
@@ -37,6 +37,7 @@
|
||||
- [前端构建分块优化开发说明](development/前端构建分块优化开发说明.md)
|
||||
|
||||
- [工作区后台索引与保存开发说明](development/工作区后台索引与保存开发说明.md)
|
||||
- [模型隔离向量索引与增量登记](development/模型隔离向量索引与增量登记.md)
|
||||
- [Mermaid 预览与缩放开发说明](development/Mermaid预览与缩放开发说明.md)
|
||||
- [扩展安装持久化与社区包开发说明](development/扩展安装持久化与社区包开发说明.md)
|
||||
- [模型上下文管理](development/模型上下文管理.md)
|
||||
@@ -96,3 +97,7 @@
|
||||
- 文档中的“计划实现”和“已经实现”必须明确区分;实现状态以代码、测试和运行时契约为准。
|
||||
|
||||
- [Markdown 语法预设与外部文件刷新](development/Markdown语法预设与外部文件刷新.md)
|
||||
|
||||
- [长文渲染优化与压测报告](development/长文渲染优化与压测报告.md)
|
||||
- [Agent 与任务压测报告](development/Agent与任务压测报告.md)
|
||||
- [后台运行日志与压力问题修复](development/后台运行日志与压力问题修复.md)
|
||||
|
||||
@@ -202,8 +202,20 @@ RunCancelled
|
||||
## 2026-09-06:后台索引补充
|
||||
|
||||
- `POST /api/workspace/open` 返回可使用的 WorkspaceSnapshot,不等待向量推理。
|
||||
- 外部新增文件登记后按笔记持久化后台向量任务,不再因此设置全库重建标记;已存在的全库待处理标记仍继续执行。模型空间与维度的持久化 sqlite-vec 索引从已有向量转换,接口响应结构不变。实现与性能验证见 [模型隔离向量索引与增量登记](../development/模型隔离向量索引与增量登记.md)。
|
||||
- `PATCH /api/notes/{note_id}` 成功代表正文、元数据和 FTS 已保存;后台向量失败不撤销这次保存。
|
||||
- `GET /api/index/status` 新增 `vector_refresh_required: boolean`,表示工作区或笔记存在向量待处理标记。该字段不是进度百分比;任务失败时也可为 true。
|
||||
- `pending_jobs` 返回真实未完成索引任务数(包含运行中),不再固定为 0。全库待重建或运行中的全量重建计一个任务;逐笔记刷新按待处理标记计数。`running_jobs` 返回当前运行数。失败后保留的待重建标记仍计入未完成数。
|
||||
- `active_searches`、`completed_searches`、`failed_searches`、`cancelled_searches` 分别表示向量/混合检索的进行中、完成、失败、取消次数,覆盖搜索、对话和 Agent 经统一检索引擎发起的调用,排除纯 FTS;混合检索回退 FTS 后成功仍计完成。计数仅保存在当前服务进程内,重启归零,与索引队列互相独立。
|
||||
- 设置与搜索页每秒轮询状态,其他页面空闲时每 5 秒轮询;不是事件推送。短检索可能无法观察到进行中状态,但完成/失败计数会保留。设置页与底部状态栏复用状态标签,未知字段显示“未获取”。
|
||||
- `POST /api/index/rebuild` 仍仅支持全量重建,并等待结果;不要将上述异步语义推广到所有索引 API。
|
||||
|
||||
状态、恢复限制与验证见 [工作区后台索引与保存开发说明](../development/工作区后台索引与保存开发说明.md)。
|
||||
|
||||
## 2026-09-06:统一运行日志
|
||||
|
||||
`GET /api/logs` 返回独立持久化的后台操作日志,无需打开 Vault。参数:`limit` 默认 50、最大 200;`before` 为上一页 next_cursor;`level` 为 INFO/WARNING/ERROR/CRITICAL 或空;`source` 按模块精确匹配;`q` 在事件名和脱敏元数据中做字面搜索。
|
||||
|
||||
返回 `items: [{id,timestamp,level,source,event,details}]`、`next_cursor`(无后续页时 null)、`sources`、`pending`、`dropped`、`write_failures`、`retention`。日志按 ID 倒序,保留最近 20,000 条。响应头 `X-Request-ID` 与后台日志关联。不得依赖日志记录笔记正文、工具参数、凭据或原始异常消息。
|
||||
|
||||
队列、错误处理、字段白名单和验证方法见 [后台运行日志与压力问题修复](../development/后台运行日志与压力问题修复.md)。
|
||||
|
||||
@@ -0,0 +1,156 @@
|
||||
# Agent 与任务压测报告
|
||||
|
||||
> 日期:2026-09-06。范围:当前第二阶段 Agent Runtime、任务 API、任务列表及 Trace 组件。测试在 Windows 11、Python 3.12.6、独立无头 Chrome 下执行,前端为 Vite 开发模式,纸间时光版本 1.8.1。
|
||||
|
||||
## 1. 结论
|
||||
|
||||
功能正确性检查通过:Agent 工具调用、事件序号与回放、终态持久化恢复、容量拒绝、取消、权限等待、故障隔离,以及任务增删改查和分页均得到预期结果。性能仍有三项明确问题:
|
||||
|
||||
| 优先级 | 问题 | 本轮证据 | 建议方向 |
|
||||
| --- | --- | --- | --- |
|
||||
| P1 | 任务列表未加载后续页;Agent 历史列表也没有后续分页入口 | 100、1000 条任务的实际页面均只请求 `/api/tasks` 并显示 50 条;Agent store 同样仅调用默认分页一次,接口默认 50 | 增加服务端筛选与分页/加载更多,显示总量,防止统计仅基于已加载项 |
|
||||
| P1 | 高并发 Agent 阻塞事件循环 | 200 并发的完成延迟 P95 约 10.55 秒;进程内心跳最大延迟约 3.56 秒 | 分析同步持久化,设计有界执行调度及顺序写入,保留事件落盘、终态与回放一致性 |
|
||||
| P1 | 大 Trace 的树形筛选长时间阻塞 | 2000 事件树形搜索约 483–617 ms;10000 事件约 25.91 秒 | 为匹配的 sequence/tool/model ID 建 Set,避免逐节点重复遍历事件;再评估分段显示及增量更新 |
|
||||
|
||||
本次新增的是可复现压测与报告,没有把上述生产问题标记为已修复。页面滚动与树形搜索是不同瓶颈:10000 事件的滚动 P95 约 40 ms,并不能说明搜索交互也流畅。
|
||||
|
||||
## 2. 隔离与方法
|
||||
|
||||
- 后端脚本在导入任何 app 模块前,将 `APP_DATA_DIR`、`APP_DB_PATH`、`APP_VAULT_PATH` 指向临时目录,结束后清理;不读写用户 Vault、现有任务及 Provider 凭据。
|
||||
- Agent 使用内置 Mock Provider,每轮模型调用注入 50 ms 异步等待,正常样本包含一次 `system.echo` 工具调用和两轮模型调用;不调用真实厂商,也不衡量回答质量或真实模型吞吐。
|
||||
- 进程内运行直接调用真实 Runtime、SQLite 和任务 ASGI 路由。任务 HTTP 复核另起独立 Uvicorn 进程,用真实回环连接执行,避免将 ASGI 驱动的连续无让出执行误解为网络服务延迟。
|
||||
- 前端挂载真实 TasksView、TraceTimeline 和 Pinia store。压测页拦截全部 fetch,不向真实后端发出请求。任务接口夹具保留默认 50 条分页,先测实际加载条数,再注入完整列表测试渲染上限,两者分开记录。
|
||||
- Trace 由确定性模型开始/完成、工具调用/结果事件组成,带调用与父节点 ID;测量首次渲染、时间线过滤、树形切换、匹配全部节点的树形搜索。
|
||||
- 滚动用 CDP 派发 120 次滚轮事件,记录真实滚动容器及 `maxScrollTop`,防止对未滚动页面统计帧间隔。Trace 测试容器显式解除应用根节点的裁剪,由独立滚动区承担真实 Agent 页滚动容器的职责。
|
||||
|
||||
本轮每个前端配置测一次;开发编译、后台负载、缓存和浏览器调度都会影响结果,数据用于发现瓶颈,不作为生产环境 SLA。首次渲染计时不包含模块下载,包含 Vue 更新及两个 animation frame。
|
||||
|
||||
## 3. Agent 后端
|
||||
|
||||
### 3.1 正常工具调用与回放
|
||||
|
||||
| 并发数 | 运行数 | 完成延迟中位数(ms) | 完成延迟 P95(ms) | 场景心跳最大延迟(ms) |
|
||||
| ---: | ---: | ---: | ---: | ---: |
|
||||
| 1 | 20 | 146.20 | 170.13 | 26.84 |
|
||||
| 10 | 20 | 405.75 | 505.74 | 136.71 |
|
||||
| 50 | 50 | 2234.45 | 2304.42 | 798.84 |
|
||||
| 200 | 200 | 10262.47 | 10554.52 | 3559.97 |
|
||||
|
||||
290 个正常运行全部完成,工具返回内容逐项一致;实时订阅事件序号连续,`after_sequence=2` 回放与原事件后缀一致。新的 Runtime 实例可以从 SQLite 恢复这些终态运行。订阅者集合最终清空,进程内保留记录不超过 200。
|
||||
|
||||
“并发”是同时提交的协程数,不代表独立 CPU 工作线程。当前 queued 是启动前状态,Runtime 并没有把超额活跃运行无限排入执行队列。场景心跳还包含提交、持久化回放与恢复校验,不能将其全部归为模型执行耗时;50、200 并发场景的心跳采样数仅 8 个,表中因此列最大值而非宣称稳定分位数。
|
||||
|
||||
代码定位:`AgentRuntime._publish()` 同步调用 `AgentTraceRepository.append_event()`,后者逐事件连接 SQLite 并提交事务;`connect()` 还加载扩展和检查迁移。这是需要进一步拆分测量的阻塞路径,本轮未完成各子步骤 CPU/磁盘成本归因。
|
||||
|
||||
### 3.2 容量、取消与故障注入
|
||||
|
||||
- 保持 200 个模型调用活跃,第 201 次创建得到 `AgentCapacityError`;随后取消全部 200 个运行,全部进入 cancelled,后台任务均结束。
|
||||
- 20 个运行等待权限:10 个允许后完成,10 个等待中取消,订阅者均释放。
|
||||
- 20 个混合运行:5 个正常完成、5 个 Provider 异常、5 个模型超时、5 个工具超时,均获得预期状态或错误码;工具执行器剩余数量为 0。
|
||||
- 正常回放和故障场景合计创建 530 个运行,临时数据库最终约 2.95 MB。工具超时被记录为 ToolResult 错误,后续 Mock 模型仍可能完成运行,不将它误算为整个 Run 必然失败。
|
||||
|
||||
这里的“恢复”是新 Runtime 读取终态持久化数据,未模拟 OS 强杀时的写入中断。SSE 通过 Runtime 的事件生成器验证序号及断点回放,没有进行真实网络慢读者/断网压力测试。
|
||||
|
||||
## 4. 任务 API
|
||||
|
||||
进程内分别对 100、1000 条任务执行创建、逐页读取、更新为 done、删除,所有 ID 完整,最终总量为 0。默认接口每页 50 条,显式每页 100 条遍历可以取回全部数据。
|
||||
|
||||
ASGITransport 的 1000 条突发操作中,心跳出现约 14 秒延迟:测试客户端与同步路由处于同一事件循环,连续就绪协程缺少网络等待,不能将其视作真实 HTTP 健康检查延迟。因此增加独立 Uvicorn + 回环 HTTP 复核:
|
||||
|
||||
| 操作 | 数量 | P95(ms) | 最大值(ms) |
|
||||
| --- | ---: | ---: | ---: |
|
||||
| 创建 | 1000 | 116.45 | 134.91 |
|
||||
| 更新 | 1000 | 159.29 | 193.37 |
|
||||
| 删除 | 1000 | 156.43 | 190.10 |
|
||||
| 分页/收尾查询 | 11 | 20.96 | 20.96 |
|
||||
| 并行健康检查 | 117 | 157.00 | 195.07 |
|
||||
|
||||
HTTP 客户端并发 20,总耗时约 18.31 秒;健康检查零失败,分页无重复/遗漏,最终任务数为 0。此处是本机单次结果,未覆盖跨网络、长期持久负载或多进程同时写同一数据库。
|
||||
|
||||
## 5. 前端
|
||||
|
||||
### 5.1 任务列表
|
||||
|
||||
100、1000 条数据的实际加载阶段都只有一次 `/api/tasks` 请求,store 中均为 50 条。以下是额外注入完整 1000 条数据后的结果,不是生产页面当前可以加载 1000 条的证明。
|
||||
|
||||
| 主题 | 完整列表渲染(ms) | 完成状态筛选(ms) |
|
||||
| --- | ---: | ---: |
|
||||
| 默认浅色 | 117.4 | 44.1 |
|
||||
| 默认深色 | 137.8 | 47.8 |
|
||||
| 纸间时光 1.8.1 | 150.0 | 59.5 |
|
||||
|
||||
1000 条列表约 11007 个 DOM 节点,实际滚动最远达到 81000 px;筛选 done 得到 334 条,与夹具期望一致。100 条样本筛选得到 34 条,也一致。默认浅色的 1000 条滚动 P95 约 30.2 ms,纸间时光约 50.1 ms;样本数少,暂不据此认定新的单一 CSS 根因。
|
||||
|
||||
### 5.2 Agent Trace
|
||||
|
||||
| 事件数/主题 | 首次渲染(ms) | 时间线搜索(ms) | 树形切换(ms) | 树形全匹配搜索(ms) |
|
||||
| --- | ---: | ---: | ---: | ---: |
|
||||
| 2000 / 默认浅色 | 283.8 | 97.4 | 64.0 | 617.2 |
|
||||
| 2000 / 默认深色 | 289.0 | 74.5 | 62.9 | 483.0 |
|
||||
| 2000 / 纸间时光 | 337.3 | 86.3 | 62.1 | 540.1 |
|
||||
| 10000 / 纸间时光 | 1803.9 | 582.8 | 317.5 | 25914.8 |
|
||||
|
||||
200 事件的树形搜索约 20–29 ms。2000 事件时间线约 20542 个 DOM 节点,10000 事件约 102542 个。查询“压力测试 1”分别命中 444、4444 条事件,与直接检查输入数据的结果一致;树形搜索“压力测试”匹配所有事件,会自动展开匹配子树。
|
||||
|
||||
代码定位:`TraceTimeline.filteredTree` 为每个节点调用 `filteredEvents.some(...)`。节点数和匹配事件数一起增加时,会产生近似二次增长的匹配工作,随后还需构造并渲染展开子树。建议先用匹配 ID 集合消除嵌套扫描,再测 DOM 更新成本;不要仅用防抖隐藏单次 25 秒阻塞。
|
||||
|
||||
10000 是扩大数据规模的诊断测试,高于 Runtime 默认内存事件保留量 2000;它直接向组件传入事件,不代表当前单次 API 页或实时 store 默认会收到这一数量。也未覆盖逐事件 SSE 增量刷新的端到端成本。
|
||||
|
||||
## 6. 复现与原始数据
|
||||
|
||||
```powershell
|
||||
# 后端:独立临时数据,离线 Mock
|
||||
backend/.venv/Scripts/python.exe backend/scripts/agent-task-stress.py --output .local-plans/agent-task-backend.json
|
||||
# 真实 HTTP:独立 Uvicorn、随机回环端口
|
||||
backend/.venv/Scripts/python.exe backend/scripts/task-http-stress.py --count 1000 --concurrency 20 --output .local-plans/task-http.json
|
||||
# 前端:先启动独立 Vite,另一个终端执行后续命令
|
||||
npm --prefix frontend run dev -- --port 5175 --strictPort
|
||||
backend/.venv/Scripts/python.exe frontend/tests/performance/run-stress.py --url 'http://127.0.0.1:5175/tests/performance/agent-task.html?kind=tasks&theme=paper-moments' --scroll --sizes 100 1000 --runs 1 --output .local-plans/task-ui.json
|
||||
backend/.venv/Scripts/python.exe frontend/tests/performance/run-stress.py --url 'http://127.0.0.1:5175/tests/performance/agent-task.html?kind=trace&theme=paper-moments' --scroll --sizes 200 2000 10000 --runs 1 --output .local-plans/trace-ui.json
|
||||
```
|
||||
|
||||
URL 的 theme 可换为 light、dark。测试应串行运行,避免不同负载相互争用;10k Trace 树形筛选可能长时间占用测试浏览器。浏览器使用临时用户目录,不接管用户当前浏览器。
|
||||
|
||||
- [Agent 与进程内任务 API 数据](performance/2026-09-06-agent-task-backend.json)
|
||||
- [真实 HTTP 任务数据](performance/2026-09-06-task-http.json)
|
||||
- [前端 13 组样本数据](performance/2026-09-06-agent-task-ui.json)
|
||||
- [前端压测工具](../../frontend/tests/performance/README.md)
|
||||
|
||||
附加回归:`test_agent_core.py`、`test_api.py` 共 26 项通过。脚本中的状态、序号、输出、分页与筛选断言均通过。未提交或推送本次材料。
|
||||
|
||||
## 7. 修复后复测(2026-09-06)
|
||||
|
||||
以上保留首次压测基线。本节对应后台 Trace 批量写入、任务后台写入、完整列表加载、Trace 集合匹配/分页和统一日志接入后的实现。样本开启新操作日志,仍只调用隔离 Mock。
|
||||
|
||||
| 项目 | 修复前 | 修复后 |
|
||||
| --- | ---: | ---: |
|
||||
| 200 并发 Agent 完成 P95 | 10,554.52 ms | 1,233.12 ms |
|
||||
| 200 并发测量区间事件循环最大延迟 | 3,559.97 ms | 509.00 ms |
|
||||
| 纸间时光 10k Trace 首次渲染 | 1,803.9 ms | 94.4 ms |
|
||||
| 纸间时光 10k Trace 树形全匹配筛选 | 25,914.8 ms | 189.2 ms |
|
||||
| 纸间时光 10k Trace 首屏 DOM 节点 | 约 102,542 | 1,852 |
|
||||
| 1,000 条任务首次实际加载 | 50 条 | 1,000 条(10 次 API 请求) |
|
||||
|
||||
Agent 测量区间还包含同步读回、校验和重启恢复,最大心跳延迟不是纯执行阶段指标。290 次普通运行、200 个容量/取消场景、20 个权限场景、20 个失败/超时场景全部通过,订阅者和工具执行器释放。不能声称消除了所有主线程工作。
|
||||
|
||||
Trace 搜索检查完整数据,只有渲染分页。10k 样本滚动 frame gap P95 为 10.1 ms,无 longtask;时间线筛选 284.9 ms,树形切换 100.9 ms。这是单次本机样本,不代表所有硬件与实时 SSE 输入。
|
||||
|
||||
1,000 条任务界面每页 100 条;筛选后数据总数 334,当前页 100。筛选 18.7 ms,滚动 frame gap P95 为 30 ms,无 longtask。断言同时检查完整数据量和分页渲染数量。
|
||||
|
||||
真实 HTTP 测试 1,000 条任务、20 并发,CRUD 全部成功,分页完整,最终任务数 0:
|
||||
|
||||
| 指标 | 修复前 | 修复后 |
|
||||
| --- | ---: | ---: |
|
||||
| health P95 | 157.00 ms | 38.64 ms |
|
||||
| 创建 P95 | 116.45 ms | 157.68 ms |
|
||||
| 更新 P95 | 159.29 ms | 208.68 ms |
|
||||
| 删除 P95 | 156.43 ms | 205.45 ms |
|
||||
| 总耗时 | 18.31 s | 24.51 s |
|
||||
|
||||
后台排队和操作记录改善了无关请求的响应,但这组样本写入吞吐下降,不能描述为 CRUD 全面提速。后续可以评估任务事务批量化与连接初始化开销;本次没有降低 SQLite 持久化级别。
|
||||
|
||||
- [Agent / 进程内任务复测](performance/2026-09-06-agent-task-backend-fixed.json)
|
||||
- [真实 HTTP 任务复测](performance/2026-09-06-task-http-fixed.json)
|
||||
- [Trace 浏览器复测](performance/2026-09-06-agent-trace-ui-fixed.json)
|
||||
- [任务浏览器复测](performance/2026-09-06-task-ui-fixed.json)
|
||||
- [日志架构与验收说明](后台运行日志与压力问题修复.md)
|
||||
@@ -0,0 +1,230 @@
|
||||
{
|
||||
"python": "3.12.6",
|
||||
"platform": "Windows-11-10.0.26100-SP0",
|
||||
"provider": "mock with 50 ms injected delay per model turn; no network",
|
||||
"results": [
|
||||
{
|
||||
"scenario": "agent_tool_runs",
|
||||
"concurrency": 1,
|
||||
"runs": 20,
|
||||
"latency": {
|
||||
"count": 20,
|
||||
"median_ms": 150.79,
|
||||
"p95_ms": 169.57,
|
||||
"max_ms": 178.52
|
||||
},
|
||||
"completed": 20,
|
||||
"ordered_events_and_replay": true,
|
||||
"terminal_recovery": true,
|
||||
"retained_records": 20,
|
||||
"elapsed_ms": 3047.59,
|
||||
"event_loop_lag": {
|
||||
"count": 995,
|
||||
"median_ms": 0,
|
||||
"p95_ms": 5.65,
|
||||
"max_ms": 21.83
|
||||
}
|
||||
},
|
||||
{
|
||||
"scenario": "agent_tool_runs",
|
||||
"concurrency": 10,
|
||||
"runs": 20,
|
||||
"latency": {
|
||||
"count": 20,
|
||||
"median_ms": 187.48,
|
||||
"p95_ms": 214.02,
|
||||
"max_ms": 214.58
|
||||
},
|
||||
"completed": 20,
|
||||
"ordered_events_and_replay": true,
|
||||
"terminal_recovery": true,
|
||||
"retained_records": 40,
|
||||
"elapsed_ms": 514.15,
|
||||
"event_loop_lag": {
|
||||
"count": 192,
|
||||
"median_ms": 0,
|
||||
"p95_ms": 4.82,
|
||||
"max_ms": 20.02
|
||||
}
|
||||
},
|
||||
{
|
||||
"scenario": "agent_tool_runs",
|
||||
"concurrency": 50,
|
||||
"runs": 50,
|
||||
"latency": {
|
||||
"count": 50,
|
||||
"median_ms": 364.9,
|
||||
"p95_ms": 366.99,
|
||||
"max_ms": 367.3
|
||||
},
|
||||
"completed": 50,
|
||||
"ordered_events_and_replay": true,
|
||||
"terminal_recovery": true,
|
||||
"retained_records": 90,
|
||||
"elapsed_ms": 526.56,
|
||||
"event_loop_lag": {
|
||||
"count": 172,
|
||||
"median_ms": 0,
|
||||
"p95_ms": 4.57,
|
||||
"max_ms": 69.89
|
||||
}
|
||||
},
|
||||
{
|
||||
"scenario": "agent_tool_runs",
|
||||
"concurrency": 200,
|
||||
"runs": 200,
|
||||
"latency": {
|
||||
"count": 200,
|
||||
"median_ms": 1118.63,
|
||||
"p95_ms": 1233.12,
|
||||
"max_ms": 1237.31
|
||||
},
|
||||
"completed": 200,
|
||||
"ordered_events_and_replay": true,
|
||||
"terminal_recovery": true,
|
||||
"retained_records": 200,
|
||||
"elapsed_ms": 1839.2,
|
||||
"event_loop_lag": {
|
||||
"count": 470,
|
||||
"median_ms": 0,
|
||||
"p95_ms": 2.6,
|
||||
"max_ms": 509.0
|
||||
}
|
||||
},
|
||||
{
|
||||
"scenario": "capacity_and_cancel",
|
||||
"active_limit": 200,
|
||||
"overflow_rejected": true,
|
||||
"cancelled": 200,
|
||||
"cancel_latency": {
|
||||
"count": 200,
|
||||
"median_ms": 7.71,
|
||||
"p95_ms": 10.8,
|
||||
"max_ms": 17.37
|
||||
},
|
||||
"elapsed_ms": 3613.48,
|
||||
"event_loop_lag": {
|
||||
"count": 1613,
|
||||
"median_ms": 0,
|
||||
"p95_ms": 0,
|
||||
"max_ms": 7.86
|
||||
}
|
||||
},
|
||||
{
|
||||
"scenario": "permission_wait",
|
||||
"runs": 20,
|
||||
"approved_completed": 10,
|
||||
"cancelled_waiting_permission": 10,
|
||||
"subscribers_released": true,
|
||||
"elapsed_ms": 388.83,
|
||||
"event_loop_lag": {
|
||||
"count": 72,
|
||||
"median_ms": 0,
|
||||
"p95_ms": 9.9,
|
||||
"max_ms": 15.27
|
||||
}
|
||||
},
|
||||
{
|
||||
"scenario": "failure_and_timeout_isolation",
|
||||
"runs": 20,
|
||||
"success": 5,
|
||||
"provider_errors": 5,
|
||||
"model_timeouts": 5,
|
||||
"tool_timeouts": 5,
|
||||
"remaining_tool_executors": 0,
|
||||
"elapsed_ms": 1295.29,
|
||||
"event_loop_lag": {
|
||||
"count": 152,
|
||||
"median_ms": 0,
|
||||
"p95_ms": 7.2,
|
||||
"max_ms": 17.24
|
||||
}
|
||||
},
|
||||
{
|
||||
"scenario": "task_api_crud",
|
||||
"tasks": 100,
|
||||
"client_concurrency": 20,
|
||||
"latencies": {
|
||||
"create": {
|
||||
"count": 100,
|
||||
"median_ms": 214.09,
|
||||
"p95_ms": 264.51,
|
||||
"max_ms": 309.99
|
||||
},
|
||||
"update": {
|
||||
"count": 100,
|
||||
"median_ms": 221.48,
|
||||
"p95_ms": 403.74,
|
||||
"max_ms": 495.1
|
||||
},
|
||||
"list": {
|
||||
"count": 1,
|
||||
"median_ms": 7.92,
|
||||
"p95_ms": 7.92,
|
||||
"max_ms": 7.92
|
||||
},
|
||||
"delete": {
|
||||
"count": 100,
|
||||
"median_ms": 232.9,
|
||||
"p95_ms": 468.48,
|
||||
"max_ms": 475.63
|
||||
}
|
||||
},
|
||||
"default_page_count": 50,
|
||||
"default_total": 100,
|
||||
"pagination_complete": true,
|
||||
"final_total": 0,
|
||||
"elapsed_ms": 3673.22,
|
||||
"event_loop_lag": {
|
||||
"count": 2337,
|
||||
"median_ms": 0,
|
||||
"p95_ms": 0,
|
||||
"max_ms": 118.92
|
||||
}
|
||||
},
|
||||
{
|
||||
"scenario": "task_api_crud",
|
||||
"tasks": 1000,
|
||||
"client_concurrency": 20,
|
||||
"latencies": {
|
||||
"create": {
|
||||
"count": 1000,
|
||||
"median_ms": 200.87,
|
||||
"p95_ms": 237.75,
|
||||
"max_ms": 376.8
|
||||
},
|
||||
"update": {
|
||||
"count": 1000,
|
||||
"median_ms": 220.04,
|
||||
"p95_ms": 260.19,
|
||||
"max_ms": 300.07
|
||||
},
|
||||
"list": {
|
||||
"count": 10,
|
||||
"median_ms": 7.89,
|
||||
"p95_ms": 9.61,
|
||||
"max_ms": 9.61
|
||||
},
|
||||
"delete": {
|
||||
"count": 1000,
|
||||
"median_ms": 218.1,
|
||||
"p95_ms": 266.23,
|
||||
"max_ms": 316.14
|
||||
}
|
||||
},
|
||||
"default_page_count": 50,
|
||||
"default_total": 1000,
|
||||
"pagination_complete": true,
|
||||
"final_total": 0,
|
||||
"elapsed_ms": 32562.93,
|
||||
"event_loop_lag": {
|
||||
"count": 24893,
|
||||
"median_ms": 0,
|
||||
"p95_ms": 0,
|
||||
"max_ms": 91.85
|
||||
}
|
||||
}
|
||||
],
|
||||
"database_bytes": 2981888,
|
||||
"complete": true
|
||||
}
|
||||
@@ -0,0 +1,230 @@
|
||||
{
|
||||
"python": "3.12.6",
|
||||
"platform": "Windows-11-10.0.26100-SP0",
|
||||
"provider": "mock with 50 ms injected delay per model turn; no network",
|
||||
"results": [
|
||||
{
|
||||
"scenario": "agent_tool_runs",
|
||||
"concurrency": 1,
|
||||
"runs": 20,
|
||||
"latency": {
|
||||
"count": 20,
|
||||
"median_ms": 146.2,
|
||||
"p95_ms": 170.13,
|
||||
"max_ms": 171.23
|
||||
},
|
||||
"completed": 20,
|
||||
"ordered_events_and_replay": true,
|
||||
"terminal_recovery": true,
|
||||
"retained_records": 20,
|
||||
"elapsed_ms": 3041.03,
|
||||
"event_loop_lag": {
|
||||
"count": 190,
|
||||
"median_ms": 5.64,
|
||||
"p95_ms": 16.81,
|
||||
"max_ms": 26.84
|
||||
}
|
||||
},
|
||||
{
|
||||
"scenario": "agent_tool_runs",
|
||||
"concurrency": 10,
|
||||
"runs": 20,
|
||||
"latency": {
|
||||
"count": 20,
|
||||
"median_ms": 405.75,
|
||||
"p95_ms": 505.74,
|
||||
"max_ms": 539.28
|
||||
},
|
||||
"completed": 20,
|
||||
"ordered_events_and_replay": true,
|
||||
"terminal_recovery": true,
|
||||
"retained_records": 40,
|
||||
"elapsed_ms": 1045.19,
|
||||
"event_loop_lag": {
|
||||
"count": 15,
|
||||
"median_ms": 57.63,
|
||||
"p95_ms": 136.71,
|
||||
"max_ms": 136.71
|
||||
}
|
||||
},
|
||||
{
|
||||
"scenario": "agent_tool_runs",
|
||||
"concurrency": 50,
|
||||
"runs": 50,
|
||||
"latency": {
|
||||
"count": 50,
|
||||
"median_ms": 2234.45,
|
||||
"p95_ms": 2304.42,
|
||||
"max_ms": 2307.54
|
||||
},
|
||||
"completed": 50,
|
||||
"ordered_events_and_replay": true,
|
||||
"terminal_recovery": true,
|
||||
"retained_records": 90,
|
||||
"elapsed_ms": 2552.49,
|
||||
"event_loop_lag": {
|
||||
"count": 8,
|
||||
"median_ms": 345.24,
|
||||
"p95_ms": 798.84,
|
||||
"max_ms": 798.84
|
||||
}
|
||||
},
|
||||
{
|
||||
"scenario": "agent_tool_runs",
|
||||
"concurrency": 200,
|
||||
"runs": 200,
|
||||
"latency": {
|
||||
"count": 200,
|
||||
"median_ms": 10262.47,
|
||||
"p95_ms": 10554.52,
|
||||
"max_ms": 10584.03
|
||||
},
|
||||
"completed": 200,
|
||||
"ordered_events_and_replay": true,
|
||||
"terminal_recovery": true,
|
||||
"retained_records": 200,
|
||||
"elapsed_ms": 11442.28,
|
||||
"event_loop_lag": {
|
||||
"count": 8,
|
||||
"median_ms": 1647.87,
|
||||
"p95_ms": 3559.97,
|
||||
"max_ms": 3559.97
|
||||
}
|
||||
},
|
||||
{
|
||||
"scenario": "capacity_and_cancel",
|
||||
"active_limit": 200,
|
||||
"overflow_rejected": true,
|
||||
"cancelled": 200,
|
||||
"cancel_latency": {
|
||||
"count": 200,
|
||||
"median_ms": 4.32,
|
||||
"p95_ms": 5.36,
|
||||
"max_ms": 8.27
|
||||
},
|
||||
"elapsed_ms": 3645.04,
|
||||
"event_loop_lag": {
|
||||
"count": 3,
|
||||
"median_ms": 14.04,
|
||||
"p95_ms": 3610.52,
|
||||
"max_ms": 3610.52
|
||||
}
|
||||
},
|
||||
{
|
||||
"scenario": "permission_wait",
|
||||
"runs": 20,
|
||||
"approved_completed": 10,
|
||||
"cancelled_waiting_permission": 10,
|
||||
"subscribers_released": true,
|
||||
"elapsed_ms": 971.64,
|
||||
"event_loop_lag": {
|
||||
"count": 11,
|
||||
"median_ms": 49.09,
|
||||
"p95_ms": 314.46,
|
||||
"max_ms": 314.46
|
||||
}
|
||||
},
|
||||
{
|
||||
"scenario": "failure_and_timeout_isolation",
|
||||
"runs": 20,
|
||||
"success": 5,
|
||||
"provider_errors": 5,
|
||||
"model_timeouts": 5,
|
||||
"tool_timeouts": 5,
|
||||
"remaining_tool_executors": 0,
|
||||
"elapsed_ms": 1531.14,
|
||||
"event_loop_lag": {
|
||||
"count": 83,
|
||||
"median_ms": 5.17,
|
||||
"p95_ms": 27.82,
|
||||
"max_ms": 255.96
|
||||
}
|
||||
},
|
||||
{
|
||||
"scenario": "task_api_crud",
|
||||
"tasks": 100,
|
||||
"client_concurrency": 20,
|
||||
"latencies": {
|
||||
"create": {
|
||||
"count": 100,
|
||||
"median_ms": 5.37,
|
||||
"p95_ms": 34.16,
|
||||
"max_ms": 61.99
|
||||
},
|
||||
"update": {
|
||||
"count": 100,
|
||||
"median_ms": 7.22,
|
||||
"p95_ms": 35.0,
|
||||
"max_ms": 96.33
|
||||
},
|
||||
"list": {
|
||||
"count": 1,
|
||||
"median_ms": 3.73,
|
||||
"p95_ms": 3.73,
|
||||
"max_ms": 3.73
|
||||
},
|
||||
"delete": {
|
||||
"count": 100,
|
||||
"median_ms": 5.44,
|
||||
"p95_ms": 14.57,
|
||||
"max_ms": 36.43
|
||||
}
|
||||
},
|
||||
"default_page_count": 50,
|
||||
"default_total": 100,
|
||||
"pagination_complete": true,
|
||||
"final_total": 0,
|
||||
"elapsed_ms": 2532.22,
|
||||
"event_loop_lag": {
|
||||
"count": 4,
|
||||
"median_ms": 776.23,
|
||||
"p95_ms": 1712.81,
|
||||
"max_ms": 1712.81
|
||||
}
|
||||
},
|
||||
{
|
||||
"scenario": "task_api_crud",
|
||||
"tasks": 1000,
|
||||
"client_concurrency": 20,
|
||||
"latencies": {
|
||||
"create": {
|
||||
"count": 1000,
|
||||
"median_ms": 5.18,
|
||||
"p95_ms": 32.23,
|
||||
"max_ms": 43.29
|
||||
},
|
||||
"update": {
|
||||
"count": 1000,
|
||||
"median_ms": 6.51,
|
||||
"p95_ms": 14.72,
|
||||
"max_ms": 90.27
|
||||
},
|
||||
"list": {
|
||||
"count": 10,
|
||||
"median_ms": 5.48,
|
||||
"p95_ms": 6.18,
|
||||
"max_ms": 6.18
|
||||
},
|
||||
"delete": {
|
||||
"count": 1000,
|
||||
"median_ms": 4.76,
|
||||
"p95_ms": 8.42,
|
||||
"max_ms": 97.64
|
||||
}
|
||||
},
|
||||
"default_page_count": 50,
|
||||
"default_total": 1000,
|
||||
"pagination_complete": true,
|
||||
"final_total": 0,
|
||||
"elapsed_ms": 21242.37,
|
||||
"event_loop_lag": {
|
||||
"count": 4,
|
||||
"median_ms": 6932.7,
|
||||
"p95_ms": 14260.46,
|
||||
"max_ms": 14260.46
|
||||
}
|
||||
}
|
||||
],
|
||||
"database_bytes": 2949120,
|
||||
"complete": true
|
||||
}
|
||||
@@ -0,0 +1,706 @@
|
||||
[
|
||||
{
|
||||
"kind": "tasks",
|
||||
"theme": "light",
|
||||
"size": 100,
|
||||
"initialRenderMs": 33.099999994039536,
|
||||
"requests": [
|
||||
"/api/tasks"
|
||||
],
|
||||
"initialTaskCount": 50,
|
||||
"fullListRenderMs": 79.09999999403954,
|
||||
"fullListIsInjected": true,
|
||||
"domNodes": 1107,
|
||||
"frameGapsMs": {
|
||||
"median": 10,
|
||||
"p95": 10.100000000000364,
|
||||
"max": 69.49999999403951
|
||||
},
|
||||
"frames": 407,
|
||||
"longTasks": [],
|
||||
"scrollTop": 0,
|
||||
"scrollHeight": 11702,
|
||||
"maxScrollTop": 10845,
|
||||
"filteredCount": 34,
|
||||
"expectedFilteredCount": 34,
|
||||
"filterMs": 16.299999982118607,
|
||||
"repeat": 1
|
||||
},
|
||||
{
|
||||
"kind": "tasks",
|
||||
"theme": "light",
|
||||
"size": 1000,
|
||||
"initialRenderMs": 4.4000000059604645,
|
||||
"requests": [
|
||||
"/api/tasks"
|
||||
],
|
||||
"initialTaskCount": 50,
|
||||
"fullListRenderMs": 117.39999997615814,
|
||||
"fullListIsInjected": true,
|
||||
"domNodes": 11007,
|
||||
"frameGapsMs": {
|
||||
"median": 20.099999999999454,
|
||||
"p95": 30.199999999999818,
|
||||
"max": 50
|
||||
},
|
||||
"frames": 353,
|
||||
"longTasks": [],
|
||||
"scrollTop": 54000,
|
||||
"scrollHeight": 115652,
|
||||
"maxScrollTop": 81000,
|
||||
"filteredCount": 334,
|
||||
"expectedFilteredCount": 334,
|
||||
"filterMs": 44.10000002384186,
|
||||
"repeat": 1
|
||||
},
|
||||
{
|
||||
"kind": "tasks",
|
||||
"theme": "dark",
|
||||
"size": 100,
|
||||
"initialRenderMs": 30.900000005960464,
|
||||
"requests": [
|
||||
"/api/tasks"
|
||||
],
|
||||
"initialTaskCount": 50,
|
||||
"fullListRenderMs": 78.2999999821186,
|
||||
"fullListIsInjected": true,
|
||||
"domNodes": 1107,
|
||||
"frameGapsMs": {
|
||||
"median": 10,
|
||||
"p95": 10.100000000000364,
|
||||
"max": 49.69999998807907
|
||||
},
|
||||
"frames": 411,
|
||||
"longTasks": [],
|
||||
"scrollTop": 0,
|
||||
"scrollHeight": 11702,
|
||||
"maxScrollTop": 10845,
|
||||
"filteredCount": 34,
|
||||
"expectedFilteredCount": 34,
|
||||
"filterMs": 16.099999994039536,
|
||||
"repeat": 1
|
||||
},
|
||||
{
|
||||
"kind": "tasks",
|
||||
"theme": "dark",
|
||||
"size": 1000,
|
||||
"initialRenderMs": 5,
|
||||
"requests": [
|
||||
"/api/tasks"
|
||||
],
|
||||
"initialTaskCount": 50,
|
||||
"fullListRenderMs": 137.7999999821186,
|
||||
"fullListIsInjected": true,
|
||||
"domNodes": 11007,
|
||||
"frameGapsMs": {
|
||||
"median": 20,
|
||||
"p95": 30.199999999999818,
|
||||
"max": 40.19999999999982
|
||||
},
|
||||
"frames": 360,
|
||||
"longTasks": [],
|
||||
"scrollTop": 54000,
|
||||
"scrollHeight": 115652,
|
||||
"maxScrollTop": 81000,
|
||||
"filteredCount": 334,
|
||||
"expectedFilteredCount": 334,
|
||||
"filterMs": 47.79999998211861,
|
||||
"repeat": 1
|
||||
},
|
||||
{
|
||||
"kind": "tasks",
|
||||
"theme": "paper-moments",
|
||||
"size": 100,
|
||||
"initialRenderMs": 38.099999994039536,
|
||||
"requests": [
|
||||
"/api/tasks"
|
||||
],
|
||||
"initialTaskCount": 50,
|
||||
"fullListRenderMs": 116.09999999403954,
|
||||
"fullListIsInjected": true,
|
||||
"domNodes": 1107,
|
||||
"frameGapsMs": {
|
||||
"median": 10,
|
||||
"p95": 20,
|
||||
"max": 59.900000000000034
|
||||
},
|
||||
"frames": 387,
|
||||
"longTasks": [],
|
||||
"scrollTop": 0,
|
||||
"scrollHeight": 11764,
|
||||
"maxScrollTop": 10907,
|
||||
"filteredCount": 34,
|
||||
"expectedFilteredCount": 34,
|
||||
"filterMs": 11.600000023841858,
|
||||
"repeat": 1
|
||||
},
|
||||
{
|
||||
"kind": "tasks",
|
||||
"theme": "paper-moments",
|
||||
"size": 1000,
|
||||
"initialRenderMs": 5.800000011920929,
|
||||
"requests": [
|
||||
"/api/tasks"
|
||||
],
|
||||
"initialTaskCount": 50,
|
||||
"fullListRenderMs": 150,
|
||||
"fullListIsInjected": true,
|
||||
"domNodes": 11007,
|
||||
"frameGapsMs": {
|
||||
"median": 10.100000000000364,
|
||||
"p95": 50.100000000000364,
|
||||
"max": 80
|
||||
},
|
||||
"frames": 368,
|
||||
"longTasks": [],
|
||||
"scrollTop": 54000,
|
||||
"scrollHeight": 115714,
|
||||
"maxScrollTop": 81000,
|
||||
"filteredCount": 334,
|
||||
"expectedFilteredCount": 334,
|
||||
"filterMs": 59.5,
|
||||
"repeat": 1
|
||||
},
|
||||
{
|
||||
"kind": "trace",
|
||||
"theme": "light",
|
||||
"size": 200,
|
||||
"initialRenderMs": 75.10000002384186,
|
||||
"requests": [],
|
||||
"domNodes": 2092,
|
||||
"scrollContainers": [
|
||||
{
|
||||
"node": "HTML",
|
||||
"height": 905,
|
||||
"scrollHeight": 905,
|
||||
"overflow": "hidden",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "BODY",
|
||||
"height": 905,
|
||||
"scrollHeight": 905,
|
||||
"overflow": "hidden",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "viewport",
|
||||
"height": 905,
|
||||
"scrollHeight": 18853,
|
||||
"overflow": "auto",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "app",
|
||||
"height": 18853,
|
||||
"scrollHeight": 18853,
|
||||
"overflow": "visible",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "trace-visualization",
|
||||
"height": 18805,
|
||||
"scrollHeight": 18805,
|
||||
"overflow": "visible",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "timeline-view",
|
||||
"height": 16692,
|
||||
"scrollHeight": 16692,
|
||||
"overflow": "visible",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "timeline",
|
||||
"height": 16692,
|
||||
"scrollHeight": 16692,
|
||||
"overflow": "visible",
|
||||
"position": "relative"
|
||||
}
|
||||
],
|
||||
"frameGapsMs": {
|
||||
"median": 10,
|
||||
"p95": 10.100000000000364,
|
||||
"max": 40.00000000000003
|
||||
},
|
||||
"frames": 411,
|
||||
"longTasks": [],
|
||||
"scrollTop": 0,
|
||||
"scrollHeight": 18853,
|
||||
"maxScrollTop": 17948,
|
||||
"filteredDomNodes": 436,
|
||||
"filteredCount": 44,
|
||||
"expectedFilteredCount": 44,
|
||||
"filterMs": 16,
|
||||
"treeSwitchMs": 32.099999994039536,
|
||||
"treeFilterMs": 27.900000005960464,
|
||||
"treeFilteredDomNodes": 689,
|
||||
"repeat": 1
|
||||
},
|
||||
{
|
||||
"kind": "trace",
|
||||
"theme": "light",
|
||||
"size": 2000,
|
||||
"initialRenderMs": 283.7999999821186,
|
||||
"requests": [],
|
||||
"domNodes": 20542,
|
||||
"scrollContainers": [
|
||||
{
|
||||
"node": "HTML",
|
||||
"height": 905,
|
||||
"scrollHeight": 905,
|
||||
"overflow": "hidden",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "BODY",
|
||||
"height": 905,
|
||||
"scrollHeight": 905,
|
||||
"overflow": "hidden",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "viewport",
|
||||
"height": 905,
|
||||
"scrollHeight": 184678,
|
||||
"overflow": "auto",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "app",
|
||||
"height": 184678,
|
||||
"scrollHeight": 184678,
|
||||
"overflow": "visible",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "trace-visualization",
|
||||
"height": 184630,
|
||||
"scrollHeight": 184630,
|
||||
"overflow": "visible",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "timeline-view",
|
||||
"height": 166992,
|
||||
"scrollHeight": 166992,
|
||||
"overflow": "visible",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "timeline",
|
||||
"height": 166992,
|
||||
"scrollHeight": 166992,
|
||||
"overflow": "visible",
|
||||
"position": "relative"
|
||||
}
|
||||
],
|
||||
"frameGapsMs": {
|
||||
"median": 10,
|
||||
"p95": 10.100000000000364,
|
||||
"max": 20.100000000000023
|
||||
},
|
||||
"frames": 491,
|
||||
"longTasks": [],
|
||||
"scrollTop": 54000,
|
||||
"scrollHeight": 184678,
|
||||
"maxScrollTop": 81000,
|
||||
"filteredDomNodes": 4036,
|
||||
"filteredCount": 444,
|
||||
"expectedFilteredCount": 444,
|
||||
"filterMs": 97.40000000596046,
|
||||
"treeSwitchMs": 64,
|
||||
"treeFilterMs": 617.1999999880791,
|
||||
"treeFilteredDomNodes": 6539,
|
||||
"repeat": 1
|
||||
},
|
||||
{
|
||||
"kind": "trace",
|
||||
"theme": "dark",
|
||||
"size": 200,
|
||||
"initialRenderMs": 81.5,
|
||||
"requests": [],
|
||||
"domNodes": 2092,
|
||||
"scrollContainers": [
|
||||
{
|
||||
"node": "HTML",
|
||||
"height": 905,
|
||||
"scrollHeight": 905,
|
||||
"overflow": "hidden",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "BODY",
|
||||
"height": 905,
|
||||
"scrollHeight": 905,
|
||||
"overflow": "hidden",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "viewport",
|
||||
"height": 905,
|
||||
"scrollHeight": 18853,
|
||||
"overflow": "auto",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "app",
|
||||
"height": 18853,
|
||||
"scrollHeight": 18853,
|
||||
"overflow": "visible",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "trace-visualization",
|
||||
"height": 18805,
|
||||
"scrollHeight": 18805,
|
||||
"overflow": "visible",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "timeline-view",
|
||||
"height": 16692,
|
||||
"scrollHeight": 16692,
|
||||
"overflow": "visible",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "timeline",
|
||||
"height": 16692,
|
||||
"scrollHeight": 16692,
|
||||
"overflow": "visible",
|
||||
"position": "relative"
|
||||
}
|
||||
],
|
||||
"frameGapsMs": {
|
||||
"median": 10,
|
||||
"p95": 10.100000000000364,
|
||||
"max": 30
|
||||
},
|
||||
"frames": 415,
|
||||
"longTasks": [],
|
||||
"scrollTop": 0,
|
||||
"scrollHeight": 18853,
|
||||
"maxScrollTop": 17948,
|
||||
"filteredDomNodes": 436,
|
||||
"filteredCount": 44,
|
||||
"expectedFilteredCount": 44,
|
||||
"filterMs": 16.69999998807907,
|
||||
"treeSwitchMs": 31.099999994039536,
|
||||
"treeFilterMs": 28.900000005960464,
|
||||
"treeFilteredDomNodes": 689,
|
||||
"repeat": 1
|
||||
},
|
||||
{
|
||||
"kind": "trace",
|
||||
"theme": "dark",
|
||||
"size": 2000,
|
||||
"initialRenderMs": 289,
|
||||
"requests": [],
|
||||
"domNodes": 20542,
|
||||
"scrollContainers": [
|
||||
{
|
||||
"node": "HTML",
|
||||
"height": 905,
|
||||
"scrollHeight": 905,
|
||||
"overflow": "hidden",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "BODY",
|
||||
"height": 905,
|
||||
"scrollHeight": 905,
|
||||
"overflow": "hidden",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "viewport",
|
||||
"height": 905,
|
||||
"scrollHeight": 184678,
|
||||
"overflow": "auto",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "app",
|
||||
"height": 184678,
|
||||
"scrollHeight": 184678,
|
||||
"overflow": "visible",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "trace-visualization",
|
||||
"height": 184630,
|
||||
"scrollHeight": 184630,
|
||||
"overflow": "visible",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "timeline-view",
|
||||
"height": 166992,
|
||||
"scrollHeight": 166992,
|
||||
"overflow": "visible",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "timeline",
|
||||
"height": 166992,
|
||||
"scrollHeight": 166992,
|
||||
"overflow": "visible",
|
||||
"position": "relative"
|
||||
}
|
||||
],
|
||||
"frameGapsMs": {
|
||||
"median": 10,
|
||||
"p95": 10.100000000000364,
|
||||
"max": 20.200000000000045
|
||||
},
|
||||
"frames": 487,
|
||||
"longTasks": [],
|
||||
"scrollTop": 54000,
|
||||
"scrollHeight": 184678,
|
||||
"maxScrollTop": 81000,
|
||||
"filteredDomNodes": 4036,
|
||||
"filteredCount": 444,
|
||||
"expectedFilteredCount": 444,
|
||||
"filterMs": 74.5,
|
||||
"treeSwitchMs": 62.900000005960464,
|
||||
"treeFilterMs": 483,
|
||||
"treeFilteredDomNodes": 6539,
|
||||
"repeat": 1
|
||||
},
|
||||
{
|
||||
"kind": "trace",
|
||||
"theme": "paper-moments",
|
||||
"size": 200,
|
||||
"initialRenderMs": 119.59999999403954,
|
||||
"requests": [],
|
||||
"domNodes": 2092,
|
||||
"scrollContainers": [
|
||||
{
|
||||
"node": "HTML",
|
||||
"height": 905,
|
||||
"scrollHeight": 905,
|
||||
"overflow": "hidden",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "BODY",
|
||||
"height": 905,
|
||||
"scrollHeight": 905,
|
||||
"overflow": "hidden",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "viewport",
|
||||
"height": 905,
|
||||
"scrollHeight": 18853,
|
||||
"overflow": "auto",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "app",
|
||||
"height": 18853,
|
||||
"scrollHeight": 18853,
|
||||
"overflow": "visible",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "trace-visualization",
|
||||
"height": 18805,
|
||||
"scrollHeight": 18805,
|
||||
"overflow": "visible",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "timeline-view",
|
||||
"height": 16692,
|
||||
"scrollHeight": 16692,
|
||||
"overflow": "visible",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "timeline",
|
||||
"height": 16692,
|
||||
"scrollHeight": 16692,
|
||||
"overflow": "visible",
|
||||
"position": "relative"
|
||||
}
|
||||
],
|
||||
"frameGapsMs": {
|
||||
"median": 10,
|
||||
"p95": 20,
|
||||
"max": 89.99999999999997
|
||||
},
|
||||
"frames": 394,
|
||||
"longTasks": [],
|
||||
"scrollTop": 0,
|
||||
"scrollHeight": 18853,
|
||||
"maxScrollTop": 17948,
|
||||
"filteredDomNodes": 436,
|
||||
"filteredCount": 44,
|
||||
"expectedFilteredCount": 44,
|
||||
"filterMs": 19.700000017881393,
|
||||
"treeSwitchMs": 40.10000002384186,
|
||||
"treeFilterMs": 19.899999976158142,
|
||||
"treeFilteredDomNodes": 689,
|
||||
"repeat": 1
|
||||
},
|
||||
{
|
||||
"kind": "trace",
|
||||
"theme": "paper-moments",
|
||||
"size": 2000,
|
||||
"initialRenderMs": 337.2999999821186,
|
||||
"requests": [],
|
||||
"domNodes": 20542,
|
||||
"scrollContainers": [
|
||||
{
|
||||
"node": "HTML",
|
||||
"height": 905,
|
||||
"scrollHeight": 905,
|
||||
"overflow": "hidden",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "BODY",
|
||||
"height": 905,
|
||||
"scrollHeight": 905,
|
||||
"overflow": "hidden",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "viewport",
|
||||
"height": 905,
|
||||
"scrollHeight": 184678,
|
||||
"overflow": "auto",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "app",
|
||||
"height": 184678,
|
||||
"scrollHeight": 184678,
|
||||
"overflow": "visible",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "trace-visualization",
|
||||
"height": 184630,
|
||||
"scrollHeight": 184630,
|
||||
"overflow": "visible",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "timeline-view",
|
||||
"height": 166992,
|
||||
"scrollHeight": 166992,
|
||||
"overflow": "visible",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "timeline",
|
||||
"height": 166992,
|
||||
"scrollHeight": 166992,
|
||||
"overflow": "visible",
|
||||
"position": "relative"
|
||||
}
|
||||
],
|
||||
"frameGapsMs": {
|
||||
"median": 10,
|
||||
"p95": 20.100000000000023,
|
||||
"max": 30.100000000000023
|
||||
},
|
||||
"frames": 416,
|
||||
"longTasks": [],
|
||||
"scrollTop": 54000,
|
||||
"scrollHeight": 184678,
|
||||
"maxScrollTop": 81000,
|
||||
"filteredDomNodes": 4036,
|
||||
"filteredCount": 444,
|
||||
"expectedFilteredCount": 444,
|
||||
"filterMs": 86.2999999821186,
|
||||
"treeSwitchMs": 62.099999994039536,
|
||||
"treeFilterMs": 540.0999999940395,
|
||||
"treeFilteredDomNodes": 6539,
|
||||
"repeat": 1
|
||||
},
|
||||
{
|
||||
"kind": "trace",
|
||||
"theme": "paper-moments",
|
||||
"size": 10000,
|
||||
"initialRenderMs": 1803.9000000059605,
|
||||
"requests": [],
|
||||
"domNodes": 102542,
|
||||
"scrollContainers": [
|
||||
{
|
||||
"node": "HTML",
|
||||
"height": 905,
|
||||
"scrollHeight": 905,
|
||||
"overflow": "hidden",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "BODY",
|
||||
"height": 905,
|
||||
"scrollHeight": 905,
|
||||
"overflow": "hidden",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "viewport",
|
||||
"height": 905,
|
||||
"scrollHeight": 921678,
|
||||
"overflow": "auto",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "app",
|
||||
"height": 921678,
|
||||
"scrollHeight": 921678,
|
||||
"overflow": "visible",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "trace-visualization",
|
||||
"height": 921630,
|
||||
"scrollHeight": 921630,
|
||||
"overflow": "visible",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "timeline-view",
|
||||
"height": 834992,
|
||||
"scrollHeight": 834992,
|
||||
"overflow": "visible",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "timeline",
|
||||
"height": 834992,
|
||||
"scrollHeight": 834992,
|
||||
"overflow": "visible",
|
||||
"position": "relative"
|
||||
}
|
||||
],
|
||||
"frameGapsMs": {
|
||||
"median": 20.100000000000364,
|
||||
"p95": 40,
|
||||
"max": 100
|
||||
},
|
||||
"frames": 357,
|
||||
"longTasks": [
|
||||
82,
|
||||
53
|
||||
],
|
||||
"scrollTop": 54000,
|
||||
"scrollHeight": 921678,
|
||||
"maxScrollTop": 81000,
|
||||
"filteredDomNodes": 40036,
|
||||
"filteredCount": 4444,
|
||||
"expectedFilteredCount": 4444,
|
||||
"filterMs": 582.7999999821186,
|
||||
"treeSwitchMs": 317.5,
|
||||
"treeFilterMs": 25914.80000001192,
|
||||
"treeFilteredDomNodes": 32539,
|
||||
"repeat": 1
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,156 @@
|
||||
[
|
||||
{
|
||||
"kind": "trace",
|
||||
"theme": "paper-moments",
|
||||
"size": 2000,
|
||||
"initialRenderMs": 117.19999998807907,
|
||||
"requests": [],
|
||||
"domNodes": 1852,
|
||||
"scrollContainers": [
|
||||
{
|
||||
"node": "HTML",
|
||||
"height": 905,
|
||||
"scrollHeight": 905,
|
||||
"overflow": "hidden",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "BODY",
|
||||
"height": 905,
|
||||
"scrollHeight": 905,
|
||||
"overflow": "hidden",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "viewport",
|
||||
"height": 905,
|
||||
"scrollHeight": 17214,
|
||||
"overflow": "auto",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "app",
|
||||
"height": 17214,
|
||||
"scrollHeight": 17214,
|
||||
"overflow": "visible",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "trace-visualization",
|
||||
"height": 17166,
|
||||
"scrollHeight": 17166,
|
||||
"overflow": "visible",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "timeline-view",
|
||||
"height": 16692,
|
||||
"scrollHeight": 16692,
|
||||
"overflow": "visible",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "timeline",
|
||||
"height": 16692,
|
||||
"scrollHeight": 16692,
|
||||
"overflow": "visible",
|
||||
"position": "relative"
|
||||
}
|
||||
],
|
||||
"frameGapsMs": {
|
||||
"median": 10,
|
||||
"p95": 10.100000000000364,
|
||||
"max": 80.09999999999997
|
||||
},
|
||||
"frames": 408,
|
||||
"longTasks": [],
|
||||
"scrollTop": 0,
|
||||
"scrollHeight": 17214,
|
||||
"maxScrollTop": 16309,
|
||||
"filteredDomNodes": 1844,
|
||||
"filteredCount": 200,
|
||||
"expectedFilteredCount": 200,
|
||||
"filterMs": 71.90000000596046,
|
||||
"treeSwitchMs": 51.400000005960464,
|
||||
"treeFilterMs": 48.70000001788139,
|
||||
"treeFilteredDomNodes": 1343,
|
||||
"repeat": 1
|
||||
},
|
||||
{
|
||||
"kind": "trace",
|
||||
"theme": "paper-moments",
|
||||
"size": 10000,
|
||||
"initialRenderMs": 94.40000000596046,
|
||||
"requests": [],
|
||||
"domNodes": 1852,
|
||||
"scrollContainers": [
|
||||
{
|
||||
"node": "HTML",
|
||||
"height": 905,
|
||||
"scrollHeight": 905,
|
||||
"overflow": "hidden",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "BODY",
|
||||
"height": 905,
|
||||
"scrollHeight": 905,
|
||||
"overflow": "hidden",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "viewport",
|
||||
"height": 905,
|
||||
"scrollHeight": 17214,
|
||||
"overflow": "auto",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "app",
|
||||
"height": 17214,
|
||||
"scrollHeight": 17214,
|
||||
"overflow": "visible",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "trace-visualization",
|
||||
"height": 17166,
|
||||
"scrollHeight": 17166,
|
||||
"overflow": "visible",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "timeline-view",
|
||||
"height": 16692,
|
||||
"scrollHeight": 16692,
|
||||
"overflow": "visible",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "timeline",
|
||||
"height": 16692,
|
||||
"scrollHeight": 16692,
|
||||
"overflow": "visible",
|
||||
"position": "relative"
|
||||
}
|
||||
],
|
||||
"frameGapsMs": {
|
||||
"median": 10,
|
||||
"p95": 10.100000000000364,
|
||||
"max": 50.09999999999991
|
||||
},
|
||||
"frames": 414,
|
||||
"longTasks": [],
|
||||
"scrollTop": 0,
|
||||
"scrollHeight": 17214,
|
||||
"maxScrollTop": 16309,
|
||||
"filteredDomNodes": 1844,
|
||||
"filteredCount": 200,
|
||||
"expectedFilteredCount": 200,
|
||||
"filterMs": 284.90000000596046,
|
||||
"treeSwitchMs": 100.90000000596046,
|
||||
"treeFilterMs": 189.19999998807907,
|
||||
"treeFilteredDomNodes": 1343,
|
||||
"repeat": 1
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,380 @@
|
||||
[
|
||||
{
|
||||
"requestedHan": 25000,
|
||||
"hanCharacters": 25632,
|
||||
"sourceCharacters": 35728,
|
||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/152.0.0.0 Safari/537.36",
|
||||
"viewport": [
|
||||
1424,
|
||||
905
|
||||
],
|
||||
"openMs": 379.09999999403954,
|
||||
"domNodes": 2110,
|
||||
"selectionMs": {
|
||||
"median": 0.4000000059604645,
|
||||
"p95": 0.7000000178813934,
|
||||
"max": 1.300000011920929
|
||||
},
|
||||
"insertMs": {
|
||||
"median": 6.300000011920929,
|
||||
"p95": 9.599999994039536,
|
||||
"max": 10.400000005960464
|
||||
},
|
||||
"foldMs": {
|
||||
"median": 42.900000005960464,
|
||||
"p95": 45.599999994039536,
|
||||
"max": 45.599999994039536
|
||||
},
|
||||
"integrity": true,
|
||||
"previewMs": [
|
||||
176.30000001192093,
|
||||
22.69999998807907,
|
||||
19.80000001192093
|
||||
],
|
||||
"previewNodes": 1058,
|
||||
"longTasks": {
|
||||
"count": 4,
|
||||
"median": 91,
|
||||
"p95": 359,
|
||||
"max": 359
|
||||
},
|
||||
"heapUsedBytes": 36560189,
|
||||
"repeat": 1
|
||||
},
|
||||
{
|
||||
"requestedHan": 25000,
|
||||
"hanCharacters": 25632,
|
||||
"sourceCharacters": 35728,
|
||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/152.0.0.0 Safari/537.36",
|
||||
"viewport": [
|
||||
1424,
|
||||
905
|
||||
],
|
||||
"openMs": 218.59999999403954,
|
||||
"domNodes": 2110,
|
||||
"selectionMs": {
|
||||
"median": 0.29999998211860657,
|
||||
"p95": 0.5,
|
||||
"max": 0.5
|
||||
},
|
||||
"insertMs": {
|
||||
"median": 4.799999982118607,
|
||||
"p95": 6.9000000059604645,
|
||||
"max": 7.699999988079071
|
||||
},
|
||||
"foldMs": {
|
||||
"median": 45.30000001192093,
|
||||
"p95": 79,
|
||||
"max": 79
|
||||
},
|
||||
"integrity": true,
|
||||
"previewMs": [
|
||||
112.90000000596046,
|
||||
27.80000001192093,
|
||||
25.399999976158142
|
||||
],
|
||||
"previewNodes": 1058,
|
||||
"longTasks": {
|
||||
"count": 5,
|
||||
"median": 65,
|
||||
"p95": 198,
|
||||
"max": 198
|
||||
},
|
||||
"heapUsedBytes": 78394355,
|
||||
"repeat": 2
|
||||
},
|
||||
{
|
||||
"requestedHan": 25000,
|
||||
"hanCharacters": 25632,
|
||||
"sourceCharacters": 35728,
|
||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/152.0.0.0 Safari/537.36",
|
||||
"viewport": [
|
||||
1424,
|
||||
905
|
||||
],
|
||||
"openMs": 207.59999999403954,
|
||||
"domNodes": 2110,
|
||||
"selectionMs": {
|
||||
"median": 0.4000000059604645,
|
||||
"p95": 0.5999999940395355,
|
||||
"max": 0.699999988079071
|
||||
},
|
||||
"insertMs": {
|
||||
"median": 4.600000023841858,
|
||||
"p95": 5.9000000059604645,
|
||||
"max": 6.800000011920929
|
||||
},
|
||||
"foldMs": {
|
||||
"median": 35.900000005960464,
|
||||
"p95": 45.400000005960464,
|
||||
"max": 45.400000005960464
|
||||
},
|
||||
"integrity": true,
|
||||
"previewMs": [
|
||||
98.30000001192093,
|
||||
29.69999998807907,
|
||||
29.80000001192093
|
||||
],
|
||||
"previewNodes": 1058,
|
||||
"longTasks": {
|
||||
"count": 4,
|
||||
"median": 59,
|
||||
"p95": 184,
|
||||
"max": 184
|
||||
},
|
||||
"heapUsedBytes": 72765231,
|
||||
"repeat": 3
|
||||
},
|
||||
{
|
||||
"requestedHan": 60000,
|
||||
"hanCharacters": 61172,
|
||||
"sourceCharacters": 85716,
|
||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/152.0.0.0 Safari/537.36",
|
||||
"viewport": [
|
||||
1424,
|
||||
905
|
||||
],
|
||||
"openMs": 394.30000001192093,
|
||||
"domNodes": 4720,
|
||||
"selectionMs": {
|
||||
"median": 0.4000000059604645,
|
||||
"p95": 0.6000000238418579,
|
||||
"max": 0.699999988079071
|
||||
},
|
||||
"insertMs": {
|
||||
"median": 6.300000011920929,
|
||||
"p95": 7.799999982118607,
|
||||
"max": 13.599999994039536
|
||||
},
|
||||
"foldMs": {
|
||||
"median": 95.80000001192093,
|
||||
"p95": 145.5,
|
||||
"max": 145.5
|
||||
},
|
||||
"integrity": true,
|
||||
"previewMs": [
|
||||
180.59999999403954,
|
||||
61.20000001788139,
|
||||
50
|
||||
],
|
||||
"previewNodes": 2560,
|
||||
"longTasks": {
|
||||
"count": 10,
|
||||
"median": 103,
|
||||
"p95": 358,
|
||||
"max": 358
|
||||
},
|
||||
"heapUsedBytes": 73234300,
|
||||
"repeat": 1
|
||||
},
|
||||
{
|
||||
"requestedHan": 60000,
|
||||
"hanCharacters": 61172,
|
||||
"sourceCharacters": 85716,
|
||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/152.0.0.0 Safari/537.36",
|
||||
"viewport": [
|
||||
1424,
|
||||
905
|
||||
],
|
||||
"openMs": 447.5,
|
||||
"domNodes": 4720,
|
||||
"selectionMs": {
|
||||
"median": 0.4000000059604645,
|
||||
"p95": 0.5999999940395355,
|
||||
"max": 0.5999999940395355
|
||||
},
|
||||
"insertMs": {
|
||||
"median": 6.699999988079071,
|
||||
"p95": 12.699999988079071,
|
||||
"max": 14.5
|
||||
},
|
||||
"foldMs": {
|
||||
"median": 99.5,
|
||||
"p95": 110.40000000596046,
|
||||
"max": 110.40000000596046
|
||||
},
|
||||
"integrity": true,
|
||||
"previewMs": [
|
||||
153,
|
||||
44.900000005960464,
|
||||
49.400000005960464
|
||||
],
|
||||
"previewNodes": 2560,
|
||||
"longTasks": {
|
||||
"count": 9,
|
||||
"median": 113,
|
||||
"p95": 410,
|
||||
"max": 410
|
||||
},
|
||||
"heapUsedBytes": 97026266,
|
||||
"repeat": 2
|
||||
},
|
||||
{
|
||||
"requestedHan": 60000,
|
||||
"hanCharacters": 61172,
|
||||
"sourceCharacters": 85716,
|
||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/152.0.0.0 Safari/537.36",
|
||||
"viewport": [
|
||||
1424,
|
||||
905
|
||||
],
|
||||
"openMs": 492.69999998807907,
|
||||
"domNodes": 4720,
|
||||
"selectionMs": {
|
||||
"median": 0.5,
|
||||
"p95": 0.6000000238418579,
|
||||
"max": 1
|
||||
},
|
||||
"insertMs": {
|
||||
"median": 7.199999988079071,
|
||||
"p95": 9.599999994039536,
|
||||
"max": 10.100000023841858
|
||||
},
|
||||
"foldMs": {
|
||||
"median": 115.80000001192093,
|
||||
"p95": 149.7000000178814,
|
||||
"max": 149.7000000178814
|
||||
},
|
||||
"integrity": true,
|
||||
"previewMs": [
|
||||
141.39999997615814,
|
||||
67.5,
|
||||
61.900000005960464
|
||||
],
|
||||
"previewNodes": 2560,
|
||||
"longTasks": {
|
||||
"count": 11,
|
||||
"median": 109,
|
||||
"p95": 445,
|
||||
"max": 445
|
||||
},
|
||||
"heapUsedBytes": 88746335,
|
||||
"repeat": 3
|
||||
},
|
||||
{
|
||||
"requestedHan": 120000,
|
||||
"hanCharacters": 122322,
|
||||
"sourceCharacters": 171613,
|
||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/152.0.0.0 Safari/537.36",
|
||||
"viewport": [
|
||||
1424,
|
||||
905
|
||||
],
|
||||
"openMs": 893.4000000059605,
|
||||
"domNodes": 9139,
|
||||
"selectionMs": {
|
||||
"median": 0.7000000178813934,
|
||||
"p95": 1.2000000178813934,
|
||||
"max": 2.399999976158142
|
||||
},
|
||||
"insertMs": {
|
||||
"median": 18,
|
||||
"p95": 28.900000005960464,
|
||||
"max": 31.5
|
||||
},
|
||||
"foldMs": {
|
||||
"median": 217,
|
||||
"p95": 292.90000000596046,
|
||||
"max": 292.90000000596046
|
||||
},
|
||||
"integrity": true,
|
||||
"previewMs": [
|
||||
203.10000002384186,
|
||||
98.7999999821186,
|
||||
92.30000001192093
|
||||
],
|
||||
"previewNodes": 5117,
|
||||
"longTasks": {
|
||||
"count": 13,
|
||||
"median": 199,
|
||||
"p95": 796,
|
||||
"max": 796
|
||||
},
|
||||
"heapUsedBytes": 113890741,
|
||||
"repeat": 1
|
||||
},
|
||||
{
|
||||
"requestedHan": 120000,
|
||||
"hanCharacters": 122322,
|
||||
"sourceCharacters": 171613,
|
||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/152.0.0.0 Safari/537.36",
|
||||
"viewport": [
|
||||
1424,
|
||||
905
|
||||
],
|
||||
"openMs": 869.0999999940395,
|
||||
"domNodes": 9139,
|
||||
"selectionMs": {
|
||||
"median": 0.7000000178813934,
|
||||
"p95": 1.300000011920929,
|
||||
"max": 3.4000000059604645
|
||||
},
|
||||
"insertMs": {
|
||||
"median": 16.69999998807907,
|
||||
"p95": 22.599999994039536,
|
||||
"max": 22.80000001192093
|
||||
},
|
||||
"foldMs": {
|
||||
"median": 220.5,
|
||||
"p95": 263.09999999403954,
|
||||
"max": 263.09999999403954
|
||||
},
|
||||
"integrity": true,
|
||||
"previewMs": [
|
||||
207.39999997615814,
|
||||
98.7000000178814,
|
||||
90.2999999821186
|
||||
],
|
||||
"previewNodes": 5117,
|
||||
"longTasks": {
|
||||
"count": 14,
|
||||
"median": 205,
|
||||
"p95": 780,
|
||||
"max": 780
|
||||
},
|
||||
"heapUsedBytes": 125636820,
|
||||
"repeat": 2
|
||||
},
|
||||
{
|
||||
"requestedHan": 120000,
|
||||
"hanCharacters": 122322,
|
||||
"sourceCharacters": 171613,
|
||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/152.0.0.0 Safari/537.36",
|
||||
"viewport": [
|
||||
1424,
|
||||
905
|
||||
],
|
||||
"openMs": 845.9000000059605,
|
||||
"domNodes": 9139,
|
||||
"selectionMs": {
|
||||
"median": 0.699999988079071,
|
||||
"p95": 1.0999999940395355,
|
||||
"max": 2.9000000059604645
|
||||
},
|
||||
"insertMs": {
|
||||
"median": 18.69999998807907,
|
||||
"p95": 27.19999998807907,
|
||||
"max": 35
|
||||
},
|
||||
"foldMs": {
|
||||
"median": 205.7000000178814,
|
||||
"p95": 263.90000000596046,
|
||||
"max": 263.90000000596046
|
||||
},
|
||||
"integrity": true,
|
||||
"previewMs": [
|
||||
213.09999999403954,
|
||||
100,
|
||||
91.5
|
||||
],
|
||||
"previewNodes": 5117,
|
||||
"longTasks": {
|
||||
"count": 13,
|
||||
"median": 191,
|
||||
"p95": 768,
|
||||
"max": 768
|
||||
},
|
||||
"heapUsedBytes": 86940861,
|
||||
"repeat": 3
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,380 @@
|
||||
[
|
||||
{
|
||||
"requestedHan": 25000,
|
||||
"hanCharacters": 25632,
|
||||
"sourceCharacters": 35728,
|
||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/152.0.0.0 Safari/537.36",
|
||||
"viewport": [
|
||||
1424,
|
||||
905
|
||||
],
|
||||
"openMs": 398,
|
||||
"domNodes": 2110,
|
||||
"selectionMs": {
|
||||
"median": 1.0999999940395355,
|
||||
"p95": 1.9000000059604645,
|
||||
"max": 1.9000000059604645
|
||||
},
|
||||
"insertMs": {
|
||||
"median": 5.300000011920929,
|
||||
"p95": 8.100000023841858,
|
||||
"max": 8.800000011920929
|
||||
},
|
||||
"foldMs": {
|
||||
"median": 58.70000001788139,
|
||||
"p95": 70.19999998807907,
|
||||
"max": 70.19999998807907
|
||||
},
|
||||
"integrity": true,
|
||||
"previewMs": [
|
||||
230.7999999821186,
|
||||
45.5,
|
||||
39.70000001788139
|
||||
],
|
||||
"previewNodes": 1058,
|
||||
"longTasks": {
|
||||
"count": 5,
|
||||
"median": 84,
|
||||
"p95": 372,
|
||||
"max": 372
|
||||
},
|
||||
"heapUsedBytes": 42428845,
|
||||
"repeat": 1
|
||||
},
|
||||
{
|
||||
"requestedHan": 25000,
|
||||
"hanCharacters": 25632,
|
||||
"sourceCharacters": 35728,
|
||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/152.0.0.0 Safari/537.36",
|
||||
"viewport": [
|
||||
1424,
|
||||
905
|
||||
],
|
||||
"openMs": 272.09999999403954,
|
||||
"domNodes": 2110,
|
||||
"selectionMs": {
|
||||
"median": 1,
|
||||
"p95": 2.0999999940395355,
|
||||
"max": 2.399999976158142
|
||||
},
|
||||
"insertMs": {
|
||||
"median": 5.699999988079071,
|
||||
"p95": 7,
|
||||
"max": 7.300000011920929
|
||||
},
|
||||
"foldMs": {
|
||||
"median": 48.900000005960464,
|
||||
"p95": 55,
|
||||
"max": 55
|
||||
},
|
||||
"integrity": true,
|
||||
"previewMs": [
|
||||
157,
|
||||
37.69999998807907,
|
||||
40
|
||||
],
|
||||
"previewNodes": 1058,
|
||||
"longTasks": {
|
||||
"count": 6,
|
||||
"median": 63,
|
||||
"p95": 245,
|
||||
"max": 245
|
||||
},
|
||||
"heapUsedBytes": 62409024,
|
||||
"repeat": 2
|
||||
},
|
||||
{
|
||||
"requestedHan": 25000,
|
||||
"hanCharacters": 25632,
|
||||
"sourceCharacters": 35728,
|
||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/152.0.0.0 Safari/537.36",
|
||||
"viewport": [
|
||||
1424,
|
||||
905
|
||||
],
|
||||
"openMs": 224.90000000596046,
|
||||
"domNodes": 2110,
|
||||
"selectionMs": {
|
||||
"median": 0.7000000178813934,
|
||||
"p95": 1.4000000059604645,
|
||||
"max": 2
|
||||
},
|
||||
"insertMs": {
|
||||
"median": 4.399999976158142,
|
||||
"p95": 6.4000000059604645,
|
||||
"max": 8
|
||||
},
|
||||
"foldMs": {
|
||||
"median": 39.099999994039536,
|
||||
"p95": 44.10000002384186,
|
||||
"max": 44.10000002384186
|
||||
},
|
||||
"integrity": true,
|
||||
"previewMs": [
|
||||
139,
|
||||
46.099999994039536,
|
||||
39.900000005960464
|
||||
],
|
||||
"previewNodes": 1058,
|
||||
"longTasks": {
|
||||
"count": 4,
|
||||
"median": 92,
|
||||
"p95": 200,
|
||||
"max": 200
|
||||
},
|
||||
"heapUsedBytes": 35903770,
|
||||
"repeat": 3
|
||||
},
|
||||
{
|
||||
"requestedHan": 60000,
|
||||
"hanCharacters": 61172,
|
||||
"sourceCharacters": 85716,
|
||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/152.0.0.0 Safari/537.36",
|
||||
"viewport": [
|
||||
1424,
|
||||
905
|
||||
],
|
||||
"openMs": 458.39999997615814,
|
||||
"domNodes": 4720,
|
||||
"selectionMs": {
|
||||
"median": 2.9000000059604645,
|
||||
"p95": 5.699999988079071,
|
||||
"max": 6.0999999940395355
|
||||
},
|
||||
"insertMs": {
|
||||
"median": 7.5999999940395355,
|
||||
"p95": 9.699999988079071,
|
||||
"max": 12.400000005960464
|
||||
},
|
||||
"foldMs": {
|
||||
"median": 120.30000001192093,
|
||||
"p95": 160.09999999403954,
|
||||
"max": 160.09999999403954
|
||||
},
|
||||
"integrity": true,
|
||||
"previewMs": [
|
||||
173.5,
|
||||
65.60000002384186,
|
||||
70.09999999403954
|
||||
],
|
||||
"previewNodes": 2560,
|
||||
"longTasks": {
|
||||
"count": 12,
|
||||
"median": 110,
|
||||
"p95": 415,
|
||||
"max": 415
|
||||
},
|
||||
"heapUsedBytes": 60644006,
|
||||
"repeat": 1
|
||||
},
|
||||
{
|
||||
"requestedHan": 60000,
|
||||
"hanCharacters": 61172,
|
||||
"sourceCharacters": 85716,
|
||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/152.0.0.0 Safari/537.36",
|
||||
"viewport": [
|
||||
1424,
|
||||
905
|
||||
],
|
||||
"openMs": 649.6999999880791,
|
||||
"domNodes": 4720,
|
||||
"selectionMs": {
|
||||
"median": 2.699999988079071,
|
||||
"p95": 5.699999988079071,
|
||||
"max": 5.800000011920929
|
||||
},
|
||||
"insertMs": {
|
||||
"median": 7.5,
|
||||
"p95": 9.099999994039536,
|
||||
"max": 10.699999988079071
|
||||
},
|
||||
"foldMs": {
|
||||
"median": 116,
|
||||
"p95": 149.09999999403954,
|
||||
"max": 149.09999999403954
|
||||
},
|
||||
"integrity": true,
|
||||
"previewMs": [
|
||||
209.30000001192093,
|
||||
80.90000000596046,
|
||||
88.7999999821186
|
||||
],
|
||||
"previewNodes": 2560,
|
||||
"longTasks": {
|
||||
"count": 12,
|
||||
"median": 116,
|
||||
"p95": 586,
|
||||
"max": 586
|
||||
},
|
||||
"heapUsedBytes": 64379838,
|
||||
"repeat": 2
|
||||
},
|
||||
{
|
||||
"requestedHan": 60000,
|
||||
"hanCharacters": 61172,
|
||||
"sourceCharacters": 85716,
|
||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/152.0.0.0 Safari/537.36",
|
||||
"viewport": [
|
||||
1424,
|
||||
905
|
||||
],
|
||||
"openMs": 519.7000000178814,
|
||||
"domNodes": 4720,
|
||||
"selectionMs": {
|
||||
"median": 2.9000000059604645,
|
||||
"p95": 4.9000000059604645,
|
||||
"max": 5.5
|
||||
},
|
||||
"insertMs": {
|
||||
"median": 9.200000017881393,
|
||||
"p95": 11.700000017881393,
|
||||
"max": 11.900000005960464
|
||||
},
|
||||
"foldMs": {
|
||||
"median": 118.40000000596046,
|
||||
"p95": 134.5,
|
||||
"max": 134.5
|
||||
},
|
||||
"integrity": true,
|
||||
"previewMs": [
|
||||
198.5,
|
||||
84.80000001192093,
|
||||
91.59999999403954
|
||||
],
|
||||
"previewNodes": 2560,
|
||||
"longTasks": {
|
||||
"count": 11,
|
||||
"median": 119,
|
||||
"p95": 469,
|
||||
"max": 469
|
||||
},
|
||||
"heapUsedBytes": 43218088,
|
||||
"repeat": 3
|
||||
},
|
||||
{
|
||||
"requestedHan": 120000,
|
||||
"hanCharacters": 122322,
|
||||
"sourceCharacters": 171613,
|
||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/152.0.0.0 Safari/537.36",
|
||||
"viewport": [
|
||||
1424,
|
||||
905
|
||||
],
|
||||
"openMs": 894.6000000238419,
|
||||
"domNodes": 9139,
|
||||
"selectionMs": {
|
||||
"median": 7.9000000059604645,
|
||||
"p95": 11.599999994039536,
|
||||
"max": 24.700000017881393
|
||||
},
|
||||
"insertMs": {
|
||||
"median": 18.19999998807907,
|
||||
"p95": 22.19999998807907,
|
||||
"max": 30.799999982118607
|
||||
},
|
||||
"foldMs": {
|
||||
"median": 247.59999999403954,
|
||||
"p95": 256.59999999403954,
|
||||
"max": 256.59999999403954
|
||||
},
|
||||
"integrity": true,
|
||||
"previewMs": [
|
||||
294.2999999821186,
|
||||
134.09999999403954,
|
||||
129.90000000596046
|
||||
],
|
||||
"previewNodes": 5117,
|
||||
"longTasks": {
|
||||
"count": 14,
|
||||
"median": 207,
|
||||
"p95": 821,
|
||||
"max": 821
|
||||
},
|
||||
"heapUsedBytes": 60930415,
|
||||
"repeat": 1
|
||||
},
|
||||
{
|
||||
"requestedHan": 120000,
|
||||
"hanCharacters": 122322,
|
||||
"sourceCharacters": 171613,
|
||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/152.0.0.0 Safari/537.36",
|
||||
"viewport": [
|
||||
1424,
|
||||
905
|
||||
],
|
||||
"openMs": 875.3999999761581,
|
||||
"domNodes": 9139,
|
||||
"selectionMs": {
|
||||
"median": 9.199999988079071,
|
||||
"p95": 15.199999988079071,
|
||||
"max": 15.900000005960464
|
||||
},
|
||||
"insertMs": {
|
||||
"median": 20.599999994039536,
|
||||
"p95": 23.19999998807907,
|
||||
"max": 26.5
|
||||
},
|
||||
"foldMs": {
|
||||
"median": 244.09999999403954,
|
||||
"p95": 269,
|
||||
"max": 269
|
||||
},
|
||||
"integrity": true,
|
||||
"previewMs": [
|
||||
272.2999999821186,
|
||||
146.30000001192093,
|
||||
157.40000000596046
|
||||
],
|
||||
"previewNodes": 5117,
|
||||
"longTasks": {
|
||||
"count": 14,
|
||||
"median": 192,
|
||||
"p95": 785,
|
||||
"max": 785
|
||||
},
|
||||
"heapUsedBytes": 31982024,
|
||||
"repeat": 2
|
||||
},
|
||||
{
|
||||
"requestedHan": 120000,
|
||||
"hanCharacters": 122322,
|
||||
"sourceCharacters": 171613,
|
||||
"userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/152.0.0.0 Safari/537.36",
|
||||
"viewport": [
|
||||
1424,
|
||||
905
|
||||
],
|
||||
"openMs": 842.3000000119209,
|
||||
"domNodes": 9139,
|
||||
"selectionMs": {
|
||||
"median": 8,
|
||||
"p95": 11.900000005960464,
|
||||
"max": 15.199999988079071
|
||||
},
|
||||
"insertMs": {
|
||||
"median": 18.900000005960464,
|
||||
"p95": 20.099999994039536,
|
||||
"max": 21.700000017881393
|
||||
},
|
||||
"foldMs": {
|
||||
"median": 212.5,
|
||||
"p95": 240.5,
|
||||
"max": 240.5
|
||||
},
|
||||
"integrity": true,
|
||||
"previewMs": [
|
||||
253.7000000178814,
|
||||
129.19999998807907,
|
||||
172
|
||||
],
|
||||
"previewNodes": 5117,
|
||||
"longTasks": {
|
||||
"count": 14,
|
||||
"median": 191,
|
||||
"p95": 762,
|
||||
"max": 762
|
||||
},
|
||||
"heapUsedBytes": 49460811,
|
||||
"repeat": 3
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,122 @@
|
||||
[
|
||||
{
|
||||
"requestedHan": 25000,
|
||||
"theme": "paper-moments",
|
||||
"frameGapsMs": {
|
||||
"median": 10,
|
||||
"p95": 20.100000000000364,
|
||||
"max": 110.09999999999991
|
||||
},
|
||||
"frames": 380,
|
||||
"framesOver25ms": 14,
|
||||
"longTasks": [
|
||||
97
|
||||
],
|
||||
"scrollTop": 6111,
|
||||
"scrollHeight": 33908,
|
||||
"foldedScrollTop": 0,
|
||||
"caretAfterFold": 1,
|
||||
"repeat": 1
|
||||
},
|
||||
{
|
||||
"requestedHan": 25000,
|
||||
"theme": "paper-moments",
|
||||
"frameGapsMs": {
|
||||
"median": 10,
|
||||
"p95": 20.100000000000136,
|
||||
"max": 50
|
||||
},
|
||||
"frames": 374,
|
||||
"framesOver25ms": 15,
|
||||
"longTasks": [
|
||||
57
|
||||
],
|
||||
"scrollTop": 6111,
|
||||
"scrollHeight": 33908,
|
||||
"foldedScrollTop": 0,
|
||||
"caretAfterFold": 1,
|
||||
"repeat": 2
|
||||
},
|
||||
{
|
||||
"requestedHan": 60000,
|
||||
"theme": "paper-moments",
|
||||
"frameGapsMs": {
|
||||
"median": 30.100000000000364,
|
||||
"p95": 50,
|
||||
"max": 100
|
||||
},
|
||||
"frames": 267,
|
||||
"framesOver25ms": 210,
|
||||
"longTasks": [
|
||||
81,
|
||||
84
|
||||
],
|
||||
"scrollTop": 52492,
|
||||
"scrollHeight": 80287,
|
||||
"foldedScrollTop": 0,
|
||||
"caretAfterFold": 1,
|
||||
"repeat": 1
|
||||
},
|
||||
{
|
||||
"requestedHan": 60000,
|
||||
"theme": "paper-moments",
|
||||
"frameGapsMs": {
|
||||
"median": 30,
|
||||
"p95": 40.100000000000364,
|
||||
"max": 100
|
||||
},
|
||||
"frames": 279,
|
||||
"framesOver25ms": 213,
|
||||
"longTasks": [
|
||||
77,
|
||||
59
|
||||
],
|
||||
"scrollTop": 52493,
|
||||
"scrollHeight": 80287,
|
||||
"foldedScrollTop": 0,
|
||||
"caretAfterFold": 1,
|
||||
"repeat": 2
|
||||
},
|
||||
{
|
||||
"requestedHan": 120000,
|
||||
"theme": "paper-moments",
|
||||
"frameGapsMs": {
|
||||
"median": 70,
|
||||
"p95": 100,
|
||||
"max": 130
|
||||
},
|
||||
"frames": 264,
|
||||
"framesOver25ms": 229,
|
||||
"longTasks": [
|
||||
84,
|
||||
52,
|
||||
89,
|
||||
58
|
||||
],
|
||||
"scrollTop": 53157,
|
||||
"scrollHeight": 159554,
|
||||
"foldedScrollTop": 0,
|
||||
"caretAfterFold": 1,
|
||||
"repeat": 1
|
||||
},
|
||||
{
|
||||
"requestedHan": 120000,
|
||||
"theme": "paper-moments",
|
||||
"frameGapsMs": {
|
||||
"median": 70.09999999999854,
|
||||
"p95": 100,
|
||||
"max": 130.10000000000036
|
||||
},
|
||||
"frames": 261,
|
||||
"framesOver25ms": 230,
|
||||
"longTasks": [
|
||||
83,
|
||||
53
|
||||
],
|
||||
"scrollTop": 53195,
|
||||
"scrollHeight": 159554,
|
||||
"foldedScrollTop": 0,
|
||||
"caretAfterFold": 1,
|
||||
"repeat": 2
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,119 @@
|
||||
[
|
||||
{
|
||||
"requestedHan": 25000,
|
||||
"theme": "paper-moments",
|
||||
"frameGapsMs": {
|
||||
"median": 10,
|
||||
"p95": 30.09999999999991,
|
||||
"max": 120.10000000000002
|
||||
},
|
||||
"frames": 356,
|
||||
"framesOver25ms": 45,
|
||||
"longTasks": [
|
||||
116
|
||||
],
|
||||
"scrollTop": 6075,
|
||||
"scrollHeight": 33871,
|
||||
"foldedScrollTop": 0,
|
||||
"caretAfterFold": 1,
|
||||
"repeat": 1
|
||||
},
|
||||
{
|
||||
"requestedHan": 25000,
|
||||
"theme": "paper-moments",
|
||||
"frameGapsMs": {
|
||||
"median": 10,
|
||||
"p95": 30,
|
||||
"max": 80.10000000000002
|
||||
},
|
||||
"frames": 369,
|
||||
"framesOver25ms": 29,
|
||||
"longTasks": [
|
||||
93
|
||||
],
|
||||
"scrollTop": 6111,
|
||||
"scrollHeight": 33908,
|
||||
"foldedScrollTop": 0,
|
||||
"caretAfterFold": 1,
|
||||
"repeat": 2
|
||||
},
|
||||
{
|
||||
"requestedHan": 60000,
|
||||
"theme": "paper-moments",
|
||||
"frameGapsMs": {
|
||||
"median": 40,
|
||||
"p95": 59.900000000001455,
|
||||
"max": 100.09999999999991
|
||||
},
|
||||
"frames": 264,
|
||||
"framesOver25ms": 221,
|
||||
"longTasks": [
|
||||
92
|
||||
],
|
||||
"scrollTop": 52345,
|
||||
"scrollHeight": 80177,
|
||||
"foldedScrollTop": 0,
|
||||
"caretAfterFold": 1,
|
||||
"repeat": 1
|
||||
},
|
||||
{
|
||||
"requestedHan": 60000,
|
||||
"theme": "paper-moments",
|
||||
"frameGapsMs": {
|
||||
"median": 40,
|
||||
"p95": 50.100000000000364,
|
||||
"max": 130.10000000000036
|
||||
},
|
||||
"frames": 265,
|
||||
"framesOver25ms": 229,
|
||||
"longTasks": [
|
||||
84,
|
||||
109
|
||||
],
|
||||
"scrollTop": 52344,
|
||||
"scrollHeight": 80177,
|
||||
"foldedScrollTop": 0,
|
||||
"caretAfterFold": 1,
|
||||
"repeat": 2
|
||||
},
|
||||
{
|
||||
"requestedHan": 120000,
|
||||
"theme": "paper-moments",
|
||||
"frameGapsMs": {
|
||||
"median": 70,
|
||||
"p95": 90.10000000000036,
|
||||
"max": 170.19999999999982
|
||||
},
|
||||
"frames": 260,
|
||||
"framesOver25ms": 235,
|
||||
"longTasks": [
|
||||
89,
|
||||
77
|
||||
],
|
||||
"scrollTop": 53200,
|
||||
"scrollHeight": 159554,
|
||||
"foldedScrollTop": 0,
|
||||
"caretAfterFold": 1,
|
||||
"repeat": 1
|
||||
},
|
||||
{
|
||||
"requestedHan": 120000,
|
||||
"theme": "paper-moments",
|
||||
"frameGapsMs": {
|
||||
"median": 70,
|
||||
"p95": 90.10000000000036,
|
||||
"max": 140.10000000000036
|
||||
},
|
||||
"frames": 259,
|
||||
"framesOver25ms": 228,
|
||||
"longTasks": [
|
||||
92,
|
||||
57
|
||||
],
|
||||
"scrollTop": 53196,
|
||||
"scrollHeight": 159554,
|
||||
"foldedScrollTop": 0,
|
||||
"caretAfterFold": 1,
|
||||
"repeat": 2
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,150 @@
|
||||
{
|
||||
"light": {
|
||||
"requestedHan": 120000,
|
||||
"theme": "light",
|
||||
"variant": "default",
|
||||
"frameGapsMs": {
|
||||
"median": 10,
|
||||
"p95": 30,
|
||||
"max": 90.09999999999991
|
||||
},
|
||||
"frames": 403,
|
||||
"framesOver25ms": 29,
|
||||
"longTasks": [
|
||||
89
|
||||
],
|
||||
"scrollTop": 54000,
|
||||
"scrollHeight": 168515,
|
||||
"foldedScrollTop": 0,
|
||||
"caretAfterFold": 1,
|
||||
"repeat": 1
|
||||
},
|
||||
"dark": {
|
||||
"requestedHan": 120000,
|
||||
"theme": "dark",
|
||||
"variant": "default",
|
||||
"frameGapsMs": {
|
||||
"median": 10,
|
||||
"p95": 30,
|
||||
"max": 90
|
||||
},
|
||||
"frames": 408,
|
||||
"framesOver25ms": 27,
|
||||
"longTasks": [
|
||||
88
|
||||
],
|
||||
"scrollTop": 54000,
|
||||
"scrollHeight": 168515,
|
||||
"foldedScrollTop": 0,
|
||||
"caretAfterFold": 1,
|
||||
"repeat": 1
|
||||
},
|
||||
"fixed": [
|
||||
{
|
||||
"requestedHan": 120000,
|
||||
"theme": "paper-moments",
|
||||
"variant": "default",
|
||||
"frameGapsMs": {
|
||||
"median": 10,
|
||||
"p95": 30.100000000000136,
|
||||
"max": 100
|
||||
},
|
||||
"frames": 422,
|
||||
"framesOver25ms": 31,
|
||||
"longTasks": [
|
||||
99
|
||||
],
|
||||
"scrollTop": 54037,
|
||||
"scrollHeight": 160247,
|
||||
"foldedScrollTop": 0,
|
||||
"caretAfterFold": 1,
|
||||
"repeat": 1
|
||||
},
|
||||
{
|
||||
"requestedHan": 120000,
|
||||
"theme": "paper-moments",
|
||||
"variant": "default",
|
||||
"frameGapsMs": {
|
||||
"median": 10,
|
||||
"p95": 30,
|
||||
"max": 90
|
||||
},
|
||||
"frames": 427,
|
||||
"framesOver25ms": 31,
|
||||
"longTasks": [
|
||||
84,
|
||||
58
|
||||
],
|
||||
"scrollTop": 54000,
|
||||
"scrollHeight": 160211,
|
||||
"foldedScrollTop": 0,
|
||||
"caretAfterFold": 1,
|
||||
"repeat": 2
|
||||
},
|
||||
{
|
||||
"requestedHan": 120000,
|
||||
"theme": "paper-moments",
|
||||
"variant": "default",
|
||||
"frameGapsMs": {
|
||||
"median": 10,
|
||||
"p95": 30.09999999999991,
|
||||
"max": 90.09999999999991
|
||||
},
|
||||
"frames": 422,
|
||||
"framesOver25ms": 29,
|
||||
"longTasks": [
|
||||
85
|
||||
],
|
||||
"scrollTop": 54037,
|
||||
"scrollHeight": 160247,
|
||||
"foldedScrollTop": 0,
|
||||
"caretAfterFold": 1,
|
||||
"repeat": 3
|
||||
}
|
||||
],
|
||||
"outlineDisabled": [
|
||||
{
|
||||
"requestedHan": 120000,
|
||||
"theme": "paper-moments",
|
||||
"variant": "no-outline",
|
||||
"frameGapsMs": {
|
||||
"median": 10,
|
||||
"p95": 30.099999999999454,
|
||||
"max": 100
|
||||
},
|
||||
"frames": 418,
|
||||
"framesOver25ms": 31,
|
||||
"longTasks": [
|
||||
101
|
||||
],
|
||||
"scrollTop": 54037,
|
||||
"scrollHeight": 160247,
|
||||
"foldedScrollTop": 0,
|
||||
"caretAfterFold": 1,
|
||||
"repeat": 1
|
||||
},
|
||||
{
|
||||
"requestedHan": 120000,
|
||||
"theme": "paper-moments",
|
||||
"variant": "no-outline",
|
||||
"frameGapsMs": {
|
||||
"median": 10,
|
||||
"p95": 30,
|
||||
"max": 99.89999999999964
|
||||
},
|
||||
"frames": 413,
|
||||
"framesOver25ms": 32,
|
||||
"longTasks": [
|
||||
87,
|
||||
50,
|
||||
52,
|
||||
52
|
||||
],
|
||||
"scrollTop": 53965,
|
||||
"scrollHeight": 160174,
|
||||
"foldedScrollTop": 0,
|
||||
"caretAfterFold": 1,
|
||||
"repeat": 2
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
[
|
||||
{
|
||||
"requestedHan": 120000,
|
||||
"theme": "paper-moments",
|
||||
"frameGapsMs": {
|
||||
"median": 70.29999999999927,
|
||||
"p95": 100.20000000000073,
|
||||
"max": 210.20000000000073
|
||||
},
|
||||
"frames": 308,
|
||||
"framesOver25ms": 286,
|
||||
"longTasks": [
|
||||
86,
|
||||
54,
|
||||
56,
|
||||
62,
|
||||
50,
|
||||
58,
|
||||
53,
|
||||
52,
|
||||
58,
|
||||
100,
|
||||
107,
|
||||
96,
|
||||
60,
|
||||
99,
|
||||
89,
|
||||
136,
|
||||
101,
|
||||
98,
|
||||
101,
|
||||
90,
|
||||
66,
|
||||
120,
|
||||
74,
|
||||
99,
|
||||
58
|
||||
],
|
||||
"scrollTop": 53127,
|
||||
"scrollHeight": 159554,
|
||||
"foldedScrollTop": 0,
|
||||
"caretAfterFold": 1,
|
||||
"repeat": 1
|
||||
},
|
||||
{
|
||||
"requestedHan": 120000,
|
||||
"theme": "paper-moments",
|
||||
"frameGapsMs": {
|
||||
"median": 70,
|
||||
"p95": 90,
|
||||
"max": 150
|
||||
},
|
||||
"frames": 261,
|
||||
"framesOver25ms": 235,
|
||||
"longTasks": [
|
||||
84,
|
||||
67,
|
||||
52
|
||||
],
|
||||
"scrollTop": 53233,
|
||||
"scrollHeight": 159554,
|
||||
"foldedScrollTop": 0,
|
||||
"caretAfterFold": 1,
|
||||
"repeat": 2
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,29 @@
|
||||
{
|
||||
"blocks": 4000,
|
||||
"dimensions": 384,
|
||||
"top_k": 20,
|
||||
"migration_ms": 1329.5076999929734,
|
||||
"same_top_k": true,
|
||||
"measurements": {
|
||||
"python_json_scan": {
|
||||
"median_ms": 1289.638800022658,
|
||||
"samples_ms": [
|
||||
1289.638800022658,
|
||||
1238.6701999930665,
|
||||
1115.6752999813762,
|
||||
1436.7559000093024,
|
||||
1833.9683999947738
|
||||
]
|
||||
},
|
||||
"sqlite_vec": {
|
||||
"median_ms": 19.673499977216125,
|
||||
"samples_ms": [
|
||||
29.709700000239536,
|
||||
17.876600002637133,
|
||||
35.13619999284856,
|
||||
19.673499977216125,
|
||||
18.28439999371767
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"transport": "real loopback HTTP, separate Uvicorn process",
|
||||
"tasks": 1000,
|
||||
"concurrency": 20,
|
||||
"elapsed_ms": 24509.81,
|
||||
"latencies": {
|
||||
"create": {
|
||||
"count": 1000,
|
||||
"p95_ms": 157.68,
|
||||
"max_ms": 186.7
|
||||
},
|
||||
"update": {
|
||||
"count": 1000,
|
||||
"p95_ms": 208.68,
|
||||
"max_ms": 259.91
|
||||
},
|
||||
"list": {
|
||||
"count": 11,
|
||||
"p95_ms": 23.39,
|
||||
"max_ms": 23.39
|
||||
},
|
||||
"delete": {
|
||||
"count": 1000,
|
||||
"p95_ms": 205.45,
|
||||
"max_ms": 279.12
|
||||
},
|
||||
"health": {
|
||||
"count": 375,
|
||||
"p95_ms": 38.64,
|
||||
"max_ms": 164.76
|
||||
}
|
||||
},
|
||||
"health_errors": [],
|
||||
"pagination_complete": true,
|
||||
"final_total": 0
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"transport": "real loopback HTTP, separate Uvicorn process",
|
||||
"tasks": 1000,
|
||||
"concurrency": 20,
|
||||
"elapsed_ms": 18312.92,
|
||||
"latencies": {
|
||||
"create": {
|
||||
"count": 1000,
|
||||
"p95_ms": 116.45,
|
||||
"max_ms": 134.91
|
||||
},
|
||||
"update": {
|
||||
"count": 1000,
|
||||
"p95_ms": 159.29,
|
||||
"max_ms": 193.37
|
||||
},
|
||||
"list": {
|
||||
"count": 11,
|
||||
"p95_ms": 20.96,
|
||||
"max_ms": 20.96
|
||||
},
|
||||
"delete": {
|
||||
"count": 1000,
|
||||
"p95_ms": 156.43,
|
||||
"max_ms": 190.1
|
||||
},
|
||||
"health": {
|
||||
"count": 117,
|
||||
"p95_ms": 157.0,
|
||||
"max_ms": 195.07
|
||||
}
|
||||
},
|
||||
"health_errors": [],
|
||||
"pagination_complete": true,
|
||||
"final_total": 0
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
[
|
||||
{
|
||||
"kind": "tasks",
|
||||
"theme": "paper-moments",
|
||||
"size": 1000,
|
||||
"initialRenderMs": 173,
|
||||
"requests": [
|
||||
"/api/tasks?limit=100&offset=0",
|
||||
"/api/tasks?limit=100&offset=100",
|
||||
"/api/tasks?limit=100&offset=200",
|
||||
"/api/tasks?limit=100&offset=300",
|
||||
"/api/tasks?limit=100&offset=400",
|
||||
"/api/tasks?limit=100&offset=500",
|
||||
"/api/tasks?limit=100&offset=600",
|
||||
"/api/tasks?limit=100&offset=700",
|
||||
"/api/tasks?limit=100&offset=800",
|
||||
"/api/tasks?limit=100&offset=900"
|
||||
],
|
||||
"initialTaskCount": 1000,
|
||||
"fullListRenderMs": 85.39999997615814,
|
||||
"fullListIsInjected": true,
|
||||
"renderedTasks": 100,
|
||||
"domNodes": 1111,
|
||||
"scrollContainers": [
|
||||
{
|
||||
"node": "HTML",
|
||||
"height": 905,
|
||||
"scrollHeight": 905,
|
||||
"overflow": "hidden",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "BODY",
|
||||
"height": 905,
|
||||
"scrollHeight": 905,
|
||||
"overflow": "hidden",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "viewport",
|
||||
"height": 905,
|
||||
"scrollHeight": 905,
|
||||
"overflow": "auto",
|
||||
"position": "static"
|
||||
},
|
||||
{
|
||||
"node": "app",
|
||||
"height": 905,
|
||||
"scrollHeight": 905,
|
||||
"overflow": "hidden",
|
||||
"position": "static"
|
||||
}
|
||||
],
|
||||
"frameGapsMs": {
|
||||
"median": 10,
|
||||
"p95": 30,
|
||||
"max": 50.10000000000002
|
||||
},
|
||||
"frames": 384,
|
||||
"longTasks": [],
|
||||
"scrollTop": 0,
|
||||
"scrollHeight": 11798,
|
||||
"maxScrollTop": 10941,
|
||||
"filteredCount": 100,
|
||||
"totalFilteredCount": 334,
|
||||
"expectedFilteredCount": 100,
|
||||
"filterMs": 18.69999998807907,
|
||||
"repeat": 1
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1,101 @@
|
||||
# 后台运行日志与压力问题修复
|
||||
|
||||
## 1. 范围与入口
|
||||
|
||||
本次针对 Agent 与任务压测发现的历史记录截断、同步数据库写入阻塞事件循环、长 Trace 树形筛选过慢进行修复,并增加统一运行日志。
|
||||
|
||||
主导航的「日志」打开 `/logs`。知识库选择页也有入口;无需成功打开 Vault 即可查看。需要 AI Core 正常提供 HTTP 服务。后台未启动时,页面显示连接错误,不伪造历史结果。
|
||||
|
||||
页面提供级别、模块、事件名/错误码/关联 ID 筛选及详情展开。日志列表高度受限,按时间从旧到新显示,默认每 5 秒获取新日志并跟随到底部。向上滚动时暂停跟随,抵达顶部自动加载更早日志并保持阅读位置;可一键回到最新。隐藏页面和卸载后停止轮询。界面最多保留当前浏览窗口的 500 条,继续读取旧日志时移出另一端的记录,后台保留窗口不受影响。所有组件使用已有主题变量、卡片、按钮、下拉框及 `ui-disclosure` 展开样式。
|
||||
|
||||
## 2. 日志覆盖
|
||||
|
||||
| 模块 | 记录内容 | 定位信息 |
|
||||
| --- | --- | --- |
|
||||
| vectors | 后台索引状态、向量调用失败、是否使用本地索引回退 | job_id、错误码、异常类型、调用位置、批次数量 |
|
||||
| models | 本地模型/远程模型运行诊断、CUDA/CPU、失败与回退 | 模型、设备、状态、错误码、耗时 |
|
||||
| agent | 创建运行、模型轮次、工具调用与结果、权限决策、完成/失败/取消 | run_id、Provider、模型、步骤、事件序号、工具名 |
|
||||
| tasks | 创建、修改、删除及不存在的删除目标 | task_id、关联 note_id、修改字段名、状态 |
|
||||
| providers / chat | 模型请求完成或未完整结束、流式模型错误、对话失败 | Provider、模型、request_id、run_id、错误码 |
|
||||
| http / api | HTTP 写操作、失败请求、超过一秒的请求及业务错误 | HTTP 方法、路由模板、状态码、耗时、request_id、资源 ID |
|
||||
| system / Python logger | 服务启动与停止,以及应用、服务器和依赖库的 warning/error | 模块、代码位置、异常类型 |
|
||||
|
||||
`X-Request-ID` 响应头可与日志中的 request_id 对照。请求上下文通过 ContextVar 传播到后台任务和线程;Agent 内部工具触发的日志还带 run_id。查询日志自身以及正常短轮询不生成 HTTP 操作日志,避免轮询放大日志量。
|
||||
|
||||
这里只记录操作诊断,不替代完整 Agent Trace、Token 用量台账和模型诊断表。旧代码 logger 的自由文本可能包含笔记或厂商返回,因此桥接时只记录级别、模块、代码位置和异常类型;需要业务错误码的地方使用结构化接口。
|
||||
|
||||
## 3. 存储、容量与隐私
|
||||
|
||||
- 位置:`APP_DATA_DIR/logs/operations.sqlite3`,与业务数据库独立,应用重启后可继续查看。
|
||||
- 保留最近 20,000 条;每批写入时淘汰更早的记录。不是按天永久归档。
|
||||
- 后台线程批量写入,队列最多 4,096 条,一批最多 128 条。队列满时丢弃新诊断记录并计数,绝不阻塞保存或模型推理。
|
||||
- 日志页面显示待写入数量、队列溢出和写入失败数量。计数属于当前进程;重启后重置。存储不可读时显示请求失败。
|
||||
- 正常退出先停止 Agent 和其他后台工作,再排空日志队列;强制终止进程可能丢失尚未写入的队列内容。
|
||||
- 不记录请求/响应正文、系统提示词、工具参数/输出、笔记标题或正文、凭据、原始异常消息、查询字符串。元数据按白名单筛选并限长,Bearer 和 `sk-` 凭据形式额外脱敏。
|
||||
- API 仅返回保留窗口内的诊断数据,不提供任意文件读取和日志删除接口。
|
||||
|
||||
## 4. 开发接口
|
||||
|
||||
```python
|
||||
from app.operation_logs import log_event
|
||||
|
||||
log_event('vectors', 'embedding.failed', level='ERROR', error=exc,
|
||||
model=model_id, job_id=job_id, error_code='EMBEDDING_UNAVAILABLE',
|
||||
fallback='local_index')
|
||||
```
|
||||
|
||||
第一个参数是模块名。`source` 是可选的元数据字段,例如 `local` 或 `api`,不要与模块名混淆。事件名应使用开发时定义的短常量。不要把正文、URL、异常消息或用户输入拼入事件名。
|
||||
|
||||
`GET /api/logs` 参数:
|
||||
|
||||
| 参数 | 规则 |
|
||||
| --- | --- |
|
||||
| limit | 默认 50,范围 1–200 |
|
||||
| before | 上页 next_cursor;正整数,返回更早的 ID |
|
||||
| level | 空或 INFO / WARNING / ERROR / CRITICAL |
|
||||
| source | 模块名精确匹配,最多 100 字符 |
|
||||
| q | 在事件名及脱敏元数据中做字面子串搜索,最多 200 字符 |
|
||||
|
||||
返回 `items`、`next_cursor`、`sources`、`pending`、`dropped`、`write_failures`、`retention`。按递增 ID 的倒序分页,插入新日志不改变已经翻到的旧页边界。没有匹配记录时 items 为空、next_cursor 为 null。
|
||||
|
||||
## 5. 压力问题的修复方式
|
||||
|
||||
Agent Trace 写入由独立异步队列调度到线程,最多合并 64 个写入为一个 SQLite 事务。提交成功后才更新对外可见快照和广播 SSE。创建记录在第一次 await 前占用运行名额,避免并发创建突破 200 个活动运行上限。取消等待正在提交的快照结束,再写终态;服务关闭会等待 Agent 和 Trace 队列。数据库失败不会被当成成功提交。
|
||||
|
||||
任务 HTTP 写操作在协程中排队,然后在线程执行;读操作也在线程执行,减少文件锁争用和主事件循环阻塞。SQLite 仍是单写者,不意味着任务写入支持无限并发。
|
||||
|
||||
前端读取任务和 Agent 列表的后续 API 页,不再只显示第一页的 50 条。任务筛选和数量基于已获取的完整列表,界面每页显示 100 个任务;运行侧栏每页 50 条。列表刷新失败保留上次结果。列表读取使用现有 offset 协议,不是跨多页的事务快照;其他客户端同时修改数据时可以刷新重新获取。
|
||||
|
||||
Trace 搜索先生成事件序号、模型调用 ID、工具调用 ID 的集合,再一次遍历调用树。匹配子节点保留父节点。搜索作用于完整已加载的历史,每页只渲染 200 个事件或树节点。工具统计按工具名和状态汇总,避免在底部再次生成数千个调用卡片。
|
||||
|
||||
## 6. 验证方法
|
||||
|
||||
后端回归覆盖日志持久化、重启、保留窗口、筛选与游标、正文排除、HTTP 关联 ID,以及后台 Trace 写入同时取消时仍释放等待方。业务回归覆盖 Agent/任务、模型路由、本地模型、用量统计和对话。
|
||||
|
||||
```powershell
|
||||
cd backend
|
||||
.venv/Scripts/python.exe -m pytest tests/test_agent_core.py tests/test_api.py tests/test_operation_logs.py tests/test_model_routing.py tests/test_local_models.py tests/test_usage_overrides.py tests/test_chat_history.py tests/test_chat_context.py -q
|
||||
```
|
||||
|
||||
运行测试前应将 APP_DATA_DIR、APP_DB_PATH 和 APP_VAULT_PATH 指向临时目录,避免模块导入时初始化真实扩展。pytest 的 fixture 会继续为每个测试隔离数据。
|
||||
|
||||
前端执行 `npm --prefix frontend test` 和 `npm --prefix frontend run build`。新增用例验证后续任务/Agent 页完整加载、Trace 全历史搜索与分页、日志筛选/游标、自动跟随与上滚暂停、顶部历史加载、存储异常提示及卸载后停止刷新。
|
||||
|
||||
2026-09-06 实测:后端全量 627 项通过;随后增加的 3 项写入失败/取消回归也通过,最后相关接口回归 21 项通过。前端全量 413 项通过,生产构建通过。构建仍提示已有部分 Markdown/Mermaid 依赖块大于 500 kB;后端测试保留已有 Starlette TestClient 弃用提示。纸间时光日志页已用隔离合成数据检查截图,运行中的本机 `/api/logs` 也已确认可返回结果。
|
||||
|
||||
离线并发压测与真实本机 HTTP 压测复现方式、前后数据见 [Agent 与任务压测报告](Agent与任务压测报告.md)。压测只使用隔离数据和 Mock Provider,不消耗用户厂商额度。
|
||||
|
||||
手工验收建议:
|
||||
|
||||
1. 创建、修改和删除一个测试任务,按返回的 task_id 或 X-Request-ID 筛选日志。
|
||||
2. 运行含工具调用的 Agent,批准或取消权限请求;按 run_id 检查创建、权限、工具结果和终态。
|
||||
3. 在隔离配置中请求未安装的本地模型,查看 models/vectors 的错误码与回退信息,不应出现输入文本。
|
||||
4. 重启 AI Core,确认已提交日志仍可查看;退出 Vault 后从入口页打开日志。
|
||||
5. 切换默认浅色、深色、纸间时光主题,检查筛选栏、错误徽标和详情展开;窄窗口下应换行且详情不撑出页面。
|
||||
# 2026-09-06:大批量本地向量传输修复
|
||||
|
||||
全量重建包含 2111 个文本块时,本地模型可能成功完成推理,但整批向量被写成一行 JSON。接收端单行限制为 16 MiB:asyncio 管道拒绝超长行,Windows 线程管道则读到不完整 JSON,最终被包装成 `LOCAL_MODEL_INVALID_RESPONSE`。这类错误不表示 CUDA 显存不足,也不应通过切换 CPU 处理。
|
||||
|
||||
Embedding 响应改为每 128 条向量一个 JSON 帧,结束帧携带总数。接收端检查偏移连续性、请求数量和结束标记;缺块时明确失败,不把部分向量写入索引。模型仍只加载一次,推理批大小不变。语音等其他响应保持原协议。
|
||||
|
||||
验证方法:在隔离数据目录运行 `tests/test_local_models.py`,分别使用 asyncio 与 Windows 线程管道传输 2111 × 384 的结果,确认旧格式超过 16 MiB,而分帧可完整接收。该文件 7 项测试通过。另使用本机 Bekko 权重、CUDA 对 2111 条合成文本做真实推理:返回 2111 条 384 维向量,设备 `cuda:0`,耗时约 12.55 秒;旧格式 JSON 为 17,886,180 字节。该验收不修改用户笔记、索引或运行配置;用户原始长文档的全库重建仍需在服务加载修复后重试。
|
||||
@@ -0,0 +1,30 @@
|
||||
# 模型隔离向量索引与增量登记
|
||||
|
||||
## 目标与实现
|
||||
|
||||
向量仍保存在本地 `app.db`,重启复用。`routed_block_vectors` 主键升级为 `(space_id, dimensions, block_id)`,同维度不同模型、同模型不同维度均独立存储。每个空间建立以模型标识和维度的 SHA-256 命名的 `vec0` 虚拟表,动态表名不包含厂商输入。
|
||||
|
||||
首次访问旧空间时,在事务中将已有 JSON 向量转换为归一化 float32 索引,不重新调用 Embedding 模型。随后检索由 sqlite-vec 执行精确 KNN,避免每次在 Python 中解码所有向量、计算点积。该实现是精确搜索,不是 ANN;依据归一化向量的欧氏距离换算余弦分数。参见 [sqlite-vec KNN 文档](https://alexgarcia.xyz/sqlite-vec/features/knn.html)。
|
||||
|
||||
覆盖检查和 KNN 使用同一事务。向量更新、删除及笔记级联删除通过触发器清理派生索引,新向量与原始向量在同一保存点写入。索引缺失或不完整仍明确失败/按已有策略回退,不混入其他模型结果。本地专用笔记按 `local_only` 元数据过滤,不同空间的结果继续使用 RRF 融合。
|
||||
|
||||
数据库搜索及旧空间转换在线程中运行,不阻塞异步服务事件循环。首次转换仍会占用 SQLite 写事务;超大库应进一步评估迁移耗时。新增空间保留原空间索引,暂不自动清理历史空间。
|
||||
|
||||
首次转换使用进程内迁移锁串行执行,在打开检索读快照之前以 `BEGIN IMMEDIATE` 获取写事务;等待迁移时不持有读事务,避免多个搜索从读锁升级写锁发生冲突。迁移完成后二次检查即可复用。普通检索和隐私分区检索共用该流程,已有索引的检索仅执行读取。
|
||||
|
||||
首次转换同时通过 Vault 的异步写入锁与笔记保存、后台索引协调,避免保存事务读取旧 Block 后与迁移争抢写锁。等待是异步的;取消检索时,仍等待迁移线程结束后才释放锁。已就绪的空间直接走只读检查,不进入写入队列。写入锁按事件循环生命周期创建,避免重启后复用已关闭循环的锁。
|
||||
|
||||
## 外部新增文件
|
||||
|
||||
文件树检测到新增 Markdown 后先登记元数据与全文索引,然后为每条新笔记持久化 `note_vectors_pending:<note_id>`,逐笔记在后台计算。不再因新增文件设置全库重建标记;已存在的全库待处理标记仍保留,以免跳过之前未完成的任务。
|
||||
|
||||
新增文件在推理期间再次变化时校验快照并重试,只同步该笔记。写入失败保留待处理标记。手动“重建全部”仍执行全库重建,正常重新打开已完成的工作区不再入队。
|
||||
|
||||
## 验证
|
||||
|
||||
- 隔离数据库运行后端全套测试:637 项通过;最终覆盖检查优化另运行检索及后台工作区回归,96 项通过。
|
||||
- 新增用例验证同模型不同维度并存、重新连接复用且查询不解码向量 JSON、旧表迁移只计算查询向量,以及外部新增文件不触发全量重建。
|
||||
- 并发迁移回归用同步事件暂停第一个请求的转换,同时发起第二个请求;验证普通/隐私分区路径均只迁移一次、两个请求结果一致,并开启 SQLite `query_only` 验证后续检索不会写入。相关检索与后台工作区测试 91 项通过。
|
||||
- 并发保存回归暂停迁移后发起实际 `update_note(..., defer_vectors=True)`,验证保存等待、事件循环仍可运行、放行迁移后正文成功落盘并保留新内容的向量待处理标记;另覆盖搜索被取消时不得提前放行保存。
|
||||
- `backend/scripts/vector-index-benchmark.py` 使用临时数据库、固定随机种子,比较 4000 条 384 维向量的 top-20,旧新路径结果顺序一致。5 次采样中位数:Python 扫描约 1289.64 ms,sqlite-vec 约 19.67 ms;首次转换约 1329.51 ms。该结果只测向量检索,不包含查询 Embedding、重排与 HTTP 耗时,不代表端到端加速比例。
|
||||
- 原始结果:[2026-09-06-sqlite-vec-search.json](performance/2026-09-06-sqlite-vec-search.json)。基准可用后端虚拟环境 Python 直接执行上述脚本,不读写用户 Vault。
|
||||
@@ -0,0 +1,110 @@
|
||||
# 长文渲染优化与压测报告
|
||||
|
||||
日期:2026-09-06。基线为 `750e172`,结果为本次未提交的渲染优化;基线和优化版使用相同样本、浏览器参数及操作序列。
|
||||
|
||||
## 1. 测试环境与范围
|
||||
|
||||
Windows、Intel Core i7-13620H、Headless Chrome 152,视口 1424 × 905,Vite 开发服务。每种规模重开测试页面三次,独立测试浏览器,不读写真实笔记。耗时基于 performance.now;打开指标不包含模块网络加载。样本含标题、表格、代码块、提示框和行内格式。
|
||||
|
||||
实际汉字数为 25632、61172、122322;Markdown 总字符数以原始 JSON 为准。不是仅以文件字节数代替“字数”。共完成优化前后 18 轮浏览器运行,所有运行的插入内容与文末完整性检查通过。
|
||||
|
||||
## 2. 本次优化
|
||||
|
||||
- 标题装饰按不可变文档和折叠状态弱缓存;光标移动不改变折叠状态时复用结果。没有折叠范围时不遍历全文生成隐藏装饰。
|
||||
- 文档变更后用位置 Set 验证标题映射,避免对每个已折叠标题反复扫描所有标题。
|
||||
- 字号装饰按不可变文档弱缓存;提示框标记位置按文档缓存,光标移动只判断标记是否处于编辑范围。
|
||||
- 静态代码高亮增加 LRU,最多 64 项、累计 100 万个字符串字符;超过预算四分之一的单块不缓存。缓存同时包含深浅主题颜色,最终输出继续净化。缓存只在进程内,不写入存储。
|
||||
|
||||
弱缓存随文档释放,不用全局 Map 持有历史文档;高亮缓存有明确上限。
|
||||
|
||||
## 3. 对比结果
|
||||
|
||||
单位 ms。打开取三轮中位数;选区、插入、折叠取各轮 P95 的中位数;热预览取六次热运行中位数。P95 样本量较少,仅用于本机前后比较。
|
||||
|
||||
| 实际汉字数 | 打开 前→后 | 光标移动 P95 前→后 | 插入 P95 前→后 | 折叠/展开 P95 前→后 | 热预览 前→后 |
|
||||
| --- | --- | --- | --- | --- | --- |
|
||||
| 25632 | 272.1 → 218.6 | 1.9 → 0.6 | 7.0 → 6.9 | 55.0 → 45.6 | 40.0 → 26.6 |
|
||||
| 61172 | 519.7 → 447.5 | 5.7 → 0.6 | 9.7 → 9.6 | 149.1 → 145.5 | 82.9 → 55.6 |
|
||||
| 122322 | 875.4 → 869.1 | 11.9 → 1.2 | 22.2 → 27.2 | 256.6 → 263.9 | 140.2 → 95.5 |
|
||||
|
||||
主要收益是减少光标移动的重复工作,以及重复代码块/重复预览的高亮开销。2.5 万汉字样本完成全部操作,但不以此宣称所有文档都能维持 60 FPS。
|
||||
|
||||
12 万汉字的整篇折叠仍超过 250 ms,插入 P95 本轮反而增加,不能声称打字性能全面提升;全量 DOM 更新、编辑器自身处理与浏览器调度仍需进一步分项剖析。打开仍有长任务,缓存没有解决虚拟化问题。
|
||||
|
||||
## 4. 原始数据与复现
|
||||
|
||||
- [优化前 JSON](performance/2026-09-06-long-document-baseline.json)
|
||||
- [优化后 JSON](performance/2026-09-06-long-document-after.json)
|
||||
- [压测脚本与指标说明](../../frontend/tests/performance/README.md)
|
||||
|
||||
```powershell
|
||||
npm --prefix frontend run test
|
||||
npm --prefix frontend run build
|
||||
npm --prefix frontend run dev -- --port 5175 --strictPort
|
||||
# 另一个终端:
|
||||
backend/.venv/Scripts/python.exe frontend/tests/performance/run-stress.py --url http://127.0.0.1:5175/tests/performance/stress.html --runs 3 --output .local-plans/stress-results.json
|
||||
```
|
||||
|
||||
新增回归检查确认光标移动复用标题装饰、正文编辑使缓存失效、折叠与展开不残留隐藏内容。前端 402 项测试通过。
|
||||
|
||||
## 5. 边界与后续
|
||||
|
||||
本次测量是浏览器中的程序化编辑事务,不是输入法、实际键盘到屏幕显示、滚动帧率或生产包启动测试。样本代码块存在重复,LRU 收益不能直接外推到全部唯一代码块的文档。堆内存只采样,不作为内存泄漏结论。
|
||||
|
||||
后续应针对 12 万字的输入和整篇折叠采集独立 CPU trace,评估装饰的增量映射及可见区域渲染;在输入法、表格与代码块编辑验收之前,不直接给 contenteditable 应用跳过布局或整篇虚拟化。
|
||||
|
||||
## 6. 手动压测反馈后的滚动与定位修复
|
||||
|
||||
用户实测:2.56 万字正常,6 万字快速滚动轻微停顿,12 万字明显卡顿;从长文末尾全部折叠没有回到顶层。
|
||||
|
||||
本轮将“全部折叠”设为一次性把光标移到首个标题并将编辑区滚动到顶部,单个标题折叠保留原有定位行为。回归用例包含 100 个同级顶层标题,从文末触发后检查光标、scrollTop 与正文不变,避免只有一个 H1 的样本掩盖问题。
|
||||
|
||||
语言标签改为只同步变动的代码块,语言菜单只在打开时响应滚动定位,并合并同一帧的重复事件;监听祖先滚动,卸载时清理监听及待执行帧。
|
||||
|
||||
新增独立 CDP 滚轮测试,在相同的有限高度 flex 容器、纸间时光主题下,每档运行两次。下表为每次帧间隔 P95 的中位数,单位 ms,越小越好。这不是原先编辑事务基准的延续,也不是生产环境 FPS。
|
||||
|
||||
| 请求汉字数 | 修改前 | 修改后 |
|
||||
| --- | ---: | ---: |
|
||||
| 25000 | 30.05 | 20.10 |
|
||||
| 60000 | 55.00 | 45.05 |
|
||||
| 120000 | 90.10 | 100.00 |
|
||||
|
||||
两档较短样本有改善,12 万字没有改善,仍未达到流畅滚动的目标。CPU 采样显示滚入新代码块时的 CodeMirror 初始化、选区测量及 DOM 观察回调占用明显;不能仅凭此认定唯一原因。代码块布局隔离实验未带来收益,已撤回,未引入可能影响编辑、选区或布局的虚拟化。
|
||||
|
||||
- [滚轮基线数据](performance/2026-09-06-scroll-baseline.json)
|
||||
- [滚轮修改后数据](performance/2026-09-06-scroll-after.json)
|
||||
|
||||
下一步需要评估代码块按交互初始化或编辑器级虚拟化,并同时验证输入、选区、搜索定位和折叠;当前不将 12 万字滚动问题标记为完成。
|
||||
|
||||
本轮前端 405 项测试通过,涵盖折叠定位、语言标签增量同步、菜单祖先滚动定位和卸载清理。
|
||||
|
||||
## 7. CodeMirror 高亮复用实验
|
||||
|
||||
在上轮提交 `874e916` 的基础上继续尝试:同一语言及主题的 CodeMirror LanguageSupport 内缓存高亮装饰,代码块离屏销毁后重新创建时,相同正文不再重复分词及构建装饰。缓存最多 32 项、64000 个源字符,超过 16000 字符的单块不缓存,使用 LRU 淘汰;语言支持释放时缓存一并释放。编辑后的内容按新正文计算,不复用旧位置。
|
||||
|
||||
回归测试通过统计分词调用验证跨视图复用、正文编辑重新计算和超限淘汰。原有深浅主题切换与编辑测试继续验证显示内容。
|
||||
|
||||
12 万字继续测量两次,帧间隔 P95 分别约 100.2 ms、90 ms,二者中位数约 95.1 ms;上一轮约 100 ms。样本重复代码较多,结果仍在明显波动范围内,不能宣称解决滚动卡顿。此优化减少确定可重复的高亮工作,但下一步仍须处理创建 CodeMirror 和布局测量的成本。
|
||||
|
||||
- [本轮滚轮原始数据](performance/2026-09-06-scroll-token-cache.json)
|
||||
|
||||
## 8. 主题对照与纸间时光 1.8.1 修复
|
||||
|
||||
用户补充:同一份 12 万字文档在默认浅色、深色下不卡顿。因此重新进行主题对照,之前将 CodeMirror 作为主要优化方向的判断不足;CPU 采样中的布局及选区测量耗时不能单独证明编辑器是主要原因。
|
||||
|
||||
保持相同文档和滚轮脚本,默认浅色、深色各测一次,P95 均约 30 ms。纸间时光 1.8.0 仅禁用整篇 `.ProseMirror` 的虚线 outline 后,两次 P95 约 30.1、30 ms;相比此前约 90–100 ms,构成明确的样式消融证据。主题与 CodeMirror 的交互仍可能影响布局,但不需要先用编辑器虚拟化解决这个差异。
|
||||
|
||||
修复将贯穿长文的虚线轮廓改为四条小尺寸渐变平铺背景,保留纸张、缝线、胶带、段落横线和叠纸阴影。独立伪元素虚线 border 的实验反而更慢,已撤回。正式主题版本升为 1.8.1。
|
||||
|
||||
| 主题或实验 | 次数 | 帧间隔 P95(ms) |
|
||||
| --- | ---: | --- |
|
||||
| 默认浅色 | 1 | 30 |
|
||||
| 默认深色 | 1 | 30 |
|
||||
| 1.8.0 仅禁用整篇 outline | 2 | 30.1、30 |
|
||||
| 1.8.1 平铺缝线 | 3 | 30.1、30、30.1 |
|
||||
|
||||
1.8.1 三次测试的帧间隔中位数均为 10 ms,全部折叠后的 scrollTop 均为 0,光标位置均为 1。已检查视口截图,手账装饰保留。这里的结果说明本轮样本与环境下,纸间时光恢复到接近默认主题的滚动表现,不代表所有设备、所有复杂文档均无长任务。
|
||||
|
||||
已安装主题保存在本地,不会自动被新版资源覆盖。刷新前端后,到“主题 → 社区主题 → 纸间时光”点击“更新”,确认版本 1.8.1 再进行手动复测。
|
||||
|
||||
- [主题对比原始数据](performance/2026-09-06-scroll-theme-comparison.json)
|
||||
Reference in New Issue
Block a user