From be7cb3a825af2ade833e85a358fe2d2110400483 Mon Sep 17 00:00:00 2001 From: Charly POLY <1252066+charlypoly@users.noreply.github.com> Date: Wed, 2 Feb 2022 11:18:31 +0100 Subject: [PATCH] Performance work: resolvers plugins, documents loading (#7452) * perf(resolvers-visitor): improve performance for config without `mappers` * perf(codegen): improve caching for output specific documents * Create witty-carrots-clap.md * update changeset * perf(resolvers-visitor): use cache for `shouldMapType()` result --- .changeset/witty-carrots-clap.md | 6 ++++ packages/graphql-codegen-cli/src/codegen.ts | 14 +++++--- .../src/base-resolvers-visitor.ts | 33 +++++++++---------- 3 files changed, 31 insertions(+), 22 deletions(-) create mode 100644 .changeset/witty-carrots-clap.md diff --git a/.changeset/witty-carrots-clap.md b/.changeset/witty-carrots-clap.md new file mode 100644 index 00000000000..190738c34c6 --- /dev/null +++ b/.changeset/witty-carrots-clap.md @@ -0,0 +1,6 @@ +--- +"@graphql-codegen/cli": patch +"@graphql-codegen/visitor-plugin-common": patch +--- + +Performance work: resolvers plugins, documents loading diff --git a/packages/graphql-codegen-cli/src/codegen.ts b/packages/graphql-codegen-cli/src/codegen.ts index af4f750025a..93a135a7301 100644 --- a/packages/graphql-codegen-cli/src/codegen.ts +++ b/packages/graphql-codegen-cli/src/codegen.ts @@ -257,11 +257,17 @@ export async function executeCodegen(input: CodegenContext | Types.Config): Prom task: wrapTask(async () => { debugLog(`[CLI] Loading Documents`); - const allDocuments = [...rootDocuments, ...outputSpecificDocuments]; + // get different cache for shared docs and output specific docs + const results = await Promise.all( + [rootDocuments, outputSpecificDocuments].map(docs => { + const hash = JSON.stringify(docs); + return documentsLoadingCache.load(hash); + }) + ); + + const documents: Types.DocumentFile[] = []; - const hash = JSON.stringify(allDocuments); - const result = await documentsLoadingCache.load(hash); - const documents: Types.DocumentFile[] = result.documents; + results.forEach(source => documents.push(...source.documents)); if (documents.length > 0) { outputDocuments.push(...documents); diff --git a/packages/plugins/other/visitor-plugin-common/src/base-resolvers-visitor.ts b/packages/plugins/other/visitor-plugin-common/src/base-resolvers-visitor.ts index 488cafa3ae0..83bdc8f2a07 100644 --- a/packages/plugins/other/visitor-plugin-common/src/base-resolvers-visitor.ts +++ b/packages/plugins/other/visitor-plugin-common/src/base-resolvers-visitor.ts @@ -376,6 +376,7 @@ export class BaseResolversVisitor< protected _hasFederation = false; protected _fieldContextTypeMap: FieldContextTypeMap; private _directiveResolverMappings: Record; + private _shouldMapType: { [typeName: string]: boolean } = {}; constructor( rawConfig: TRawConfig, @@ -438,15 +439,7 @@ export class BaseResolversVisitor< return `export type ResolverTypeWrapper = ${this.config.resolverTypeWrapperSignature};`; } - protected shouldMapType( - type: GraphQLNamedType, - checkedBefore: { [typeName: string]: boolean } = {}, - duringCheck: string[] = [] - ): boolean { - if (checkedBefore[type.name] !== undefined) { - return checkedBefore[type.name]; - } - + protected shouldMapType(type: GraphQLNamedType, duringCheck: string[] = []): boolean { if (type.name.startsWith('__') || this.config.scalars[type.name]) { return false; } @@ -469,8 +462,8 @@ export class BaseResolversVisitor< const field = fields[fieldName]; const fieldType = getBaseType(field.type); - if (checkedBefore[fieldType.name] !== undefined) { - return checkedBefore[fieldType.name]; + if (this._shouldMapType[fieldType.name] !== undefined) { + return this._shouldMapType[fieldType.name]; } if (this.config.mappers[type.name]) { @@ -478,7 +471,7 @@ export class BaseResolversVisitor< } duringCheck.push(type.name); - const innerResult = this.shouldMapType(fieldType, checkedBefore, duringCheck); + const innerResult = this.shouldMapType(fieldType, duringCheck); return innerResult; }); @@ -507,13 +500,17 @@ export class BaseResolversVisitor< shouldInclude?: (type: GraphQLNamedType) => boolean ): ResolverTypes { const allSchemaTypes = this._schema.getTypeMap(); - const nestedMapping: { [typeName: string]: boolean } = {}; const typeNames = this._federation.filterTypeNames(Object.keys(allSchemaTypes)); - typeNames.forEach(typeName => { - const schemaType = allSchemaTypes[typeName]; - nestedMapping[typeName] = this.shouldMapType(schemaType, nestedMapping); - }); + // avoid checking all types recursively if we have no `mappers` defined + if (Object.keys(this.config.mappers).length > 0) { + typeNames.forEach(typeName => { + if (this._shouldMapType[typeName] === undefined) { + const schemaType = allSchemaTypes[typeName]; + this._shouldMapType[typeName] = this.shouldMapType(schemaType); + } + }); + } return typeNames.reduce((prev: ResolverTypes, typeName: string) => { const schemaType = allSchemaTypes[typeName]; @@ -594,7 +591,7 @@ export class BaseResolversVisitor< const baseType = getBaseType(field.type); const isUnion = isUnionType(baseType); - if (!this.config.mappers[baseType.name] && !isUnion && !nestedMapping[baseType.name]) { + if (!this.config.mappers[baseType.name] && !isUnion && !this._shouldMapType[baseType.name]) { return null; }