Problem
The assignment-response review UI remounts its DoenetViewer iframe from scratch on every selection change: apps/app/src/views/AssignmentItemResponseStudent.tsx:157 keys the viewer with
key={`${user.userId}|${itemAttemptState.itemNumber ?? ""}|${attemptNumber}`}
so switching student, item, or attempt tears down the iframe and rebuilds it — a fresh ~29 MB standalone-bundle parse plus a full core worker boot (~180 MB churn and a multi-second wait) per click while an instructor pages through responses.
Current constraint
Today this is hard to avoid: @doenet/doenetml-iframe bakes all props into the iframe srcDoc, so changing doenetML/initialState props reloads the iframe anyway (Doenet/DoenetML#1436). The explicit key at least makes the reload deterministic.
Proposed change
Once Doenet/DoenetML#1436 lands (message-based prop updates, core re-init inside the same realm for source/state changes):
- Drop the composite key and let the viewer receive the new document/state via props, so selection changes re-initialize the core (~1–2 s) inside the already-parsed realm instead of rebuilding the realm.
- Verify the review flags (
forceDisable, shown responses, etc.) update correctly through the live-update path.
Related observation (lower priority): the two side-by-side editor pages (DoenetMLComparison.tsx:152/197, DocEditorHistoryMode.tsx:235/322) each hold two full editor iframes (~2 × editor cost) while open — by design, but the second editor could mount lazily on first selection.
Impact
Instructor review paging goes from a full embed boot per click to a core re-init per click; roughly 5–10× faster switching and far less memory churn on the heaviest instructor workflow.
🤖 Generated with Claude Code
Problem
The assignment-response review UI remounts its
DoenetVieweriframe from scratch on every selection change:apps/app/src/views/AssignmentItemResponseStudent.tsx:157keys the viewer withso switching student, item, or attempt tears down the iframe and rebuilds it — a fresh ~29 MB standalone-bundle parse plus a full core worker boot (~180 MB churn and a multi-second wait) per click while an instructor pages through responses.
Current constraint
Today this is hard to avoid:
@doenet/doenetml-iframebakes all props into the iframesrcDoc, so changingdoenetML/initialStateprops reloads the iframe anyway (Doenet/DoenetML#1436). The explicit key at least makes the reload deterministic.Proposed change
Once Doenet/DoenetML#1436 lands (message-based prop updates, core re-init inside the same realm for source/state changes):
forceDisable, shown responses, etc.) update correctly through the live-update path.Related observation (lower priority): the two side-by-side editor pages (
DoenetMLComparison.tsx:152/197,DocEditorHistoryMode.tsx:235/322) each hold two full editor iframes (~2 × editor cost) while open — by design, but the second editor could mount lazily on first selection.Impact
Instructor review paging goes from a full embed boot per click to a core re-init per click; roughly 5–10× faster switching and far less memory churn on the heaviest instructor workflow.
🤖 Generated with Claude Code