Repository: gatsbyjs/gatsby
File: packages/gatsby-source-contentful/src/extend-node-type.js (JavaScript)

Code before:

          const rawReferences = { Entry: new Set(), Asset: new Set() }

          // Locate all Contentful Links within the rich text data
          const traverse = obj => {
            for (let k in obj) {
              const value = obj[k]
              if (value && value.sys && value.sys.type === `Link`) {
                rawReferences[value.sys.linkType].add(value.sys.contentful_id)
              } else if (value && typeof value === `object`) {
                traverse(value)
              }
            }
          }

          traverse(JSON.parse(source.raw))

          if (!rawReferences.Entry.size && !rawReferences.Asset.size) {
            return []
          }

          const rawEntries = Array.from(rawReferences.Entry)
          const rawAssets = Array.from(rawReferences.Asset)

          // Query for referenced nodes
          const resultEntries = await context.nodeModel.runQuery({
            query: {
              filter: {
                contentful_id: { in: rawEntries },
              },
            },
            type: `ContentfulEntry`,
          })

          const resultAssets = await context.nodeModel.runQuery({
            query: {
              filter: {
                contentful_id: { in: rawAssets },
              },
            },
            type: `ContentfulAsset`,
          })

          // Localize results
          const nodeLocale = parent.node_locale

          const findForLocaleWithFallback = (nodeList = [], referenceId) =>
            nodeList.find(
              result =>
                result.contentful_id === referenceId &&
                result.node_locale === nodeLocale

Review comment (performance):
General remark for the remainder of this function;

I think it'd be more efficient to tap into the nodes directly. There ought to be a `getNodesByType` api you can tap into. Then for each element of the two sets above you can search through the returned list.

```js
const assetNodes = getNodesByType('ContentfulAsset')
const rev = new Map
// If the `contentful_id` is not unique, you can create a pair with the locale
assetNodes.forEach((value, key) => rev.set(value.contentful_id, value)) 
// Then processing the raw entries should be near-instant
const localizedEntryReferences = []
rawReferences.Entry.forEach(({contentful_id}) => localizedEntryReferences.push(rev.get(contentful_id)));
const localizedAssetReferences = []
rawReferences.Asset.forEach(({contentful_id}) => localizedAssetReferences.push(rev.get(contentful_id)));
```

You could even manually generate a reverse lookup list first, to make the match super fast.

Code after:
      },
      references: {
        type: [`ContentfulReference`],
        async resolve(source, args, context, info) {
          const parent = await context.nodeModel.findRootNodeAncestor(source)

          const rawReferences = { Entry: new Set(), Asset: new Set() }

          // Locate all Contentful Links within the rich text data
          const traverse = obj => {
            for (let k in obj) {
              const value = obj[k]
              if (value && value.sys && value.sys.type === `Link`) {
                rawReferences[value.sys.linkType].add(value.sys.contentful_id)
              } else if (value && typeof value === `object`) {
                traverse(value)
              }
            }
          }

          traverse(JSON.parse(source.raw))

          if (!rawReferences.Entry.size && !rawReferences.Asset.size) {
            return []
          }

          const rawEntries = Array.from(rawReferences.Entry)
          const rawAssets = Array.from(rawReferences.Asset)

          // Query for referenced nodes
          const resultEntries = await context.nodeModel.runQuery({
            query: {
              filter: {
                contentful_id: { in: rawEntries },
              },
            },
            type: `ContentfulEntry`,
          })

          const resultAssets = await context.nodeModel.runQuery({
            query: {
              filter: {
                contentful_id: { in: rawAssets },
              },
            },
            type: `ContentfulAsset`,
          })

          // Localize results
          const nodeLocale = parent.node_locale