- From: Tab Atkins Jr. <jackalmage@gmail.com>
- Date: Fri, 16 Oct 2009 13:06:53 -0500
Promoting this reply to top-level because I think it's crazy good. On Fri, Oct 16, 2009 at 11:09 AM, Aryeh Gregor <Simetrical+w3c at gmail.com> wrote: > On Fri, Oct 16, 2009 at 10:16 AM, Tab Atkins Jr. <jackalmage at gmail.com> wrote: >> As well, this still doesn't answer the question of what to do with >> script links between the static content and the original page, like >> event listeners placed on content within the <static>. ?Do they get >> preserved? ?How would that work? ?If they don't, then some of the >> benefit of 'static' content is lost, since it will be inoperable for a >> moment after each pageload while the JS reinitializes. > > Script links should be preserved somehow, ideally. ?I would like to > see this be along the lines of "AJAX reload of some page content, > without JavaScript and with automatically working URLs". [snip] > I'm drawn back to my original proposal. ?The idea would be as follows: > instead of loading the new page in place of the new one, just parse > it, extract the bit you want, plug that into the existing DOM, and > throw away the rest. ?More specifically, suppose we mark the dynamic > content instead of the static. > > Let's say we add a new attribute to <a>, like <a onlyreplace="foo">, > where "foo" is the id of an element on the page. ?Or better, a > space-separated list of elements. ?When the user clicks such a link, > the browser should do something like this: change the URL in the > navigation bar to the indicated URL, and retrieve the indicated > resource and begin to parse it. ?Every time an element is encountered > that has an id in the onlyreplace list, if there is an element on the > current page with that id, remove the existing element and then add > the element from the new page. ?I guess this should be done in the > usual fashion, first appending the element itself and then its > children recursively, leaf-first. This. Is. BRILLIANT. Single-page apps are already becoming common for js-heavy sites. The obvious example is something like Gmail, but it's becoming more common everywhere. The main benefit of doing this is that you never dump the script context, so you only have to parse/execute/apply scripting *once* across the page, making really heavy libraries actually usable. In fact, writing a single-page app was explicitly given as a suggestion in the "Global Script" thread. Even in contexts with lighter scripts, there can still be substantial run-time rewriting of the page which a single-page app can avoid doing multiple times (frex, transforming a nested list into a tree control). The problem, though, is that single-page apps are currently a bit clunky to write. They require javascript to function, and the necessary code is relatively large and clunky, even in libraries like jQuery which make the process much simpler. It requires you to architect your site around the design, either producing a bunch of single-widget files that you query for and slap into place, or some relatively complex client-side logic to parse data structures into HTML. It's also very hard to get accessibility and graceful degradation right, requiring you to basically completely duplicate everything in a static form. Finally, preserving bookmarkability/general deeplinking (such as from a search engine) requires significant effort with history management and url hacking. Aryeh's suggestion, though, solves *all* of these problems with a single trivial attribute. You first design a static multi-page site like normal, with the only change being this attribute on your navigation links specifying the dynamic/replaceable portions of the page. In a legacy client, then, you have a perfectly serviceable multipage site, with the only problems being the reloading of js and such on each pageload. In a supporting client, though, clicking a link causes the browser to perform an ordinary request for the target page (requiring *no* special treatment from the author), parse/treebuild the new page, and then yank out the relevant fragments and replace bits in the current page with them. The url/history automatically updates properly; bookmarking the page and visiting it later will take you to appropriate static page that already exists. Script context is maintained, listeners stay around, overall page state remains stable across 'pageloads'. It's a declarative, accessible, automatic, and EASY way of creating the commonest form of single-page apps. This brings benefits to more than just the traditional js-heavy apps. My company's web site utilizes jQuery for a lot of small upgrades in the page template (like a hover-expand accordion for the main nav), and for certain things on specific pages. I know that loading the library, and applying the template-affecting code, slows down my page loads, but it's not significant enough to be worth the enormous effort to create an accessible, search-engine friendly single-page app. This would solve my problem trivially, though, providing a better overall UI to my visitors (snappier page loads) without any real effort on my part, and without harming accessibility or SEO. This also trivially replaces most/all uses of bad mechanisms like <frameset> used to address similar problems (such as maintaining state on a complex nav). The only addition I'd make to this is to allow a tag in the <head> that specifies default replaceability for all same-origin links. Perhaps just an attribute on <base>? It would accept a space-separated list of ids, just like the @onlyreplace attribute on <a>s. An @onlyreplace attribute on a link would completely override this default (this would allow me to, frex, have the mainnav only replace the subnav, while all other links replace the content instead). I believe that the single-page app pattern solves a lot of problems that exist today and will persist into the future, and that it's worthy of being made into a declarative, html-supported mechanism. I also believe that Aryeh's suggestion is the correct way to go about this. The only problem I can see with this is that it's possible for authors to believe that they only need to actually write a single full page, and can just link to fragments containing only the chunk of content to be replaced. This would mostly break bookmarking and deeplinking, as visitors would just receive a chunk of unstyled content separated from the overall page template. However, because it breaks so *visibly* and reliably (unlike, say, framesets, which just break bookmarking by sending you to the 'main page'), I think there would be sufficient pressure for authors to get this right, especially since it's so *easy* to get it right. Thoughts? ~TJ
Received on Friday, 16 October 2009 11:06:53 UTC