diff --git a/.changeset/chilly-ants-search.md b/.changeset/chilly-ants-search.md new file mode 100644 index 00000000000..d79440a9d0b --- /dev/null +++ b/.changeset/chilly-ants-search.md @@ -0,0 +1,5 @@ +--- +'@graphql-codegen/cli': minor +--- + +Performance optimizations in schema and documents loading (shared promises) diff --git a/packages/graphql-codegen-cli/src/codegen.ts b/packages/graphql-codegen-cli/src/codegen.ts index 330ddc3d4b9..af4f750025a 100644 --- a/packages/graphql-codegen-cli/src/codegen.ts +++ b/packages/graphql-codegen-cli/src/codegen.ts @@ -33,6 +33,24 @@ const makeDefaultLoader = (from: string) => { }; }; +// TODO: Replace any with types +function createCache(loader: (key: string) => Promise) { + const cache = new Map>(); + + return { + load(key: string): Promise { + if (cache.has(key)) { + return cache.get(key); + } + + const value = loader(key); + + cache.set(key, value); + return value; + }, + }; +} + export async function executeCodegen(input: CodegenContext | Types.Config): Promise { function wrapTask(task: () => void | Promise, source: string) { return async () => { @@ -84,6 +102,22 @@ export async function executeCodegen(input: CodegenContext | Types.Config): Prom let rootDocuments: Types.OperationDocument[]; const generates: { [filename: string]: Types.ConfiguredOutput } = {}; + const schemaLoadingCache = createCache(async function (hash) { + const outputSchemaAst = await context.loadSchema(JSON.parse(hash)); + const outputSchema = getCachedDocumentNodeFromSchema(outputSchemaAst); + return { + outputSchemaAst: outputSchemaAst, + outputSchema: outputSchema, + }; + }); + + const documentsLoadingCache = createCache(async function (hash) { + const documents = await context.loadDocuments(JSON.parse(hash)); + return { + documents: documents, + }; + }); + async function normalize() { /* Load Require extensions */ const requireExtensions = normalizeInstanceOrArray(config.require); @@ -210,8 +244,12 @@ export async function executeCodegen(input: CodegenContext | Types.Config): Prom Object.assign(schemaPointerMap, unnormalizedPtr); } } - outputSchemaAst = await context.loadSchema(schemaPointerMap); - outputSchema = getCachedDocumentNodeFromSchema(outputSchemaAst); + + const hash = JSON.stringify(schemaPointerMap); + const result = await schemaLoadingCache.load(hash); + + outputSchemaAst = await result.outputSchemaAst; + outputSchema = result.outputSchema; }, filename), }, { @@ -220,7 +258,10 @@ export async function executeCodegen(input: CodegenContext | Types.Config): Prom debugLog(`[CLI] Loading Documents`); const allDocuments = [...rootDocuments, ...outputSpecificDocuments]; - const documents = await context.loadDocuments(allDocuments); + + const hash = JSON.stringify(allDocuments); + const result = await documentsLoadingCache.load(hash); + const documents: Types.DocumentFile[] = result.documents; if (documents.length > 0) { outputDocuments.push(...documents);