Declarative Partial Updates - Customizing navigation experience
This page contains a video recording of the presentation made during the breakout session, along with a transcript. Video captions and transcript were automatically generated and may not properly translate the speaker's speech. Please use GitHub to suggest corrections.
Table of contents
See also:
Video
Transcript
Room 504: Alright. We're going to talk about the clarity of partial updates, which is… I'm not sure if it's a good name still, but it's the name of the repo, and it grew from there, so I can bike-shed what a better name for it is, but… It's actually a collection of a few different things that have a few different features that have a common theme to them, or common purpose to them, and, we're designing them in a way that each of them, on its own, makes sense or works, regardless of the rest of the… They look very separate, but they're… because they're built together in a common theme, they should also work nicely when combined.
Room 504: I'm gonna do the first part, kind of BFS, like go over all of it. Very shallow peak, because it's not a long presentation, and then we can do deeper dives just based on interest and questions from the room. We can go back and talk about the different things based on what the room wants. What do you guys want to discuss, but hopefully that would work, and not… too overloading and confusing.
Room 504: It's a stock photo from… a picture from the… Template, I mean.
Room 504: The motivation behind all this is kind of broad. This is about navigation experience. On the web. We want to make the navigation experience what it feels like To move between pages, or to move between states. Translation, whatever page means, We want to make sure it's fast, we want to make sure it's smooth. And we want to make sure it's customizable, so that it can be part of a brand, be part of whatever the designer wants to do, just part of the creativity of the web. One part that we'll see later is that fast and smooth sometimes are in cahoots with each other. You have to… Feels like in the last year, so many of the features I worked on were called defer" something or something later, but we have fetch Later now, the fair navigation commit, keep any… or render blocking, we keep having to do things later. Well, we want things to be fast, and a lot of it is this trade-off between fast and smooth.
Room 504: Like, if you animate something, it's definitely going to be slower than just showing the end photos. Animations are, by default, slow. The slower then the fastest you can be, so… this fast and smooth trade-off is something I always found fascinating, and this is part of it. And the third part is customizable. We don't want to just make decisions for all our… all the authors. In this, but rather, let them make the decision for themselves.
Room 504: One design principle for this whole aspect of all this features is that declarative is key. Now, declarative is a word that can be overloaded by many meanings. We chose a very specific meaning for what declarative is. It means less event-driven JavaScript, less JavaScript that you have to do in real time, respond in real time to something that happens, and write code that does something in that particular time. Declarative doesn't mean no JavaScript, for example. You can have JavaScript in advance that defines a set of rules. And it's still declarative in that sense, because the script doesn't run in real time, it's part of an interaction. Just a definition, not the correct one, really.
Room 504: And the idea is that when we have things that are more declarative by that definition. We have less jank, because we're running less JavaScript code at that time. We have less bundle size for the all JavaScript altogether. We have less lifecycle errors, because declarative solutions tend to have better error handling than script. We just throw everything. And we have more opportunities for the browser to optimize, because we're at the higher level usually.
Room 504: There are more things here than I can fit. Anyway, we have, three… let's say, meta features or aspects of the web that we tackled around our navigation experience. One of them is simply updating the DOM. Right now, updating the DOM, there are low-level DOM APIs for this, you just use one DOM node at a time, or one fragment at a time. You can stream to the main You can stream in order to the main document, in the main document response. But when you start wanting to update the document, you can't stream. When you stream, you have to be in order, like, there's a lot of things that end up pushing you to having to write scripts in real time that update the DOM for every change in the DOM. And that's what frameworks basically do most of the time. They respond to events, and then do the actual updates in the DOM one update at a time, so that's an event-driven, non-declarative thing.
Room 504: We have two solutions to that that we'll talk about. One is our out-of-order streaming, and one's stream to element.
Room 504: With gestures, right now. The two gestures that are natively supported, in the web, are a scroll. It's a gesture. And click, it's also a gesture. And what we see is that most mobile websites today are just a bunch of scrolls and clicks, while their native counterparts and their native counterparts are not that. There are a lot more gestures, there are a lot of swiping going on. Swipe to dismiss, open to refresh, swipe to subscribe or unsubscribe or remove something. And… drawers that go in and over scroll. All those kind of things. We see that when people try to do them on the web, they again have to do it with libraries that deal with touch events, or pointer events, whatever. And… Not declarative. Doing overscroll in a way that doesn't go event by event, it's actually really difficult. I try to do it a while ago, you need a combination of positions sticky and multiple… multiple scroller elements, and it doesn't scale at all, and a lot of people choose to just not do it, and then that's how the mobile web looks like.
Room 504: The other one is snap-to-activate, I'll get to that, but It's the idea that with gestures, you form actions. You don't just scroll and change what you see, like, all this. So I have to dismiss, and all this stuff. I was talking about. Those are actions. The things we can't see here is… the UI during navigation. I'll get to that, each of them.
Room 504: And this is another value of declaratives that we found in… This whole thing. I came to my latest step. Step in browser development through the web performance… a lot of web performance work, and We found that a lot of web performance issues are caused from main thread congestion. People doing way too many things on the main thread. A lot of the value of this work is to be able to delegate certain things, mainly content templating, to a worker or the server, Room 504: or other things to the 104 worker or server, and gestures and other UI… more UI things to the compositor, and to… I think that the browsers can parallelize without having to add a JavaScript thread.
Room 504: So, first one is Stream to Element. And the value of streaming to Element is being able to drive UI updates from a server from a worker. Like, like we just discussed. It's just… From a server, it's very common To main frameworks to, Like, in React it's render to stream, which takes a React tree that is not ready, and stream placeholder, etc. And other frameworks, like Marco, have this. Other frameworks didn't get to it, like Nuxt doesn't have it and have an open issue for it. And the other thing is with UIs that are very dynamic. I think, We haven't talked about AI today at all, right? So this is gonna be the first one. With chat style, chat-style UIs are very common today, and those are very dynamic, and they come they are served as they come, and if you notice in some of those UIs, they're sometimes updated, not exactly in the order they come. et cetera, so it's… it's becoming more and more that these UIs are dynamic rather than being static, so… Here's some code in the beautiful code coloring of this template.
Room 504: So this is how stream to element is currently proposed. We create… we stream HTML to an element of shadow root. The word unsafe here means that we have to trust the source, but there could be a safe version with a sanitizer. Both are okay. Unsafe here doesn't mean that. It just means we have to trust the source. This is how you would use it. You can get a response body, You pipe it through text in text decoder, and then you pipe it to the element. From that moment on, the HTML just goes from the response to the element, etc. Or you can create a worker that does it, post the writable to the worker. And the worker can do templating, you can render to stream with React in that worker, or through all kinds of other… things to your liking. The platform is not opinionated about what it is.
Room 504: When I show those things, we can return to them, so… And… depth. more questions at the end? I think with all of them, and then think of which one you would want to return to, even though they're a bit broad. It's easier for me right now.
Room 504: And this is the other wave, it's Out of order streaming is just serving the content when it's ready. This is a very common case for having a select box for countries, for example. We have a select box for countries with just an option called loading. And then you call your unoptimized, that database that get countries. That is localized in the thing you want, and it's exactly… This, and you use the template element. With a content method, and you append, or you replace children. Do that… here it should be replaced children, because you want the loading to go away. And you can replace things out of order based on the order which… in which the server is ready, or whatever. The order you want.
Room 504: Next one is over-scroll gestures. We talked about it. All this drawer… first LUIs, or having a button that you only get to after you scroll. For example, in the BlueSky app, you can move between tabs, and then if you get to the last one, and you scroll again, the menu appears. It's the… It's a common over-scrolled practice in native, and this guy specifically has it in their native app and not in their PWA. And I found that sad. Like, it's a degraded experience, because things are hard. Don't take the solutions here. The solutions for the previous ones are more advanced in terms of spec discussions. The CSS ones are not as advanced yet, in terms of how much we talked about them in the working group. And so, it might change, but this is what we have now.
Room 504: For example, for a drawer menu, we can say that the container has an named overscroll area. And the manual… Attached itself to that over-scale area. And positioned itself, so… That menu is, like, a little thing on top of the container that will Whoa. Scroll over it, if nothing else is scrolling. And we'll discuss this more at the CSS Working Group on Friday morning. Feel free to ask things about it out. And if things are more confusing than others, and either that's cooked, whatever.
Room 504: The other one is snap to activate. Use cases we discussed is this… Swipe to dismiss, or pull to refresh. Swipe to delete an item from a list. And we're basically thinking of these gestures as a progressive enhancement on top of clicking. Often you would have also a button that does the same thing. It's some… there is an accessibility guideline for it, often there is also a refresh button somewhere. We're thinking of all those swipes as kind of a progressive enhancement, but you don't have to click. You can also do things by scrolling the container and using Snap. It's not point as a… Oh, I scroll-snapped to this place? What I actually meant is to click something. And there's… Nice things about doing that is that we've discussed this in the ARIA Working Group. The initial conversation in the ARIA Working Group yesterday. But that if we do it right. We can also connect it to Screen readers in a way that communicates it in a way that is, like: Oh, if you scroll to the left, you're going to show the menu. If you scroll up, you're going to reload, which is what happens today in native UIs.
Room 504: We need that semantic expression rather than just positioning things and using scroll or snap change events, and then trust the developers to put area action or something in it. We can level it and invest.
Room 504: And the other thing is that we can have all kind of predictive things, basically. The nice thing about swiping and snapping that we know where you're going to snap, or you might snap. If you're swiping to a place that's gonna load new content, we can already predictively load that content. If you're trying to reveal a list… a tab in a list of tabs, and that tab is new content that is maybe streamed from somewhere, then we can predictively loaded.
Room 504: And this is not designed at all, but, it's just totally strawman, but not even sure it's going to be CSS versus HTML, but right now we see it as a progressive enhancement, like pointer event, where you create a relationship that this particular... Right, and that when you scroll snap to it, it actually clicks itself, or a different item. That's relationship.
Room 504: And… The other two are about studying the navigation experience. It's very broad, like I said, and bear with me. Also, part of it is overview for people to say, oh, this one interests me, and we didn't talk about it enough, so I can go to the repo and, like, find out where the issues are, and they… Go back to them, because… I found that there were lots of sessions here that I just didn't get to, and, like, wasn't even aware of, so… And I'm not gonna apologize anymore for being too proud.
Room 504: So, CSS routes matching. This is about styling the navigation experience. We recently… A year and a half ago, we released the cross-document View Transitions. Which is a new way to style the navigation experience. You create an animation declaratively between two pages. But what we found is that in order to make it customizable in any way, you need to know where you're going from and where you're going to. Like, often things were directional, for example. You have tabs, in your mental model, and you want things to slide in top order. And in order to know where you're going to fall into, currently, you need to intercept the page for the events on both sides, check which URL you're buying from, and which URL you're coming to. And, like, make CSS decisions based on that. So again, for not the clarity is there. And… I don't remember who, but on BlueSky just a few days ago, was saying that using cross-document view transitions without a navigation API is like flying without a direction. It's just flying… flying into the air, and… There are customers, of course, documentary transitions that just don't do directional animation, because it's too hard as to use script. For that, we are going to talk on Friday morning about CSS route matching. And it's basically styling things based on where you're at, where you're going to, where you're going from.
Room 504: The names here are based on named URL patterns that will define either in CSS or HTML, but you can use the inline URL pattern, which I didn't put in there. And in the example, but for example, here you can say that when you're going from a movie list. Two movie details. Your view transition is going to look like expanding a thumbnail to the hero image. Who can express all of this. All of this. Customizable navigation experience with CSS, or where it belongs.
Room 504: And the last thing is customizing this experience, this preview with a script, which is preview before commit. Allowing two-phase navigate… two-phase transitions. Where are we? Before we switch to the next page, we show something We show an animation, and maybe let it run through. We show some exit thing. And for that, we're using some script. This is not exactly declarative, but it is customizable. We can do something, like, if we're… not ready to render yet, we're going to show if… The same document view transition of a preview. And wait until finished, and only then… The navigation is going to come in. Or this can be declarative by saying that any particular animation can Prefer to be completed before the new page commits.
Room 504: And let's see… Okay. This is it for all the things, and I want to get to the queue, because it's a lot.