Aalexbit-codemod

render-boundary-read-miner

Detect expensive cross-boundary reads inside React render paths

code-miningreactperformance
Public
0 executions

Run locally

npx codemod render-boundary-read-miner

render-boundary-read-miner

Detect expensive cross-boundary reads inside React render paths.

This is a read-only mining codemod. It emits JSSG metrics and does not edit source files.

Scope

The core detection logic applies to any React or TSX codebase. It looks for reads that cross process, thread, or subsystem boundaries inside render scopes — the kind of work that can cause jank when it runs on every paint.

This package includes a few repo-specific hooks for tldraw repo as a demonstration of how you can tailor a codemod to your own conventions. Those extensions are optional patterns you can copy, rename, or remove when adapting the codemod elsewhere.

What it detects

General React render scopes

  • Function components that return JSX
  • React class render() methods that return JSX
  • Render wrappers and callbacks such as memo, forwardRef, useMemo, and useCallback
  • One-hop derived helper functions called directly from a render scope

tldraw-specific extensions (demonstration)

These patterns are included to show how a codemod can be customized for a particular repo:

  • ShapeUtil.component() and ShapeUtil.toSvg() methods on classes named *ShapeUtil
  • tldraw reactive wrappers and callbacks such as track, useValue, useStateTracking, useQuickReactor, useReactor, computed, and react

To adapt this codemod for another project, edit scripts/codemod.ts: add your own render-scope classifiers, receiver names, and hook sets alongside or instead of the tldraw-specific ones.

Cross-boundary reads

Inside those scopes it emits metrics for likely cross-boundary reads, including:

  • Namespace reads such as wasm.*, Module.*, worker.*, engine.*, canvas.*, scene.*, runtime.*, and bridge.*
  • Repository-style reads such as store.get*(), model.get*(), doc.get*(), editor.get*(), editor.store.*, and app.get*()
  • Hot render paths such as JSX expressions, component bodies, collection callbacks, loops, and derived render helpers
  • Serialization or cloning around the read, such as JSON.stringify, Array.from, .toJSON(), .serialize(), and .clone()
  • Lower severity for memoized, cached, batched, or snapshot-style reads

Metrics

Each finding increments render-boundary-read with dimensions for severity, file, line, scope, boundary, operation, hot path, serialization, caching, and reasons.

The codemod also increments render-boundary-read-summary with lower-cardinality dimensions for rollups by severity, boundary, scope kind, and hot-path category.

Ready to contribute?

Build your own codemod and share it with the community.