Files
inkreach-agent/docs/plugins/08-performance.md
T

101 lines
4.1 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# L7 · 性能与检验(plugin:check)
> 前置:L0–L6。约 20 分钟。
> 目标:插件百花齐放,但**绝不卡宿主、绝不风格跑偏**;发布前有机器关卡把关。
## 性能铁律
### 1. 主进程不阻塞(检验器:error)
`main.mjs` 运行在宿主主进程。任何同步 IO——`fs` 的 `*Sync`、`execSync`、
`spawnSync`——都会卡住**整个应用**的事件循环(聊天流、其他插件全部冻结)。
一律用 `node:fs/promises` 与异步子进程:
```js
// ❌ const text = fs.readFileSync(path, 'utf8')
// ✅
import { readFile } from 'node:fs/promises'
const text = await readFile(path, 'utf8')
```
### 2. 激活限时 10 秒(宿主强制)
插件工厂若返回 Promise,宿主限时 10s;超时或 reject 即把插件标记为失败
(插件管理页可见红字),绝不无限等待拖垮 runtime 重建。因此:
- 激活路径只做「注册」级别的工作,重活(预取数据、预热连接)放到工具首次调用
- 自己 `catch` 并 `api.log.error`——被宿主兜住意味着插件没跑起来
### 3. renderer 装载限时 8 秒(宿主强制)
读源与 import 各限时 8s,超时/失败由宿主呈现统一失败态(重试按钮);
组件渲染期崩溃由 PluginErrorBoundary 兜底。插件只需管好组件内部的异步。
### 4. 自己的异步自己兜(sdk 提供 `withTimeout` / `withRetry`)
先于宿主超时并自行恢复,而不是等宿主判死:
```js
import { withTimeout, withRetry, TimeoutError } from '@aso/plugin-sdk'
// 网络请求:3s 超时,失败退避重试 2 次(300ms → 600ms)
const data = await withRetry(() => callApi(), { retries: 2, delayMs: 300, timeoutMs: 3000 })
// 单次限时
const cfg = await withTimeout(loadConfig(), 2000, '加载配置')
try {
await risky()
} catch (err) {
if (err instanceof TimeoutError) { /* 降级路径 */ }
throw err
}
```
注意:`withTimeout` 只是竞速,底层操作不会被取消——有 `AbortController` 的
调用方请把 signal 接到底层,再用它兜底计时。
### 5. 渲染不卡顿
长列表分页/虚拟化,不要一次渲染数万节点;重计算放进工具(Agent 侧)或
`setTimeout(fn, 0)` 分帧,不占渲染主线程。
## 三态呈现(检验器:warn)
任何异步 UI 必须是四态之一:`LoadingState` / `ErrorState` / `EmptyState` / 数据。
`alert`/`confirm`/`prompt` 是阻塞式同步对话框,禁止(用 `Button` + 状态组件替代)。
详见 [L6](./07-ui-components.md)。
## 样式一致性(检验器:error)
- 只用公共组件库 + [DESIGN.md](./DESIGN.md) token;硬编码 hex 色值是 error
(`#fff`/`#ffffff` 白字除外)
- renderer.mjs 必须经宿主 shim 使用单实例 React(`__ASO_PLUGIN_HOST__`)——
自带 React 副本 = hooks 全部失效
## 日志(检验器:error)
`main.mjs` 禁 `console.*`,统一 `api.log.*`——Agent 自诊断闭环见 [L5](./06-self-diagnosis.md)。
## 检验器:`pnpm plugin:check <插件目录>`
发布前必跑;Agent 自迭代时,**通过检验器是完成定义(DoD)的一部分**。
| 级别 | 检查项 |
|---|---|
| error | manifest 缺失/不可解析;id/name/version(semver) 缺失;minContract 高于宿主契约;entry 指向的文件不存在;renderer.mjs > 8MB / main.mjs > 2MB;main.mjs 同步 IO;main.mjs `console.*`;renderer.mjs 未引用 `__ASO_PLUGIN_HOST__`;任何源码硬编码 hex 色值 |
| warn | 缺 minContract;renderer.mjs > 300KB(疑似打包自带 React);注册 view/panel 但未用三态组件;`alert/confirm/prompt`;entry.renderer 产物缺失但有 src/renderer.tsx(未构建) |
宿主契约版本从 `plugin-host.ts` 源码提取(单一事实源),检验器与宿主永不会各执一词。
## 一张自查表
- [ ] `pnpm plugin:check <目录>` 0 error
- [ ] main.mjs 无同步 IO,激活 10s 内完成
- [ ] 一切异步有超时与重试,catch 后 `api.log` + `ErrorState`
- [ ] 长列表不整批渲染
- [ ] 深浅色各看一眼(token 正确时自动成立)
---
**上一篇** [L6 公共组件库](./07-ui-components.md) · 返回 [教程索引](./README.md)