Complex JS-heavy Web Apps, Avoiding the Slow (Chrome Dev Summit 2018)

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
[MUSIC PLAYING] MARIKO KOSAKA: Let's go back to February 1993 on www-talk mailing list. JAKE ARCHIBALD: This man, Marc Andreessen, he's the creator of Mosaic, one of the earliest web browsers. He wrote this. "I'd like to propose a new optional HTML tag, IMG." MARIKO KOSAKA: And this man replied, Sir Tim Berners-Lee, he wrote, "Or how about ENTITY, ICON6, SYSTEM, URL, &ICON6." [CHUCKLES] JAKE ARCHIBALD: And Marc replied, "Quick, Tim, look over there." And two months later, Mosaic shipped with the IMG tag. [LAUGHTER] MARIKO KOSAKA: It's really fair to say that IMG has been pretty popular on the web for the past 25 years, right? JAKE ARCHIBALD: Yes. MARIKO KOSAKA: In fact, according to HTTP Archive, the average web page loads 650 kilobytes of images. That means it's 52% of page content. JAKE ARCHIBALD: Yeah. And images are less blocking compared to things like CSS and scripts. But they can take bandwidth away from more important things. And of course, if the image is your primary content, loading it quickly is very important. MARIKO KOSAKA: Yeah. Unfortunately, websites throw those bytes away by using really inefficient codec like the one that comes with Photoshop. JAKE ARCHIBALD: And there are better options as well. So this is mozjpeg from Mozilla. But there is also WebP, which is probably supported by the majority of your visitors. As you can see, that WebP has beaten mozjpeg. But both of them have done really, really well compared to Photoshop's JPEG encoder. MARIKO KOSAKA: Yeah. But except you can't really see it. All you can see is some text and numbers. And these [? come-online ?] tools are great for batch processing and automating your build process and everything. But when you are trying to build a site and trying to choose something, it's really not a good experience to change the option. Because you can't really see the effects of the image while you are doing it. So a lot of innovative, small compressions are hidden behind these texts. JAKE ARCHIBALD: Yeah. And this winds me up every time I see a new image format come out. Because you get these really bold claims in a few sample images. And I'm left feeling, I don't believe you. I don't believe you unless I can try it in an easy way using my own images, not cherry-picked examples. So we thought, let's make image compression easy using the world's most accessible GUI, the web. MARIKO KOSAKA: Yeah. So that's what we did. I'm really excited for this slide. Because I get to do this announcements of the product thing. Well, here we go. Today, we are excited to announce new progressive web app, Squoosh. JAKE ARCHIBALD: Yay. OK, fair enough. MARIKO KOSAKA: Did you like that animation? JAKE ARCHIBALD: It was a beautiful animation. Well done. MARIKO KOSAKA: Thank you. JAKE ARCHIBALD: So now the most terrifying part of any presentation, we are going to give a live demo a go. And with the big web quiz failing earlier, luck isn't on our side. Actually, so with the big web quiz stuff, I had noticed some of the answers changing from underneath me as I was correcting them and editing them yesterday. And when that happened, I thought, well, what could have happened here? Could Surma have coded it wrong? Or am I so jet lagged I don't really know what's going on? And I went for that one. I just didn't believe Surma could have done it wrong. OK, are you ready to go? MARIKO KOSAKA: Yeah. JAKE ARCHIBALD: OK. It's going to be fine. So this is Squoosh. This is squoosh.app. So all we need now is an image to compress. And there are some example ones along the bottom here. But let's pick a real-world example. I'm going to go to the Google I/O website. This is the one from this year. Now that header image there is a massive 1.7 megabytes. And that is a large portion of the page weight here. So I'm going to save that image, and we're going to drag it into Squoosh. With Squoosh, it supports the file picker. It supports copy and paste. In this case, we're just going to use drag and drop. There we go. So on the left-hand side here, we've got the original 1.7 megabyte image. And on the right-hand side, we've got mozjpeg. As you can see straight away, mozjpeg has taken it from 1.7 megabytes to 500k. That's huge. And to my eyes, I can't really see a difference between the two. If we zoom right in to the folks on the screen here, we can start to see the difference. If we drag from side to side-- there you go-- slight difference. But it's not going to be displayed like this on the website. It's displayed zoomed out, and you can't see a difference. All this is a-- this kind of interface, this works with touch events and stuff as well. You can touch the screen and do it. So it works great on a Chromebook. I was paid to say that, but it is, nonetheless, true. [LAUGHTER] But because it's displayed for these-- it's optimized for high-resolution screens, this big image, well, we can tweak the settings based on that. So we're going to bring the quality down to 44, obviously, one that we rehearsed. And that's just because it's going to be resize down like that. And we can't really go lower than 44, because it starts picking up banding issues, especially around the sky bit there. But we've really dropped the file size. It's almost another 200k gone. Now, lossy formats, they work by removing data that humans aren't very good at seeing anyway. So for instance, we're more sensitive to changes in brightness than changes in color. So these lossy formats, they'll store color data at a lower resolution than the brightness data. But again, since this is aimed at high-density screens, we can go even lower. So we're going to dive into these advanced settings here. We tried to expose everything that these codecs can do. So there are some scary things here like trellis multipass. What does that do? Well, I have absolutely no idea. But I can check this. I can see the impact of it. It's really cheap for me to try it. I'm not breaking anything. MARIKO KOSAKA: Yeah. The great thing about having UI is that you can see it right here, right? And you can figure that out, like, toggle it. JAKE ARCHIBALD: Yeah. You can start to learn what they do. MARIKO KOSAKA: And if it's [? a come-online ?] tool, you can't really see until you're finished, right? JAKE ARCHIBALD: Absolutely, and one of the options we are going to look at is the auto-subsample chroma. This is the thing that's changing the resolution of the color data. By default, it halves it, but we're going to quarter it. And that's another 20k gone as well. So we've now reduced it by 83% of the original that is on the I/O website. If we zoom right in, it's looking like a bit of a mess. You can really see the difference there. But again, zoomed out, which is how it's displayed on the site, it's really different. It's really difficult to tell the difference. Mozilla have done an amazing job at getting the most out of an old image format like JPEG. But let's compare it to WebP. So on the left-hand side, we're going to switch to WebP. And we'll drop the quality down to 20. WebP is a much more modern image format. It's based on the VP8 video codec. It's supported in Chrome. It's coming to Edge 18, Firefox 65. But straight off now, we'll-- we're going to be around about-- MARIKO KOSAKA: Sorry. Sorry. [INAUDIBLE] Yes. JAKE ARCHIBALD: There we go-- about another 100k less than the JPEG. That's 1/10 of the size of the original. If we zoom into those people on the screen again, we can start to see the difference between the two codecs. JPEG goes for a very blocky look, whereas WebP loses details through smoothing. In fact, the WebP, at this size, kind of looks in some ways worse than the JPEG. I don't know. It's subjective. But that's also because we've been able to drop the quality of the WebP a lot more because it doesn't suffer from those banding issues that we get with JPEG. And again zoomed out, there's barely a difference. So now we've done that, we can download the two images and hopefully send them to the people who on the I/O site because that's 1.4 megabytes saved for every visitor that supports WebP, 1.3 megabytes saved for people who like to support JPEG. So that's lossy compression. But we support lossless compression as well. The Squoosh logo here, this is an SVG. Vector formats are great because they're maximum resolution on any device density, any size. But it's worth looking at how this comes out in a nonvector format. This looks a bit broken. This is because we're using JPEG, which doesn't support transparency. So we'll change to another format. We'll change to OptiPNG, which is an optimized PNG format. Once we do that, it's bigger. It's over twice the size, which is not great. But we can optimize for these kind of codecs. So we're going to reduce the palette. We're going to bring it down to, I don't know, 70 colors. And we can turn off differing because we're happy with just a flat color there. And once we do that, we are now smaller with the PNG versus the SVG. It's just a few K. If we zoom right in, we can start to see, I don't know, very subtle differences. But zoomed out, it's not a big deal at all. But let's throw this at WebP's lossless mode. So we're going to copy the settings from one site to the other so we keep the reduced palette data, switch to WebP, and put it in lossless mode. So WebP's lossless codec, it's kind of like a completely different codec. They should have probably called it something different because it's much more similar to PNG. But now you can see we've cut even more off the file size. We're 34% smaller than what we were with the PNG, with the SVG even. But this is yet another cherry-picked demo. Like, we have scripted this to look good on stage, right? What I am saying to you right now is literally written on this screen, including that, and that, and that, and this. MARIKO KOSAKA: Excuse me. [LAUGHTER] Yeah, well, but all we are saying is that, just don't trust our demo. Just go to our app, throw your own image, and try it out. And see how many bytes you can shave off the image by keeping acceptable quality. So we can go back to the slides now. JAKE ARCHIBALD: OK. So that's the good parts. But Squoosh is still in beta. It isn't finished yet. There are-- there's a few rough edges. And we do want to be honest about that. For instance, right now, if you open it in Firefox, you get this. We're a little bit behind on our browser support. [LAUGHTER] Oh, come on. Look, we've run out of time. We are hoping to fix this. MARIKO KOSAKA: Yeah. We had the big web quiz to build and everything. JAKE ARCHIBALD: We had other things to build. We are joking of course. MARIKO KOSAKA: Joking. JAKE ARCHIBALD: Come on, right? MARIKO KOSAKA: Yeah. As well as being a useful tool-- which we hope that you find it useful too-- we wanted to practice what we preach. So we wanted to make the Squoosh to be a great PWA. So Squoosh works in latest version of all modern browsers. [APPLAUSE] Well, this is kind of-- JAKE ARCHIBALD: Only Googlers can get a round of applause for just making things work with other browsers. MARIKO KOSAKA: Yes. This is kind of sad that we got applause for this. JAKE ARCHIBALD: Yes. In fact, what you're seeing here is Firefox 63 opening a WebP of my stupid cats. And this is in Firefox 63, which does not support WebP. WebP support doesn't land until Firefox 65. MARIKO KOSAKA: Yeah. But we didn't want the key features to be missing. So we needed to make sure the Squoosh could lead and create images in all modern browsers using those codecs, which brings onto-- let's talk about how we built Squoosh. JAKE ARCHIBALD: Yeah, and this is an idea I had around about five years ago. It's something I'd been wanting to build. And I tried to build it five years ago, but browsers weren't quite smart enough. But more importantly, I wasn't quite smart enough. So Squoosh is a real team effort with contributions from all of these talented engineers and Paul Kinlin. MARIKO KOSAKA: The key thing that made-- [LAUGHTER] Are you glad that joke landed really well? JAKE ARCHIBALD: Thank you. MARIKO KOSAKA: The key thing that made Squoosh possible is WebAssembly, which is supported in all modern browsers for over a year now. I know we have WebAssembly sessions later in this conference. But as a little primer, Wasm, or WebAssembly, is a compile target for the web. So you have your code written in C, Rascal, or whatever choice. You would usually compile it to run it on different OS as the app. But using WebAssembly, the technology, you can compile the same code and run it in browser. So for Squoosh, the mozjpeg, the web WebP, the OptiPNG, all of those codecs are written in C. So we used a tool called Emscripten to compile the C code into a WebAssembly so that we can run it in browser. JAKE ARCHIBALD: Yeah. And this was really, really essential for the project because browsers do actually ship with imaging coders like JPEG and PNG, which you can access via the Canvas API like this. But they suck. They are really, really bad. We have made them available in Squoosh. So you can use them if you want. They are actually quite fast. That's the one thing they've got going for them. We thought, why not? But you only get this one quality option. And ugh, they're just rubbish. This is Chrome's JPEG encoder on the left compared to mozjpeg. And it's ugh, the Chrome version is just a lot rougher. It's blah. It's horrible. It's actually way worse in Firefox. MARIKO KOSAKA: Firefox. JAKE ARCHIBALD: The JPEG encoder in Mozilla's browser is terrible compared to Mozilla's JPEG encoder. [LAUGHTER] MARIKO KOSAKA: Yeah. We see the same thing for PNG too. So that Squoosh logo that we looked at in the demo, if you use a browser's native compressor, then those are the numbers you get. The Firefox are significantly better than other browsers. But it's still not good compared to OptiPNG, which Squoosh uses. And this is for exactly the same image, pixel-by-pixel, just compression, different numbers. JAKE ARCHIBALD: Exactly. And Wasm let's us bypass the browser's encoders and use much better ones. It also let us bring in the WebP decoder to use in browsers that don't have native WebP support. Now, I know almost nothing about C. So that part of the project was really down to this man. So please, welcome to the stage-- so good, we named him once-- it's Surma. [MUSIC PLAYING] [APPLAUSE] MARIKO KOSAKA: So you made most of the WebAssembly stuff work. SURMA: Yeah. [LAUGHTER] JAKE ARCHIBALD: How was it? SURMA: It was good. JAKE ARCHIBALD: Cool. SURMA: Cool. JAKE ARCHIBALD: Surma, ladies and gentlemen. [MUSIC PLAYING] [APPLAUSE] MARIKO KOSAKA: Yeah. Well, thankfully Surma wrote an article about it. So we have some things to share. JAKE ARCHIBALD: Yeah. Compiling a codec to Wasm, that involved writing a little bit of C++, which included the codec and some of the Emscripten stuff. And then we wrote a function. This is the function we want to expose to JavaScript. It takes our image data, takes it as a string because that's how Emscripten represents binary data in C++. So on the JavaScript side, we're passing in a Uint8array. And it ends up in C++ as a string. And we also have our other arguments, width and height, and the codec settings. In this example, I'm just using quality. And then we call out to the actual encoder under the hood, passing in all the settings, getting the output, and then we return it. And this vowel and type memory view stuff, this is annotation to tell Emscripten to treat the return value as a Uint8array back in JavaScript land. And then all we needed to do is tell Emscripten which methods to expose. That's it. MARIKO KOSAKA: I'm a web developer. You completely lost me. Do you get any of this? JAKE ARCHIBALD: No, I don't understand it either. But I copied the patterns from Surma's article. And hey, it just works. It's great. MARIKO KOSAKA: Great. JAKE ARCHIBALD: I was able to take those patterns and use them for different kinds of C projects as well, like text compressions and stuff. It's-- yeah, it's pretty good, pretty good. MARIKO KOSAKA: Yeah. So compiling that code with Emscripten gives a JavaScript file in Wasm binary. So now you can include that script onto your page, which also loads that Wasm binary. And once all of the script is ready, you can just call that encoding function as if you're calling JavaScript. JAKE ARCHIBALD: Yeah. Using Emscripten, it feels a little bit rough and ready. But the docs are really good. And Surma's article is good enough to get you started. MARIKO KOSAKA: Yeah. But in this case, we are dealing with a large C project here. And those are really CPU intensive. So that brings us to performance, which we were kind of worried about in the beginning of the project because we knew that's going to be a thing that we need to take care. JAKE ARCHIBALD: Yeah. We're halfway through the talk, so we're actually finally starting to get to the point. MARIKO KOSAKA: Yeah. So we used PREACT to orchestrate the DOM and webpack to bundle it all together. JAKE ARCHIBALD: Yeah. We used PREACT because it does what it does in 3k, which is kind of amazing. We also had Jason on the project-- that's probably-- MARIKO KOSAKA: That's true. Clear it off the [INAUDIBLE]. JAKE ARCHIBALD: --another reason. We wouldn't want to upset him. And we used webpack because there isn't really anything else that does what webpack does, certainly, not in the way we wanted it done. We wanted a lot of control over it. And it was really only webpack. MARIKO KOSAKA: Yeah. So as a result, our app is 400 Kilobyte gzipped, all in all, everything. But this is well below the median from HTTP Archive, which is 1.5 megabytes. So we're quite happy about that. JAKE ARCHIBALD: Yeah. We're winning. We're winning. We're happy with that. So the vast majority of that size is the codecs and the processes, like, the stuff we brought in from C land. And that's-- yeah-- 300 kilobytes of that stuff. And I'm pretty sure there's some waste and duplication here. But like I said, Emscripten's a little bit rough and ready. And cosharing between Wasm modules, it doesn't seem all that easy right now. It's something we'll look into. But we were able to limit that damage by lazy-loading these using workers. MARIKO KOSAKA: Yeah. As we've already seen, compressor is CPU intensive. So depending on settings, encoding can take 30 seconds to sometimes minutes. And when that thing is happening and occupying CPU, we don't want that UI to be frozen. We want users to be pinch zooming, and moving around, and testing, and possibly changing the options too. So-- JAKE ARCHIBALD: Yeah. Workers give us this lazy loading stuff for free, which is great. But the main benefit is concurrency. We create up to two workers. And both of those are just going to be pointing at the same script. That's one for the left-hand side of the image and one for the right-hand side of the image. This means the left-hand side can be encoding a JPEG. And the right-hand side can be optimizing PNG. And all the while, the main thread stays responsive. And that was really all the concurrency that we needed. MARIKO KOSAKA: Yeah. But it came with another benefit too. So the left-hand side-- let's say [INAUDIBLE],, left-hand side worker is compressing an image, right? But what if a user changes the setting? The current job is out of date. We need to update it. But those compression encoders are written in a synchronous way. So there is no abort API. There is no way to kill it. However, we put it into worker. So in this case, we just terminate the worker, and then click new workers, put the new job in, and then start it back up again. JAKE ARCHIBALD: Yeah. And the implementation for this is pretty simple. So it's just like this. MARIKO KOSAKA: Ooh. JAKE ARCHIBALD: Oh. Oh, go on, you click. This is the problem. We've got two slide clickers. And we needed to rehearse who was doing the changing for each slide. So what you saw there was us messing it up. [LAUGHTER] Implementation is roughly like this-- if busy, terminate, and restart. But also, we only spin up one of these workers when we need it, like, just in time. So if you're doing something kind of like what we were doing in the demo-- we had the original image on one side, JPEG on the other. We only spin up one worker because we're only having one side doing compression at the time. And also, if one of those workers is idle for 10 seconds, we kill it as well. And that is really just to be kind to the user's device to bring the memory footprint down. MARIKO KOSAKA: Yeah. That worker is almost empty when it started. Heavy stuff is imported when it's needed. This keeps the worker startup time down. And also, you don't really need to download and parse and wait for the OptiPNG and mozjpeg stuff if user is just encoding WebP. JAKE ARCHIBALD: Yeah. And using a wait import like this, this is part of the platform. It's supported behind a flag in Chrome. But it isn't supported and stable or in other browsers. Thankfully, it's something that webpack can just handle. It polyfills it, and it just works. Now, the final piece of this puzzle is how we actually talk to the workers. MARIKO KOSAKA: Yeah. So request and response communication with workers-- eh, a little tricky. So the way worker works is that you send the worker some job. And at some point, they come back with the results. But you need to associate those requests and response. So in this code example, we just give a unique ID. And when worker is done with that job, then it gives back the ID. But you have to write your own logic for this. And it's like, eh, eh, eh. JAKE ARCHIBALD: It's rubbish. I really don't like it. It's one of the things that puts me off putting stuff into the-- of a thread. It goes ah, I'm going to have to do the post method thing. I don't like it. MARIKO KOSAKA: Yeah. That's a layer to worry about when you're writing application. JAKE ARCHIBALD: But again, to the rescue, it's Surma. [LAUGHTER] He built Comlink, a little library that you can use, you can get from mPm to use it. It's just like this. You create a worker as you usually would. And then you tell Comlink all of the things that you want to expose. These can be classes, values. But we were just using functions. And then over in your page, you just hook the Comlink up to the worker. And now you can call those functions just as if they're part of your page. Comlink takes care of all of the bookkeeping, the post message stuff, all of that mess. MARIKO KOSAKA: So once we've split up that codecs, our app came down to 35 kilobyte. Yeah. But I want to make sure that a user will still have to download those 300 kilobytes if they want to use all of the codecs. But they don't need to load those upfront. But 35 kilobytes, it still contains the pinch zoom logic, the options panel, the fancy slider, then this thing, and that thing, this thing, this thing, ooh, that thing too. And what these have in common is that it's not here, our first page. JAKE ARCHIBALD: Yeah. Imagine going to a restaurant and asking to see the menu. And 10 minutes later, you still haven't been given it. So you're going to ask, excuse me, where's the menu? And they say, oh, well, we're busy preparing every single dish we do. And then we'll give you the menu, so when you pick something-- bam-- we will give you that straight away. It's ready. [LAUGHTER] MARIKO KOSAKA: Yeah. You laugh but much of the web is built this way, especially JavaScript-heavy apps. JAKE ARCHIBALD: Yeah. Because you might look at the menu and decide, oh, I don't want any of this stuff. Or you might want something simple. You're certainly unlikely to want everything. So why should getting the menu and making a choice be blocked on them preparing all of their most complex, time-consuming dishes? MARIKO KOSAKA: Yeah. Same for JavaScript apps. They prepare everything up front before doing anything. So the user really shouldn't have to wait for all of these things to download, parse, and execute. They just need to get to this page. JAKE ARCHIBALD: And like most web apps-- like most apps-- Squoosh has a limited set of first interactions. [INAUDIBLE] it's dropping an image onto the page, selecting one file by the file picker, or selecting one of the demo images. So we split all of that out. This is roughly how things looked at the start. We had our intro. And we had our compression UI. If no file had been selected, we show the intro. Otherwise, we send that file to the compression UI and display that. We changed this so the whole compression API part, that was loaded asynchronously. And the tool chain actually made that a lot easier than I expected. MARIKO KOSAKA: Yeah. So first up, we removed the URL import and instead, dynamically imported that in the constructor and set that as a state. So dynamic imports are supported natively in Chrome and Safari. But using webpack provides similar functionality to all of the browsers. JAKE ARCHIBALD: Yeah. So the compression UI is going to start downloading as soon as the intro loads. But there is a small chance that the user is going to be able to select a file before it's ready. So in which case, we just show a spinner. Very unlikely that the user is going to see that, but we put that in just in case. MARIKO KOSAKA: Yeah. So remember with codec, speed it up. We chopped that 300 kilobytes off. But with the code splitting, we made that into 15 kilobytes. And this is despite our app being JavaScript-driven, using frameworks. And 15 kilobyte gzipped is even with empty cache on the user's device. JAKE ARCHIBALD: Exactly. And that means on a slow 3G connection, the user gets the first interaction in 3.3 seconds. And that's a slow connection on a slow phone, but it's not the worst conditions. Even on 2G, we are still interactive in less than 5 seconds. Now, I don't think many people in this room spend a lot of time on 2G. I know I don't. But this kind of performance means the app is really usable even in emerging markets. And this is why I'm a huge fan of these microframeworks, like PREACT, but also Lit-html, hyperHTML, Svelte. We couldn't have actually hit these numbers with React because that's 30, 40 kilobytes out the door. We couldn't do it with Vue, because that's 20 kilobytes. Angular is 60. Ember is bigger still. But let's not get carried away. 15 kilobytes, 8 of which is JavaScript, is actually a lot of JavaScript for these couple of interactions. MARIKO KOSAKA: Yeah. So for instance, let's look at how we might build this user interface with just Vanilla JavaScript. So here's a minimal implementation of drag and drop, just a few lines. And then add that to that drag and drop is the self-selecting of file code. That's not that much. And then this is for selecting one of the demos, clicking, and loading the image. So these, all of that code, minified and gzipped, it's only 550 bytes. JAKE ARCHIBALD: Or 350 bytes. MARIKO KOSAKA: Ooh. JAKE ARCHIBALD: But whatever. I'll go with the number on the screen. MARIKO KOSAKA: Can't see the number. Yes, 350 bytes. JAKE ARCHIBALD: And that's why I get really, really grumpy when I see sites like with this 600k or more JavaScript bundle. And that's for first interaction. I have friends who build native apps. And when they talk about their two megabyte Android Instant Apps, I love being able to go, instant, 2 megabytes. Great. 15k. [LAUGHTER] But then they-- MARIKO KOSAKA: With your smug face on. JAKE ARCHIBALD: Yeah. [CHUCKLE] I think it's called a shit-eating grin. Anyway. [LAUGHTER] But then they can point to large parts of the web that have thrown this advantage away. Parts of the website have taken on the worst of native but none of the benefits. MARIKO KOSAKA: Yeah. So if you take anything, anything out of this talk, please, please, please, study your website or your web apps, and find out what the first interaction is. And shift the reasonable amount of code for that first interaction. Now, reasonable amount of code. How do we find out? We have a lot of tools. Yeah. Just experiment, and find out what is reasonable to you. JAKE ARCHIBALD: So you also need to keep an eye on the bundles between builds. And with webpack-- and right now that, unfortunately, means going and looking at minified code. Because that's where it does things like tree-shaking and dead-code removal. It's part of the minification process. MARIKO KOSAKA: Yeah. We ran into a few bugs because of that, right? JAKE ARCHIBALD: Yeah. We were still not quite sure if it was a bug in webpack or if it was our expectations were different to what webpack was doing. But it was when we dived into the minified bundle, that's when we found that stuff out. Alternatives, like rollup are much better here. They will show you the dead-code removal during development. So it's easier to see when something's not going as you expect. But rollup doesn't have the kind of holistic asset graph that we really needed for this project. Anyway, my point is, there are huge gains to be had by keeping an eye on this stuff. MARIKO KOSAKA: Yeah. So like we said, we used PREACT to orchestrate the DOM But we also used Web Components When we were building this system, we were talking to a lot of developers of, yeah, we are building this cool app. And we were using PREACT. And you're going to be-- got Web Components. And they were kind of surprised. Because they were asking questions like, well, wait. Isn't Web Components an alternative to frameworks? JAKE ARCHIBALD: Yeah, but they're not. I don't know why you would think that. Well, actually, I don't know why you would think that, and I think it's our fault. Well, I think it's Google's fault. I think our messaging suggested that Web Components are the same thing as Polymer. And Polymer is an alternative to the frameworks. But web-components, they're not the same thing. Web Components are the lower level primitive that Polymer uses. MARIKO KOSAKA: Yeah. We did use Polymer's custom element polyfill for Edge. But for other browsers, we just shipped the Vanilla web components JAKE ARCHIBALD: Yeah. We used custom elements for some of our leaf components that contained the minimal amount of state. For instance, this is the pinch-zoom element. Just put stuff inside it; now you can pinch-zoom it. And it has an API. We also did this with our side-by-side slidy thing, comparison. MARIKO KOSAKA: We call it two-up. JAKE ARCHIBALD: We call it a two-up, yeah, because we didn't know what else to call it. A fancy range input, drop target-- we made components for all these bits and pieces. MARIKO KOSAKA: Yeah. So we could have done all of this in PREACT component because we were using PREACT. But using Web Components, we can take that and put it into some other project using different frameworks or just use it as is in the project that you don't really need framework. JAKE ARCHIBALD: Yeah. And if you're open sourcing client, Web Components are the best way to share things like this, so we did. We have released a few of our Web Components a separate project. So we'll make more available as we extract them from the main app. We were hoping to release more. But uh, we've run out of Time-- Whatever. We used PREACT, but these things, they can be used in Vue, Svelte, Angular, React, whatever. MARIKO KOSAKA: Yeah. Most frameworks are fine with Web Component. But some have a few rough edges. So if you are curious, check out custom-elements-everywhere.com to see how custom elements work with whatever the framework you are using. JAKE ARCHIBALD: We also released libraries for some of the other things we built, like a pointer event helper, thing, and a webpack plugin for dealing with asset inlining and optimization. So it has been-- well, we're vastly running out of time-- 20-odd minutes, and I haven't yet mentioned service workers. MARIKO KOSAKA: A new record at the very end, very end. JAKE ARCHIBALD: New personal record. Yes, the site does work offline. Our service worker approach isn't particularly novel. We catch the things. We serve the things. That means it works offline. And we also let the user know when there's an update available. MARIKO KOSAKA: Yeah. But there's one unique thing about this Squoosh. That is, when users first visit the site, we cache all of it in the next interaction. But we do not cache any of the codec, the 300 kilobyte bit, until the user access will drop the image and then get to this view. JAKE ARCHIBALD: Yeah. And this was just being kind to the user's bandwidth. When the user just visits the site, it feels rude to download the whole 400k app. So we wait for some signal from the user that they're actually interested. And that's when we cache the chunkier parts. MARIKO KOSAKA: Yeah. And this is what we love about the web, right? Write it once, build it, and then put it into phone, tablet, desktop, with the fraction of the size. JAKE ARCHIBALD: Of the equivalent native app, yeah. And those native apps are only targeting one operating system. Whereas, we can hit loads of them. And to share it, just copy the URL-- MARIKO KOSAKA: That's the best part. JAKE ARCHIBALD: --and send it to someone. MARIKO KOSAKA: That's the best part of the web. JAKE ARCHIBALD: Love it. MARIKO KOSAKA: So if you want to dig into the code, it's all on GitHub. There are lots of things we want to do. There are bugs to fix, codecs we want to include. And if you're interested, please come join us to build this up. We really want this tool to be really useful to everyone. JAKE ARCHIBALD: Yes, absolutely. So thanks for listening. Now go Squoosh some images. MARIKO KOSAKA: Please never say that again. [APPLAUSE] Thank you very much. JAKE ARCHIBALD: I promise nothing. Thank you very much. [MUSIC PLAYING]
Info
Channel: Google Chrome Developers
Views: 35,103
Rating: 4.9386973 out of 5
Keywords: type: Conference Talk (Full production);, pr_pr: Chrome, purpose: Educate
Id: ipNW6lJHVEs
Channel Id: undefined
Length: 31min 54sec (1914 seconds)
Published: Mon Nov 12 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.