This is a legacy document and covers some of our early justifications
You've read the Explainer and you're still wondering "why the heck do we need the Navigation Controller?"
You've arrived at the right document -- not least of all because the other two aren't set up as explanations of the why, but more as expositions of the how.
The indispensable Jake Archibald has written persuasively on the topic of why AppCache (as currently conceived and re-conceived in recent proposals) is insufficient to the task, and this document is (where it refines) a refinement of those points. You are encouraged to seek out his thinking independent of this tract -- a document that focuses on 3 main failings; in order from least-to-most problematic:
- Composition: AppCache (and its recent iterations) deal with composition via pre-flattening: applications must create centrally managed lists of required resources, updating these lists every time the required set of items changes. This reflects the "chrome, not content" bias of AppCache and scales so poorly to distributed, large-scale server environments (multi-homed, load-balanced, and rolled out in stages) that it has already been identified as a central design failure by Facebook (among others). It remains unrepaired in both the latest AppCache drafts and proposed "AppCache v2" declarative forms. The larger failure is an inability to deal flexibly with mutually distrustful parties. AppCache provides no road to safe coordination between, e.g., font foundries and their customers in a cached scenario, depriving apps of creative flexibility easily afforded to native brethren or dooming their offline versions to a sub-standard experience. There's no standard contract for "here's how you cache off-domain resources without offending the other party" and AppCache is singularly unprepared to evolve to a world of lightweight collaboration.
- Misplaced Efficiency Arguments: there is a deeply worrying strain of argument that pervades that debates around AppCache and Navigation Controller about the risks and rewards to be gained from the ability for developers to make "things that work offline" and the effort required to get there. The simplistic form of these views biases spec development not towards development of a coherent system for the co-operative creation of reliable systems, but towards the shortest thing to type. This misreads both our recent collective experience and the amount of data underlying the intuitions that precede this bias. Were the current systems powerful, scriptable, and lacking in short-form versions, we might observe libraries filling gaps in our current efforts. In such a scenario the general approach of Hussmanesque re-imagination of existing infrastructure to support clearly demonstrated needs -- as notably pursued by the Parkour team -- might hold sway. But this is not where we (collectively) are. Instead, the honest observer must concede a series of user-unpatchable failures, leading to a desolate landscape of powerless, forlorn web developers witnessing their native compatriots passing them in both fundamental power and library choice. Another variant of misplaced efficiency argument imagines (without data!) that current implementation state is the end of our collective creativity regarding threading, lifecycle management, and signal-fed optimization opportunities, despite the Navigation Controller spec being explicitly designed to enable UA's to make (many) choices in nearly all corner cases which have performance impacts.
- Model Failure: the "patch and pray" model of changes to the HTML 5 AppCache spec is excusable at first, second, and third. But given the enormously long cycle times suffered by web developers attempting to adopt each new (fully-declarative, non-polyfillable) iteration, coupled with the intrinsic insecurity of not having direct programmatic control over caches and navigation dispositions, it becomes ever more difficult to write off the long trail of failure that follows AppCache everywhere it goes as "teething problems". Indeed, the latest
INTERCEPT
and (confus[ed|ing]) API additions speak to a spec in crisis. It knows it needs to hand power back to programmers, but has not created avenues to do this. Each new escape hatch lacks rigor and coherence, explaining little, if anything, about the levels above it while providing only momentary respite for the programmers who learn enough of AppCache to understand that they must pile most of their applications into these misshapen outlets. It is time for a new approach that fundamentally empowers developers and treats performance as an (anticipated) implementation concern.
Let's not beat around the bush: AppCache and its successors attempt a scenario-solving style of spec development in a problem domain its authors fundamentally did not understand. And it shows.
Our efforts to enable pervasive offline have been long on self-assurance about what to do and light on evidence. Instead of admitting that we don't know the entire problem space, the needs of all classes of developers, and the architectural styles that they will employ based on their constraints, we have instead blundered forward based on assumptions -- assumptions about app architecture, about the commonality of the situation described by our loudest customers, and about the completeness and usability of our last best effort.
Navigation Controllers represent a departure from hubris: by creating primitives that developers can explore (and yes, make mistakes with!) we create a space in which iteration can happen faster than the interoperable center of deployed browser features can expand. In sharp contrast to AppCache, Navigation Controllers require that we only expand the interoperable center once, powerfully, and then observe the winning patterns in order to discern what to standardize next.
A key question for all web specs must always be "what is the role of a declarative form in this design?" The Parkour project has sought to reckon with this question regarding extensions to HTML elements in depth, at length, based on extensive library development and use as well as tremendous amounts of research and consultation with those most invested in delivering tools to web developers. As a result the project has created primitives that developers covet enormously: they explain existing behaviors and expand our collective horizons by decoupling the primitives from the declarative. These extensions, declarative and otherwise, have relied on strong evidence from a decade of library development, enabled in large part by giving web developers "too much" power to make tremendous messes. It is, however, these "messes" of unsemantic markup and impossibly-deep DOMs out of which our repairs have been informed. We can make efficient what we observe that developers (needlessly) do too much of. What we can't do, however, is anticipate everything everyone might do.
A related question is often confused for the preceding query: "what forms must be declarative?". In the case of the Navigation Controller, it seems that the answers are largely related to features it has not yet gained:
- The ability to request bundles of permissions to elide runtime prompts
- The ability to request installation with affordances (app icons, etc.)
- System-enforced declarations of intent regarding relationships to other origins (e.g., CSP) and storage use
None of these require that AppCache or its successors weigh in on questions of resource caching, navigation to URLs, or application initialization. What we have witnessed, therefore, appears to be a bait-and-switch: we have come to understand that some features must be declarative while choosing not to address them for the open web.
That isn't to say that declarative forms aren't good and that we can't and won't evolve towards them. Indeed, "static routes" in Navigation Controllers are an early example of cow-path-paving: by creating a fully de-sugarable feature that has a terser form and a browser-fast-path implementation opportunity, Navigation Controllers are showing that it's possible to "evolve upward" to deliver both explanations for new features and improved performance over the long term for truly common patterns. This is the beginning of an evidence-based process of feature evolution that depends not on expanding the power of the overall system but observing states of nature and evolving to get better at the common cases. It's a method of evolution that AppCache can never hope to embody.
The time for clearer air is now: we must focus first on providing declarative forms for what only the declarative can do, leaving the rest to evidence, and where that is scant, to systems that provide the hope of collecting such evidence in the future. We have failed too much, too long to deceive ourselves further on these points.