Today I Learned

Daily reflections on work and learning—what I did and what I learned.

20267

2026-07-07

Making Nested UI Re-renders O(1) — read-model, external store, and render-count tests

In an immutable-tree editor, editing a single line redrew everything; here's how I first pinned the problem with a test, then cut row and container re-renders with a normalized projection and per-id subscriptions

  • An immutable tree patch gives ancestors a new ref too, so passing props down triggers O(depth) re-renders — a normalized entry plus per-id subscription can cut it to O(1)
  • The entry cache must be stabilized by output value-equality, not input ref, and the external store sync must run synchronously at the choke point right before setState
2026-07-06

Bundle Shared Vendor, Cross-Block Selection, Floating-UI Coordinates

webpack splitChunks traps, cross-block range operations in a hybrid editor, selectionchange·scroll anchor patterns, Context subscription separation

  • Using chunks:all with a fixed name on a catch-all vendor pulls dynamic imports up into a shared chunk.
  • For cross-block text operations, stateless derivation from getSelection + a single boundary split is safer than range state.
2026-07-05

Block-Editor Ordering, Collaboration, and Keyboard Contracts

General patterns: fractional ordering, optimistic rebase, IME defer, keyboard undo delegation, scoped popover, Jest ESM shim, and more

  • For sibling ordering, a fractional position key + neighbor anchor + tie-break is better for concurrent inserts than an integer index.
  • Optimistic UI can't rebase without an inverse patch, and the remote seq must be the merge authority.
2026-07-04

The Document Is the Host SoT; the Editor Is a Focused Guest

Explaining, for a first-time reader, the host/guest boundary in a block-document editor, React external-store snapshots, the 2-stack undo, and HTML5 drag and selection/copy

  • Document meaning is owned by host patches, and the rich-text engine is kept only as a guest for the focused block.
  • Using only a ms timestamp in a useSyncExternalStore snapshot drops re-renders on same-ms mutations — a monotonic revision is needed.
2026-07-01

Long Lists: flatten → SSR First Slice → virtualizer

A pattern that separates infinite scroll from list virtualization, guarantees first HTML with an SSR static gate, then switches to a virtual list

  • Infinite scroll controls the data-exposure ceiling; virtualization controls the DOM ceiling — each separately.
  • Flatten a nested group UI into header/item rows before feeding it to the virtualizer.

20266

2026-06-30

Direct-Upload Contract, CSS-Token Theming, Hydration Boundaries

Shared principles learned from the 4-step presigned-URL upload, a single generator for @layer-based token theming, and fr layout with post-mount hydration

  • A presigned-URL upload is a 4-step contract of presign→PUT→complete→create, and skipping the complete notification means the backend never registers the upload.
  • CSS-token theming must separate @layer (priority), @scope (scope), and light-dark() (mode), and unify runtime and build CSS under a single generator so they don't diverge.
2026-06-29

Choosing a Search Backend in a Serverless Environment

What to put inside vs. outside the function in serverless, and how to hide swappable search behind a provider contract

  • A search engine that needs to stay resident can't run inside a serverless function, but can be replaced by a pre-built in-memory index.
  • Build artifacts read at runtime must be declared in bundle file tracing, or they go missing on cold start.