frontend-patterns/research/candidates/ProgressiveEnhancement.md

97 lines
5.5 KiB
Markdown
Raw Permalink Normal View History

---
title: Progressive Enhancement
status: draft
maturity: hypothesis
families: [quality, execution, affordance]
scales: [L3, L6]
admission: research-candidate-only
---
# Progressive Enhancement
Context: essential reading/navigation or submission should work before optional
scripts arrive. Problem: delayed or failed client execution can block a usable
server-delivered interface. Resilience competes with interaction richness and the
cost of maintaining equivalent behavior across paths.
Proposed solution: give the essential task a usable HTML/link/form contract first;
add client behavior that preserves its meaning and authoritative validation.
Define which controls are essential and what enhanced behavior adds. Test absent,
late and partially failing scripts separately. Server-rendered text alone does not
establish a functional no-script task.
For enhanced navigation, preserve route, history, loading/error feedback and focus
semantics. For writes, avoid duplicate submission when falling back after an
uncertain response: reconcile the original operation before resubmitting it.
Keyboard operation, labels, status announcements and recovery focus need explicit
verification in both paths. Native elements help but are not an accessibility proof.
Consequences: initial tasks depend on fewer client capabilities, while parity and
failure recovery add design work. No-script support is not offline support. A
client-only rich editor may deliberately require scripts; name that requirement
instead of promising a fallback that cannot perform the task.
Evidence: [navigation review](../reviews/NavigationRenderingEvidence.md) N03–N05
locates htmx and SvelteKit mechanisms with specific link/form/action prerequisites.
These are two documentation families, not two verified deployments of this complete
contract. Full-pattern recurrence and decision benefit remain unknown. This develops
an existing seed; hypothesis only, no canonical identity or admitted relations.
Proposed connections: [URL-addressable State](URLAddressableState.md) supports shared
view selection; [Mutation Outcome Tracking](MutationOutcomeTracking.md) matters when
an enhanced write becomes uncertain. Neither is a universal dependency.
[VC-03](../walkthroughs/VC03-ContentPublication.md) explores a read-only core.
## Prospective runtime corroboration — 2026-09-27
Native links and GET filtering remain usable with JavaScript disabled or htmx
loading failed. An enhanced 503 keeps the old URL/view, and an explicitly provided
native recovery link navigates successfully. This does not establish automatic fallback,
late-script safety, accessible focus/announcements or offline availability.
See [NH01–NH06](../reviews/NavigationHistoryExperiment.md). One authored application
with a real package, not independent deployed recurrence. Hypothesis retained.
## Keyboard continuation and feedback — 2026-09-27
[Navigation focus experiment](../reviews/NavigationFocusExperiment.md) NF01–NF06
distinguishes successful route continuation, failed navigation, history restoration
and background updates. In the raw fixture, a replacement link retains focus but
fragment navigation leaves the old title and failures produce no visible status.
The authored policy updates title/status, selects a heading for direct continuation
and preserves a surviving control when the user has moved focus during the request.
Choose a continuation policy for the task; do not universally focus a heading or
return to the invoker. Check ownership when the response is applied, not only when
it is requested. Failure feedback need not move focus. Same-ID restoration is not
proof of semantic continuity. DOM/ARIA checks here do not establish spoken feedback;
AT, delayed history and overlapping-request behavior remain unverified.
## Separate completion and focus ownership — 2026-09-27
[Competing navigation](../reviews/NavigationOwnershipExperiment.md) NO01–NO06 exposes
limits of the preceding single-response policy. Validate applicability for each intended result
effect, including old errors and history restoration, not only before moving focus.
A current response may update content/title/status while the user has moved focus
to another surviving task; an obsolete response may own none of those effects.
The latest-intent policy tested here does not revive older success when newer intent
fails. Ignoring completion does not abort or undo server work.
A scoped navigation generation and separate focus-change check meet the tested
obligations. Their history adapter depends on pinned htmx internals; multiple history
misses, nonzero swap delays, redirects, lifecycle teardown and AT validation remain
open. Do not apply this navigation policy indiscriminately to unrelated background work.
## Effect-specific applicability contrast — 2026-09-27
[Zulip source study](../reviews/ZulipNavigationSourceStudy.md) ZN02–ZN04 shows a useful
contrast: noncurrent fetches may update cached data, while selected-view continuations
check list identity. Shared connection feedback and view-specific errors have different
scopes. Do not turn the earlier generation guard into a blanket discard rule for
every result from a view the user has left. Define data/cache acceptance separately
from current-view, feedback and focus effects, with their own consistency contracts.
This is static support for an asynchronous-navigation obligation, not evidence that
Zulip supplies the native/no-script path required by this whole candidate. Some
auxiliary continuations lack a visible matching guard in the inspected code; runtime
behavior and transport/caller limits remain unknown. Hypothesis retained.