> 原始 Markdown 孪生体（构建期从源 Markdown 生成）。渲染页：https://docs.gatellm.io/zh-CN/practices/script-performance · 文档索引：https://docs.gatellm.io/zh-CN/llms.txt


# 脚本性能与内存

脚本是网关里表达力最强、开销也最大的改写手段。本页是脚本性能与内存的唯一权威，其余页面（[上游与模型字段](/zh-CN/reference/upstreams-models-fields.md)、[脚本 API 参考](/zh-CN/reference/scripting-api.md)、[脚本配置](/zh-CN/reference/scripting-config.md)、[写第一个脚本变换](/zh-CN/howto/write-script-transform.md)）只留指针指回这里。

## 开销来自序列化

脚本引擎（基于 QuickJS）拿到的是 JSON body 解析为对象后的形式。开销主要来自 JSON 序列化/反序列化，耗时随 body 大小线性增长。

## 耗时参考

| body 大小 | 典型单次脚本耗时 |
|-----------|-----------------|
| < 10 KB | 毫秒级 |
| ~100 KB | 数十毫秒 |
| ~1 MB（多模态大对话，含内联 base64） | 显著上升，且占内存 |

::: tip 简单改写别用脚本
简单字段增删改用 `request_payload` 声明式规则——在网关内部直接改写请求体、不经过脚本引擎的序列化，性能最好。选型见 [请求改写与路由：怎么选](/zh-CN/practices/routing-and-transform.md)。
:::

## 反模式：用 after 槽脚本做纯路由决策

::: danger 大 body 上不要用 after 槽脚本做纯路由决策
after 槽脚本会把整段 body（含内联 base64）读入脚本引擎内存，多模态大对话易触发脚本引擎内存 OOM；且 `script_error_mode = log-and-continue` 下切路由会被**静默跳过**。

这类「检测图片/联网 → 切模型」的**纯路由决策**，只要目标与当前路由**同协议**，改用原生 `switch-route` 规则——它的谓词只做结构/小值检查、永不读取二进制内容字节，大请求体的磁盘暂存保持开启，含 base64 的 body 以占位符 + 磁盘临时文件留在磁盘上、不读入内存。

只有切换是**跨协议**、或判定逻辑超出「字段存在性/小值相等」能表达的范围时，才退回脚本——放 **before 槽**读客户端原始格式（before 槽在协议翻译前运行，尚未解析为目标协议 body）。
:::

## 写法建议

- **只读需要读的字段**：不要 `JSON.stringify(body)` 整个 body，按需取字段。
- **早返回**：条件不满足时尽快 `return body`，减少不必要的处理。
- **避免在循环里做大对象拷贝**。
- **流式响应脚本**：对每个块处理，避免累积状态。

## 出错模式的选择

- `log-and-continue`（默认）：脚本失败则原 body 透传，请求不中断。适合非关键改写。
- `log-and-reject`：脚本失败直接拒绝请求。合规要求严格（脱敏不能漏）时用这个。

字段见 [脚本配置](/zh-CN/reference/scripting-config.md)。

## 常见问题

**Q：脚本超时了怎么办？**
`SCRIPT_MAX_OPERATIONS`（默认 2000）限制每次脚本执行的最大操作数。超了会被中断。死循环或过重逻辑会被它兜住。

**Q：多模态大对话脚本 OOM，但确实需要读图片内容判定？**
读图片内容做判定本身就会把 base64 读入内存。考虑把判定改成结构检查（用 `switch-route` 的 `when` 谓词检查「有没有 image 块」而非读图片内容），或在上游/模型层用协议覆盖分流。

**Q：before 和 after 槽都配了脚本，执行顺序？**
before 先跑（可触发立即 `useModel` 切换），after 后跑。一旦 before 触发切换，原路由的 after 不执行。详见 [脚本 API 参考](/zh-CN/reference/scripting-api.md)。

**下一步**：[请求改写与路由：怎么选](/zh-CN/practices/routing-and-transform.md) 看选型；[脚本 API 参考](/zh-CN/reference/scripting-api.md) 看 API；[脚本配置](/zh-CN/reference/scripting-config.md) 看配置。
