You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
While investigating an issue with graphql codegen taking too long in the pipeline of one of my company's projects, I came across a performance issue caused when spreading a deeply nested fragment multiple times in the same file. The issue happens when near-operation-file and typescript-operations are used together, and is ultimately caused due to the first supplying repeated input to the latter.
Here's how it works:
near-operation-file resolves document imports here and then generates a list of externalFragments for each given file here. That list includes all nested fragments, and if a fragment is spread N times in the same file, it and of its nested fragments will be included N times. externalFragments is then passed as a config to plugins here.
typescript-operations includes externalFragments into allFragmentshere and then passes it to TypeScriptDocumentsVisitorhere, which passes it to SelectionSetToObjecthere, which passes it to getFieldNameshere.
getFieldNames iterates over its first argument (selections) and when it finds a fragment spread, it calls itself passing loadedFragments.filter(def => def.name === selection.name.value).flatMap(...) as the selections argument here. That's where the issue happens: because the same fragment is included multiple times in loadedFragments, the recursive function call will iterate multiple times over the same fragment. If that fragment has a nested one, the same will happen to it, and so on.
All that means that if a fragment is spread M times and has N levels of fragment spreads (e.g. if fragment A spreads fragment B, which spreads fragment C, which doesn't spread anything, N = 3), getFieldNames will be called at least M^N times.
The text was updated successfully, but these errors were encountered:
vhfmag
changed the title
Repeat fragment spreading causes perf issues with near-operation-files + typescript-operations
Repeated fragment spreading causes perf issues with near-operation-files + typescript-operations
Jun 21, 2024
Which packages are impacted by your issue?
@graphql-codegen/near-operation-file-preset
Describe the bug
While investigating an issue with graphql codegen taking too long in the pipeline of one of my company's projects, I came across a performance issue caused when spreading a deeply nested fragment multiple times in the same file. The issue happens when
near-operation-file
andtypescript-operations
are used together, and is ultimately caused due to the first supplying repeated input to the latter.Here's how it works:
near-operation-file
resolves document imports here and then generates a list ofexternalFragments
for each given file here. That list includes all nested fragments, and if a fragment is spread N times in the same file, it and of its nested fragments will be included N times.externalFragments
is then passed as a config to plugins here.typescript-operations
includesexternalFragments
intoallFragments
here and then passes it toTypeScriptDocumentsVisitor
here, which passes it toSelectionSetToObject
here, which passes it togetFieldNames
here.getFieldNames
iterates over its first argument (selections
) and when it finds a fragment spread, it calls itself passingloadedFragments.filter(def => def.name === selection.name.value).flatMap(...)
as theselections
argument here. That's where the issue happens: because the same fragment is included multiple times inloadedFragments
, the recursive function call will iterate multiple times over the same fragment. If that fragment has a nested one, the same will happen to it, and so on.getFieldNames
will be called at least M^N times.Your Example Website or App
https://github.com/vhfmag/codegen-perf-issue-repro
Steps to Reproduce the Bug or Issue
yarn codegen
frags.ts
and spread it into the last oneyarn codegen
— it should take 4 times as long as it did before because we spread fragment A 4 times in theops.ts
fileExample change:
Expected behavior
Time complexity should increase linearly with M & N
Screenshots or Videos
No response
Platform
graphql
version: 16.2.0@graphql-codegen/near-operation-file-preset
version(s): 3.0.0Codegen Config File
Additional context
No response
The text was updated successfully, but these errors were encountered: