Skip to content

lazy-load the Tiptap composer

jedmund requested to merge jedmund/lazy-composer into main

Created by: jedmund

Audit #9: the ~1.7MB Tiptap chunk was statically pulled in by 10 admin routes (all edit/new form pages + the posts list page). This adds a LazyComposer.svelte wrapper that dynamic-imports ComposerCore on mount, so Tiptap only loads when the editor is actually about to render.

Change

  • New LazyComposer.svelte — thin wrapper that does await import('./ComposerCore.svelte') inside onMount, forwards all props + bind:data, and re-exports the editor's focus/blur/clear/isEmpty/getContent/getText methods so bind:this still works on the wrapper.
  • 6 consumers swapped to import LazyComposer instead of the barrel: AlbumForm, ProjectForm, GardenItemForm, InlineComposerModal, /admin/posts/new, /admin/posts/[id]/edit.
  • Placeholder — a small spinner renders in the composer's footprint while the chunk loads.

Measurement

Checked the built chunk graph by finding the chunk that contains Tiptap and counting which route nodes statically reference it.

Before After
Admin route nodes that statically load Tiptap chunk 10 0

Routes affected (/admin/albums/new, /admin/albums/[id]/edit, /admin/garden/new, /admin/garden/[id]/edit, /admin/projects/new, /admin/projects/[id]/edit, /admin/posts/new, /admin/posts/[id]/edit, /admin/posts, /admin/universe/compose) all now defer the ~1.7MB Tiptap chunk until the editor mounts.

Trade-offs

  • Short loading state on edit/new/compose pages — the rest of the form renders immediately; the composer area shows a spinner for one network round-trip before becoming interactive.
  • /admin/posts list page — the inline composer at the top shows the same spinner briefly on page load. Acceptable given the list itself is the primary content.
  • bind:this forwarding — the wrapper re-exports each editor method. If new methods are added to ComposerCore, they need to be forwarded here too.

Test plan

  • /admin/posts/new — spinner appears, composer replaces it, typing works, autosave fires
  • /admin/posts/[id]/edit — existing content loads into composer correctly
  • /admin/albums/new + /admin/albums/[id]/edit — album form fields render immediately; composer loads into the content area
  • /admin/projects/new + /admin/projects/[id]/edit — case study editor works
  • /admin/garden/new + /admin/garden/[id]/edit — notes editor works
  • /admin/posts list page — inline composer's "clear" button still works (calls editorInstance.clear())
  • /admin/universe/compose — modal composer works in both inline and full modes
  • Network tab on /admin/posts shows the Tiptap chunk loading lazily (not in the initial waterfall)

Merge request reports

Loading