首页 / 资讯中心 / 文章详情

TypeGraphQL 性能优化指南:从基准测试到 simpleResolvers 实战调优

TypeGraphQL 性能优化指南:从基准测试到 simpleResolvers 实战调优 ★ FEATURED ARTICLE
后端GraphQLAPI设计【免费下载链接】type-graphqlCreate GraphQL schema and resolvers with TypeScript, using classes and decorators!项目地址https://gitcode.com/gh_mirrors/ty/type-graphql点击查看免费下载TypeGraphQL 是基于graphql-js之上的一层 TypeScript 抽象它用类和装饰器极大地提升了开发体验授权、校验、中间件开箱即用但抽象也带来了运行时开销。本文基于官方性能文档结合仓库源码与基准测试系统讲解 TypeGraphQL 的性能开销来源、基准测试数据、异步执行路径的代价以及simple/simpleResolvers这两个内建性能优化开关的用法、原理与适用边界帮助你在保持开发效率的同时把查询执行成本降到接近裸写graphql-js的水平。基准测试抽象层的运行时开销从何而来为了量化 TypeGraphQL 抽象层的开销仓库在 benchmarks 目录下提供了多组对照基准同样的 Schema 分别用 TypeGraphQL 装饰器方式和裸写的graphql-js方式实现然后在同一台机器、同样 25 000 条数组数据下执行同样的查询并统计耗时。基准代码位于 benchmarks/array运行入口 benchmarks/array/run.ts 展示了测试的核心手法通过ARRAY_ITEMS 25000控制数据量用graphql的execute执行一段嵌套查询顶层数组 nestedField内层对象连续跑 50 次BENCHMARK_ITERATIONS 50后输出耗时并对结果做断言校验保证比较的是正确结果下的真实耗时。对照实现分两组裸graphql-jsstandard.ts 用GraphQLObjectType手工构造对象类型字段不写resolve即默认取source上的同名属性TypeGraphQLstandard.ts 用ObjectType()Field()声明同样的SampleObject并在Query中返回同样的数组。官方文档给出的典型实测数据如下25 000 条数组项25 000 array itemsDeeply nested objectStandard TypeGraphQL1253.28 ms45.57 μsgraphql-js265.52 ms24.22 μs可以看到在最苛刻的返回 25 000 个嵌套对象场景下标准 TypeGraphQL 的执行时间大约慢了 5 倍。需要说明的是这是一组极端压力用例专门放大抽象层的固定开销真实应用中若查询耗时主要来自数据库查询等 I/OTypeGraphQL 与裸graphql-js的差距占比会显著缩小但依然不可忽略。仓库里的历史运行结果 benchmarks/array/results.txt 记录了该基准在 Core i7 2700K / Windows 10 / Node.js v13.5 环境下的实测数值可作参考不同硬件与 Node 版本下绝对值会变化但相对趋势一致标准 TypeGraphQL 约 15.5s50 次合计裸graphql-js约 13.3s而带全局中间件的 TypeGraphQL 高达 62.7s使用simpleResolvers后回落到 15.0s。性能开销的两个主要来源1. 默认字段解析器会组装并执行中间件栈在源码 src/schema/schema-generator.ts 中每个 Object Type 字段默认都会被赋上一个由createBasicFieldResolver生成的解析器。查看 src/resolvers/create.ts 的实现可以看到即使一个字段只是返回 root 上的同名属性它依然会把globalMiddlewares与该字段自身的中间件拼接成一个中间件数组若配置了authChecker且字段带有roles如Authorized则通过 applyAuthChecker 在栈首插入授权中间件通过 applyMiddlewares 以递归dispatchHandler的方式逐个执行中间件后再调用真正取值的 handler。applyMiddlewares的dispatchHandler是async函数每一层await handlerFn(...)都会引入 Promise 链。因此只要字段走默认解析器无论中间件列表是否为空都可能落入异步执行路径空栈时会直接同步返回 handler 结果见 src/resolvers/helpers.ts。更值得注意的是文档明确提示一旦注册了全局中间件每个隐式字段解析器都会创建中间件栈——这正是带全局中间件的基准数据暴涨到 1253.28 ms 的原因。2. Promise 与 async 字段解析器本身代价高昂文档给出了裸graphql-js下同步与异步字段解析器的对比graphql-js25 000 array itemssync resolvers265.52 msasync resolvers512.61 ms同样是裸graphql-js仅把字段resolve改成async见 async.ts对应同步版 standard.ts执行时间就翻了一倍。因此 TypeGraphQL 的优化策略很直接尽可能避开异步执行路径。文档列出的条件是解析器不使用 auth 特性、不使用 args或已关闭参数校验、且不返回 Promise 时TypeGraphQL 可以走更快的同步路径。对应的对照实现可见 async-field-resolvers.ts所有字段都用FieldResolverasync包装实测明显变慢与 sync-field-resolvers.ts。所以在排查性能瓶颈时建议先从解析器本身入手去掉不必要的async/await、关闭未使用的特性、精简参数定义与校验配置往往立竿见影。内建优化开关simple 与 simpleResolvers如果查询返回的是海量 JSON 形态的数据且字段不需要字段级访问控制或自定义中间件就可以用装饰器选项直接整段剥离授权与中间件栈让字段解析器变成最轻量的形态。单字段级别Field({ simple: true })只对某个字段生效ObjectType() class SampleObject { Field() sampleField: string; Field({ simple: true }) publicFrequentlyQueriedField: SomeType; }该选项在 src/decorators/Field.ts 中定义为FieldOptions.simple其注释原文即Set totrueto disable auth and all middlewares stack for this field resolver。对象类型级别ObjectType({ simpleResolvers: true })对该 Object Type 的全部字段生效ObjectType({ simpleResolvers: true }) class Post { Field() title: string; Field() createdAt: Date; Field() isPublished: boolean; }该选项在 src/decorators/ObjectType.ts 中定义为ObjectTypeOptions.simpleResolvers注释为disable auth and all middlewares stack for all this Object Type fields resolvers元数据落在ClassMetadata.simpleResolvers见 src/metadata/definitions/class-metadata.ts。两者的合并与覆盖规则从源码 src/schema/schema-generator.ts 可以看出两者的优先级是字段级选项优先于类级选项const isSimpleResolver field.simple ! undefined ? field.simple true : objectType.simpleResolvers ! undefined ? objectType.simpleResolvers true : false;也就是说可以用Field({ simple: false })在simpleResolvers: true的类上为个别字段恢复完整的中间件/授权栈。这一行为在测试 tests/functional/simple-resolvers.ts 中有专门验证测试声明了NormalObject、ObjectWithSimpleField、SimpleObject、SimpleObjectWithNormalField后者的normalField显式写simple: false配合全局测试中间件断言了中间件执行次数——普通对象字段执行 2 次Query 字段simple 字段/对象只执行 1 次simple: false覆盖后恢复为 2 次。底层效果解析器退化为直接取值当isSimpleResolver为 true 时schema-generator 直接不给字段赋解析器resolve: undefined完全交给graphql-js默认的取值逻辑读取source上同名属性见 src/schema/schema-generator.ts。这相当于绕过了createBasicFieldResolver里的中间件拼接、applyAuthChecker和applyMiddlewares把字段执行压缩到与裸graphql-js相同的路径上。实测收益最高提速 76%开销降到约 13%文档给出的最终基准对比25 000 条数组项25 000 array itemsgraphql-js265.52 msStandard TypeGraphQL310.36 msTypeGraphQL with a global middleware1253.28 msTypeGraphQL with simpleResolvers applied (and a global middleware)299.61 ms两处关键结论提速幅度与带全局中间件的 1253.28 ms 相比加上simpleResolvers后降至 299.61 ms提速约 76%接近裸写水平299.61 ms 相比裸graphql-js的 265.52 ms 只多约 13% 的开销远低于文档开头提到的约 500%5 倍差距。对应的 TypeGraphQL 基准实现见 simple-resolvers.tsObjectType({ simpleResolvers: true }) 仍然挂着一个loggingMiddleware全局中间件它和 with-global-middleware.ts 的唯一差别就是simpleResolvers这一行性能差异因此而来。注意该优化默认不开启simpleResolvers未定义时按false处理见上文的isSimpleResolver判断主要就是因为全局中间件与授权特性依赖默认的完整解析器路径。使用 simpleResolvers 的代价与适用边界打开simpleResolvers或字段级simple: true等于对相关字段关闭两样东西Authorized守卫失效字段上的授权检查不再执行这些字段会变成公开可访问全局中间件不再执行例如性能指标采集、访问日志、错误上报等依赖全局中间件的能力在该字段上会静默失效。因此文档给出的建议是只在确有必要时使用典型场景就是返回海量嵌套对象的查询如一次性返回上万元组的列表页使用前先确认该对象类型的字段确实不需要字段级权限控制也不依赖任何中间件提供的横切能力若只有一个高频字段受影响优先用字段级Field({ simple: true })而不是类级simpleResolvers: true把影响面降到最小若个别字段仍需授权/中间件用Field({ simple: false })显式恢复源码支持测试已验证。小结性能调优路线图结合本文可以整理出一条务实的调优路径先用基准与真实负载确认瓶颈确实在字段解析层而不是数据库或网络检查并精简解析器移除不必要的async/await、关闭未使用的 auth/args 校验等特性审视全局中间件的使用范围——它会让每个隐式字段都背上中间件栈对返回海量数据的对象类型启用simpleResolvers或用字段级simple: true精准优化高频字段注意授权与中间件的失效边界必要时用simple: false局部恢复并在 tests/functional/simple-resolvers.ts 的模式上补充自己的回归测试。通过这套组合拳TypeGraphQL 应用的查询执行开销可以从5 倍于裸graphql-js降低到仅约 13% 的附加开销在享受装饰器开发体验的同时把运行时成本压到接近手写graphql-js的水平。赞分享后端GraphQLAPI设计【免费下载链接】type-graphqlCreate GraphQL schema and resolvers with TypeScript, using classes and decorators!项目地址https://gitcode.com/gh_mirrors/ty/type-graphql点击查看免费下载相关推荐TypeGraphQL 性能优化实战指南从基准测试到 simpleResolvers 加速TypeGraphQL 性能优化实战指南从基准测试到 simpleResolvers 加速 TypeGraphQL 是构建在 graphql js 之上的 T后端GraphQLAPI设计TypeGraphQL 性能深度剖析基准测试、异步执行路径与 simpleResolvers 优化实战TypeGraphQL 性能深度剖析基准测试、异步执行路径与 simpleResolvers 优化实战 TypeGraphQL 本质上是构建在 GraphQL后端GraphQLAPI设计STL-ThumbnailWindows资源管理器3D模型预览终极解决方案STL ThumbnailWindows资源管理器3D模型预览终极解决方案 您是否曾经在管理大量STL文件时感到困扰每次都需要打开专业的3D软件才能查看模型上一篇终极智能分层工具LayerDivider让插画编辑效率提升500%下一篇Video2X基于AI的视频超分辨率与帧插值框架深度解析创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
阅读完成 · 觉得有帮助?
咨询建站