 I barely ever only trim on one side. I usually just still trim. Is that a lifestyle choice? Welcome back to the AVDP203 World Cup of Web Preachers 2018. Bringing the enthusiasm back. That's really good. This is the episode where we find out who wins. Yes, it is. Because in the previous few episodes, we figured out one finalist. Do we reveal that now, or should we just see how it is? No, because I've forgotten, and I want to keep it that way, so I don't incorporate it into my decision. We did, in the last episode, figure out the other semi-finalist, which is the page life cycle API. Yes, correct. Why don't you just give the word page? It's part of the API name, isn't it? I'll just keep it, just make it simple. I'm going to try using that tactic of argument in this next phase as well. We do, we do, we do, we do, we do, we do, we do, we do. Just, oh, OK. Trim start, trim end. Once again, the font is making it almost legible. I feel like it says it. Yeah, OK, let it explain it to me. Trim? Gotcha. Remove them space at start and end. Trim left, trim right. I thought there was already left and right, so I wondered if you type out. Trim non-standard, but in pretty much all browsers, I think except Edge. OK. Trim start, trim end. There you go. So here's a question then, though. Does trim start behave differently in right-to-left languages? Oh, I was wondering that, but because there's no language applied to a JavaScript environment, yes, in a web environment, but not in a JavaScript environment, which this is, I'm pretty sure there is absolutely no difference. So we're calling it trim start, trim end, because we already have trim left, trim right, but that's not standard. And we have pad start and pad end, and it's basically to make you OK? Sure, yeah. So that's it. Scanning my notes, yes, this is now in everything except Edge, but it has landed in Chakra, so it's likely to be in the next version of Edge. Going up against that is import.meta. So import.meta is basically an object where you have metadata about the module that you're currently in, and I think the only thing that's on there right now is the URL property, and it's more or less equivalent to what document.currentscript.source used to be. The thing you can't use that is because if you have, so document.currentscript gives you the script tag of the, that's included in the document. Yeah, that's currently running. Now the problem is that an import or a JavaScript module can have an import. And so that doesn't have a script tag. So what is current script supposed to be? So it's giving you the URL of the current script, not script. Exactly, and that is super important if you think about if you want to do some path mangling for dynamic imports, or any kind of like module loader, or maybe just do relative path resolution, all these things. But it's not a DIR name thing that you have in Node. Exactly, that kind of thing. So it's a simple feature, but it's actually quite powerful and useful. All right. So it feels like we had two quite small, simple features there. It's a nice change. Yeah, some of them have been bigger. So it feels like we could probably make a decision reasonably quickly. But then I, so trim, start, trim, end doesn't feel that new because we already have it. And also I barely ever only trim on one side. I usually just trim. Is that a lifestyle choice? Yeah, I usually trim all the way. I am going to vote for probably the same reasons you import meta. It's more of a feature. It is a new thing. It's actually really painful once you run into the problem that it's not support in all browsers. And modules are, but import.meta is not. And it's sometimes really annoying. Sold. There we go, import.meta. Let's introduce the next feature, which is, this is a lot of letters. Reg X? Reg X, see, the font is terrible. It looks like Beg X. Beg X named capture groups. Yeah. I know these. I heard of them. I never actually looked at the syntax. But it is just this. I find Reg X to be right only. Yeah, it's executable line noise. Once you've read them, it's absolutely impossible to know what it was. And you go, one, two, three, what is that? I don't know. It makes no sense. I knew it a second ago, and now I don't. But being able to do this, name groups like this, and then so result.groups, you get the stuff out. Brilliant. Before that, you only had a numbered array, and it would be completely unclear. Exactly. And another place that would be unclear is when you're using string.replace. Oh, yeah. But you can use the group names there as well. So in this example, I'm changing it from being year month day to day month year. Because month day year is absolutely nonsensical and should not be used. Agreed. Yes, two people, European. There we go. We absolutely think that. So yeah. More on that next Wednesday. OK, we've been proven to be nontrustworthy when it comes to dating. OK, for a dating, it's not what I meant, but it's still true. Also, it's not really true. All right, going up against WigEx, name capture groups. Yep. Oh, I did that right. Is relative time format. We're going, well, I mean, the other thing wasn't strictly to do with dates, but we're still sticking with that. We're sticking in that territory. This is basically moments.js on the platform. Oh. Yeah, we got it. So you can basically create a relative time format instance that is localized. In this case, I'm using English because we've been mostly speaking English. It could have done German, but I didn't. OK. Also because I mostly copy pasted and was too lazy to actually generate a German one. Yep. Yeah, you just pass in. Here's a number. Here's the unit. It will give you that as a localized string. And there's obviously many more options if you want to have a full breakdown or just the highest option if you want to have four months, three days, and two hours ago. Or if you want to just have one of them, if you want to have it more numeric or spelled out as words, all these options are there. But basically, moments.js on the platform, it's a big dependency that you can hopefully ditch now. Well, I mean, I felt like it was going to be an easy one. But now I'm less sure. Things like moment.js are one of the things that leads to quite big bundle sizes because you end up with these large libraries in for. Especially if you don't screenshot them. They have all the localization still in there. Right. So having that just on the platform that feels like a huge win, the Regex thing is really useful for the readability of Regex. How often do you use Regex? I know Jason lives off of Regex. Yes. You mean our colleague, Jason. Jason Miller. Because it sounds like you were talking about the web standard. Oh, Jason. Jason lives off of Regex. It's like, you knew you should not parse your Jason with Regex. Turns out you can parse languages with Regex. I mean, Jason Miller, who does all kinds of minification and mini code, mini micro-library magic. And it's often because Regex. But I'm going to say the relative time thing. Yeah, I agree. It's one of the first bits of Intel that I am really, really happy with, I'd say. Yeah. Some of it I've found it to be. It's a well-designed API, it seems. Yes. I think there's still some things that could be even better. But you know what? I'm going to cut my losses here. It's a good idea. Yeah, it is something that you could legitimately replace moment with. Yeah. And look, we have a new thing to decide. So import met a relative time format. I'm going to go with relative time format. Oh, you're less sure. I'm trying to, subjectively, I've run more often into import.meta when writing stuff. And then into relative time format. That being said, pretty much a lot of apps need the relative time format. Many apps probably don't need import.meta. So in terms of the average developer, I'm going to type with you. RTF is the big hitter here. Yeah, the wins for the web by reducing those model sizes feels bigger. That is import.meta you could probably work around in a lot of cases. That's probably like a Babel plug-in or something, but does it? Very possibly, very possibly. Right, OK. Yeah, there you go. So we got relative time formats through to the next stage. But now I want to talk about Resize Observer. I've got a feeling this might go far in this contest. That's because I wrote the article on it. You did write the article on it. And it's a really good article as well. And it's such an amazing feature, I think. It's also quite simple. It is also quite simple, I would say. You give it an element, and it will tell you when it changes size. Some of the complexities in how it handles recursive changes, like it's only if it's sort of things inside that element that are changing. But most of the time, that is something you shouldn't be running into. But most of you just say, this is a resize event for elements rather than just the window. Absolutely. And that. You can build element queries, I think they're called, on top of this. All these things. That for me is the selling point. It's the element containing the query stuff that we can only be wanting for ages. So what do you bring into the table? OK, let's see who has to beat the Resize Observer. It's audio worklets. Oh, OK. So another worklet. The worklets are coming to the platform. Yes, the year of the worklets. So a little bit of catch up. Usually when you do audio, you create an audio context. And then you can create notes and connect them. So in this case, I'm creating a track note from an audio element. Then I'm creating a gain note, which allows me to adjust the gain, how much louder or quieter do I want this audio to become. And a paner, do I want it on the left speaker, the right speaker, somewhere in the middle. And then I connect these notes. Like it's like a little data flow model. It's very similar to what you do in an audio system where you're plugging things into each other, like different processes. The reason it's written this way is because all of this is running in a different thread. All this data mangling is happening in a different thread because audio has to be usually super low latency. Latency is one of the biggest factors when you do audio work. It's kind of declarative. But then people are like, well, I kind of want to manipulate the buffers myself. I want to get an audio buffer and do some math myself. And they were looking at, do we do events, but events are async by default. So it gets really hard with a real timeness. And now worklets are primitive that actually gives a solution because now you can do your own note. So this is the same code. And now there is a SIRM node. And the SIRM node is basically an audio workload node. And it takes a name. And then in a different file that we loaded up here, I can extend Audio Workup Poster, which is the basic node, and create my own one. And just in there, I'll have access to my inputs, which is an array of buffers. And I can define what is in the outputs. Right, because there are ways to do this sort of processing on the main thread. And I think it's now a deprecated API because you run into all of this. The asyncness and the, yeah, all the real timeness problems. And as latency for the thread hops in as well because audio is already a different thread, but now you have to jump back to main thread. It gets un-realty. And the worklets can just be migrated to different thread. Run on the same thread. You can still maintain the same declarative API and allow basically now to have DSP plugins on the web. All the effects that people do can now just be ported to an audio workload. That's nice. That is nice, actually. But, but, but, it's not resized observer though, is it? It's not, it's, audio is still, it's just in neat use case. Like in general, audio is actually kind of frowned upon on the web. And in apps in general, like things just start playing audio are bad. And there is audio apps, and those are great and really impressed with how far people get. But the audience who can use these, fairly small. Yeah, the little bits of audio stuff I've done on the web, I've really enjoyed. I had loads of fun with it. But it is, I've only done it like once or twice. Pick up quiz. The first time was one of them, right? Yeah, that actually might be the only one. And I did a little bit of extra stuff after that. But it was, it was, it was much like. And the best observer, it's just so good. I want that in every browser, like today, please. So I can, you know, do that sort of stuff. Have the, you know, container queries sort of thing. Stop just attaching. Because what we do right now is we attach a, resize this into the window. But that doesn't necessarily mean that, you know, that's not going to catch all of the cases. No, and then you call, get on the client rack and it becomes performance footgun. It's so hard to do right. Exactly, exactly. Right, so that goes through to the next stage. And now we are coming onto the final two features that we're going to talk about. I am going to talk about cache mode. On, on fetch. Yes, so this is part of request object. Because it's part of a request object, you always get this second parameter of fetch as well. Yeah. And what you're essentially doing is, is saying, how this request should go through the cache, if at all. So with reload, I'm saying, on the way out, ignore the cache. But on the way back, it can go into the cache. Oh, you have control over both pathers. Yes. Yes, pathers. No, no, you say pathers. Why not? It's Christmas. Treat yourself to some new words that you just made up. That's fine. So yeah, but this is a good, like, if you know, if you know there's a more up-to-date version, but it's, the user has a one in the cache that's, yeah. You have one in the cache mode. Yeah, that's just, what's in this? Yes, so you can bypass the cache one that you're talking about. So basically no store will then be on the way out. It can hit the cache, or probably not. No store behaves as if the cache doesn't exist. OK. So it bypasses the cache both ways. And no cache does every. Yeah, I'm reading this off a piece of paper. It will, even if there's an item that is fresh in the cache, it bypasses it, but it will still do a re-validate. Fresh in the cache. Fresh in the cache. Yeah, all right, cool. Forced cache means if there's something. So basically the stuff of undoing the cache busting thing where we put random query things, amongst other things. But with forced cache, it means that you could take the item in the cache, even if it's stale, according to, like, max age. And only if cached means. And also don't hit the network at all, right? Well, forced cache will still hit the network. Only if cached will not. Interesting. That's it. Lots of control. I like it. Only if cached has to be same origin. That is the feature. All right, going up against that is class fields. Oh. Yeah, so it's. I don't know a lot about this, so I'm. It's pretty simple. It's this. OK. So far, so one. So this doesn't include the private? No. But it will basically build on top of this. Once this is landed in Chrome, the private ones are the names that start with a hash. Hashtag. Yes, and those will only be accessible from within the function, from within the class, not from outside. This is pretty much just sugar, I guess, over getters and static getters. But the biggest beneficiary would, for example, be custom elements because you have the observed attributes field that always has to be a static getter function. And now it could just be a proper static attribute, and it just looks nice and it's easy to read what's going on. What about the instance ones? That's so it's that. Where did they happen in relation to the constructor? Do you know? I do know. I'm assuming it runs before the construct. I think that's after the super constructor, but before your own constructor. I think that's what TypeScript does. So that would make sense. Yeah, I think. Maybe. Who knows? Maybe. Right. OK. So that means away with the slides. Away with the slides. In with the brackets. This is it. So OK, one of the things that is pushing me towards the cache mode is that. It's actually capability, right? Well, it classifies a sugar. And it's also sugar that I write a lot of TypeScript these days. So I already have it. Yeah, yeah, I get it. I'm glad that it's going to JavaScript proper. And I'm more excited about the private instance properties. True, true. And the things of like, oh, well, they could be munched in code minification. Yeah, they're private. Yeah, they're private. So I'm more excited about that. So I'd be tempted to put cache mode through. I haven't run into the problem with cache mode very often, I have to say, where I wanted to have control about how the fetch is being handled. That being said, I think it's a very, because. The GitHub case is that you've updated your service worker. You want to get the freshest version of these things. And you're not in control of GitHub's headers. Yeah, I guess I mostly happened when I was inside my service worker. But yeah, I agree. What I would say is anything we pick now, I'm going to be voting resize observer in the next thing. Both of these lose against resize observer. So, go on, I'll let you pick. What do you want to put through? Let's put cache mode through, I agree. It's an actual capability that was missing while class fields, we had to work around three years. It's been fine. Yes, absolutely. It's nice. It's nice. Yes. So next bit. We already said it. I, yeah. Yeah, you agree? Yeah, I agree. We're going to rattle through these. Yeah, I just think resize observer, like the amount of stuff that solves is amazing. Yeah, so resize observer, the amount of stuff that you can do with it. Yeah, it's very versatile. It solves just such a longstanding problem. So now. Now we're getting into the interesting bits. Yeah, so what have we got here? Relative time format and resize observer. It's still resize observer for me. I agree. I agree. The amount of times that I've wanted resize observer in the past, it's loads. Yeah. It's loads. That's probably four. The physical unit is loads. It's loads, yeah. Yeah, loads times two, I would say. So let's put resize observer through to the next round and we'll see where that leaves us. Here we go. Now we're getting, that's a rough one. Now, yeah, I could have predicted this. The thing is, that the interesting thing is there's a commonality here that these both solve longstanding problems. Yeah. The tab discarding thing has existed since mobile and there's only now a solution to it. The resize observer, you could sort of equally say that this has been a problem since mobile as well because that one whole responsive thing really came into it to be. I'm going to be honest, I feel like lifecycle API is more work around the ball than resize observer. Yes, because you could put stuff in session storage. Onblur has been there for a long time, and you have IDB, you have local storage, you have means to persist state locally. Yes. So you could have done the right thing for a long, long time now, and this is just a cherry on top for you. While resize observer, you had to go to get bound inclined right and other awful things. I'm pressing the button because I absolutely agree with you. And I think I now remember, this is our second finalist, if I remember correctly. Oh. And I think I remember now who our other finalist is, and it means we have one CSS feature and one JavaScript feature in our finalist, which I think is amazing. That is exciting. Oh, you're right. Yes, I had forgotten about it. So it's kind of horrible that with the amount of work that's gone into these features and the diversity of the features that we now have to just declare one the best arbitrarily based on just some loose opinions while wearing a ridiculous jumper. We should, we feel like, is that going in your ear every time? Brilliant. Excellent. You want to start or should I? Well, it feels like we have to summarize scroll snap again, because. No, I think we should link back to the video. You just want another view. Yeah. Yeah, why not? Excellent. Watch the video if you don't know what scroll snap is about. So we've got the, I am going to show the demo again. Why not? It's a tab we've got here, I now remember. So this is scroll snap. This is. Isn't it great? It's not the best demo anyone's ever made. It might be a slightly underwhelming demo now that I think about it. If this loses, then whoever made this demo is going to feel pretty terrible. Yeah, so this is like having a sort of page paginated system within your scrolling. And you see it on the mobile UIs, right? Where you have, you swipe between individual panels and you just want them to lock into view. Yes. But you don't want to reinvent the wheel. Ideally, just use a scroller and just let the rest be handled by the operating system. Yeah. And it's nice since CSS, so it's super smooth. It's bringing something that is. Composited scrolling. Composited scrolling. It's a very native feeling feature. Yeah, because the browser. Even the browser might yield to the operating system. And this isn't even something that animation workload is going to solve, right? Because animation. It's used to. It doesn't anymore, yeah. OK. We used to want it to solve it, but actually, you actually can in a way, but it's quite tacky. You can still, if so. You would have to have a scroll container and then sort of fake it. If you don't like how scroll snap works, the animation workload is your escape hatch. OK. It's not as easy as it used to be, but honestly, scroll snap covers the 95%ile, I would say. All right. So I think that's where my argument lies. Both of these are. They solve long-standing problems. Currently powerful tools. Big problems have happened around for a long time. So resize observer, there's more types of UI that it solves a problem for. Yeah. Like, there are definitely cases where you scroll snap, like the two cases we've mentioned, having a carousel, which is the example we're looking at, and having those sort of like page UI things, which I have written that in JavaScript, it's incredibly hard, and it's still a bit janky and slow. Resize observer, once that's in all browsers, I feel like I'm going to have like five elements on the page or having their resize observer doing different things, applying class names. It's just really difficult. For me, my argument here is going to be the amount of code that scroll snap allows me to not write just outweighs what resize observer allows us. Well, that's a really compelling argument, actually. I like that. Because if you write scroll snap yourself in JavaScript, it's on the main thread. You have to do the physics things. It's going to be different from, for example, Android 2S. They feel different when they scroll, and you're either going to be in uncanny valley, or you have to have two implementations, aiming at both perfectly. It's a lot of code. It's very hard to get right. For me, it's scroll snap. But then the extensible web person within me is looking at two features here. One is a high-level feature that I can't really hook into, and the other is very much a primitive. But that being said, extensible web doesn't say them should not be high-level features. They should just be built in a, they should just be taken out of exposing low levels first and then see the popular patterns and then providing easier ways for those. And if we were talking about an animation workload where you can control scroll position in this way, that feels like the next step up. This is a big step up. That's the big asterisk about the animation workload story here, where you can't really control scroll position anymore. You're used to it, but that's been removed from the spec. But you can still achieve the same visual effect by skinnapping interview. So it is an escape hatch for this. Resize observer, you've got the window resize listener. You could infer stuff in other ways, I guess. It's difficult code. Worst comes to worst, you could have a RAF that's checking layout. I mean, usually, you know your breakpoints and your CSS breakpoints. You could actually avoid the get-bonding claimant if you do it right. It's all of hard work now. It's difficult to make modules like that, modules and components like that, but absolutely this. Is it settled? I think I agree. I think scroll snap. It's just how smoothly it does it. And although it's not something I'm going to be necessarily using on every page, as you say, it's a much bigger step in the right direction from how we were doing it today versus resize observer, which is still a massive step. So with that, our HTTP203 World Feature Championship 2018 thing, Renderer, is going to be scroll snap. Scroll snap? It's scroll snap. It is scroll snap. He wins the orange carrot. I was going to ask what they win, and I was thinking it was nothing, because our opinion is essentially meaningless other than just what we like. Are we going to send them the glittery carrot of the 2008 Glittery Carrot Award? I like it. We should do it next year. Until next year. Until next year. Well done, scroll snap. I'm back in for time, because this is saying internal server error. Let me try this again. I really want to go to the pub. Yes. Yes. OK. OK. It's working. We're back in.