WebWorkers: Code Session - Supercharged

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
SURMA: It is Thursday. It is 2:30 PM, UTC. It is time for Supercharged. Hi, I'm Surma. MARIKO: Hi, I'm Mariko. SURMA: And we are going to do some WebWorkers. Let's go. [THEME MUSIC] SURMA: So WebWorkers-- usually on Supercharged, we do more like leading-edge technology, things that only work in Chrome Canary with web platforms flag enabled. But today, with WebWorkers, we're actually using something that has been around for years. MARIKO: Yeah. SURMA: And many browsers-- I think even Explorer, multiple versions, have support for WebWorkers. MARIKO: Pretty much. SURMA: So you can follow along in whatever browser you are today. And that's new. So Mariko, welcome. I'm very happy to have you here. MARIKO: Thank you. SURMA: Before we dive into code, I think we should make sure that everybody-- I'm not sure everybody knows what a WebWorker really is. MARIKO: Yes. SURMA: And even I'm not sure if I know the right definition of it. Can you maybe bring us all up to speed? MARIKO: Oh, OK. Cool. Sure. Should I do the picture? SURMA: If you want to. MARIKO: So how would you describe WebWorker, if somebody asked you online, what is WebWorker? SURMA: I would basically say it's a actual second thread for JavaScript, like proper parallelism in JavaScript. And then you have some very simple ways to communicate with your original main thread, as it's called. MARIKO: Right. Right. So-- whoops. Yep, this one. I had that explanation given to me. And I was like, what do you mean thread? JavaScript is a single thread. SURMA: Exactly. And that's what already confuses people, I think. MARIKO: Yeah. Yeah. So I discovered WebWorker when I was trying to make the very similar app that we're going to try to make today. And I wanted to make it performant, and I discovered WebWorker. And I was like, what does that even mean? It was really confusing. So I pictured it for you. I drew a picture. SURMA: You are known on the Internet for drawing explanations of things. So I'm very happy that Supercharged gets to enjoy these drawings of yours as well. MARIKO: So imagine that your browser is a planet-- Earth, something. You might know when the garbage collection is, you know, the garbage day schedule with garbage collection. You know all the elements on the planet, because HTML elements up there. And the WebWorker, you can think of it something like a International Space Station. It's something that you create from the browser, the planet browser. You launch it-- SURMA: I like planet browser. MARIKO: --out of the world. It's outside of the planet browser. But then, from planet browser, you send the data out to do all kinds of scientific exploration that happens. So they can do a lot of tasks. But because it is outside of the planet browser, they cannot touch the elements on the thing. So in the WebWorker-- SURMA: That makes a lot of sense. MARIKO: --it does not have access to window object. It does not have access to document object. Basically, you cannot do anything that touches what's on the screen, but you can do a lot of JavaScript. SURMA: True. And that's what we're going to use today. MARIKO: Yes. SURMA: And so this was the first explanation, probably of many to come, because we are introducing some new concepts. But if you have any questions, you people watching us live in the chat, ask them. Because I'll be monitoring the chat, or the hashtag Supercharged on Twitter, or my mentions on Twitter. And I'll try to forward them to Mariko, because she's the expert on all of these things. And she will, hopefully, answer your questions, even if they are about coconuts, Jake. Thank you, for making sure that people believe us that this is actually live. So where should we start? MARIKO: What? Coconut? I'm sorry? SURMA: Jake said in the chat that I should say something about coconuts to prove that this is live. MARIKO: Oh yeah. By the way, for somebody who doesn't know Jake, he's our colleague who is literally sitting at the wall behind us. SURMA: He did the livestream with me two months ago, three months ago, about ServiceWorker. Who would have thought? MARIKO: OK. So as I explained, in order to utilize WebWorker, you kind of have to have a lot of JavaScript to do-- like something that is not changing the visual or making a DOM element. It's a lot of JavaScript. So I have a plan for today that I kind of thought of. So what if we-- so I know Matt did last Supercharged an image processing thing and WebGL. SURMA: Yeah, we did WebGL. MARIKO: But I don't know how to speak WebGL, but I know how to do 2D Canvas. So what if we do a lot of our image processing in 2D Canvas? And you do basically image filters, do a lot of using the bits thing. And then that involves a lot of-- [LAUGHS] SURMA: The bits thing. MARIKO: That thing, yeah. That, the thing, the pixel thing that you-- SURMA: If you don't know what we're talking about, I recommend you watch the previous live stream, after we're done. Like, watch us first, then watch the other one. Because we have many live streams on this channel, which you also should subscribe to. MARIKO: So here's the very simple diagram of what's in my head. SURMA: OK, this is what we're going to build. MARIKO: Yeah. So I'm going to have an Input button that opens up the file dialog. So it's like, I want to edit this image, right? That is loaded into the screen. And when that gets loaded into the screen, it does something. Let's say, it's kind of like an Instagram filter, right? SURMA: Yeah. MARIKO: You know, let's make it like a black and white, or like, you know, warm, cool-- SURMA: Any kind of image processing, MARIKO: Yeah. SURMA: [INAUDIBLE] image processing. MARIKO: And then display it on the screen. SURMA: OK. MARIKO: Because I suspect that doing those filter things involves a lot of computation. SURMA: Yeah. MARIKO: And maybe it's a good example to put it into WebWorkers. So let's get into first making that application, before even we talk about WebWorker. SURMA: Yeah, let's go for it. MARIKO: All right. So I have index.html. And I start a simple server that is serving that file. SURMA: OK, cool. MARIKO: Let's just see I'm not lying. Let's say, hi. And then, if I reload it, it just shows up as a hi. So that's working. So for now, let's just say title. SURMA: And we're done. MARIKO: [LAUGHS] SURMA: See you next time. MARIKO: Supercharged. SURMA: Oh, you're even on brand. That's so good. MARIKO: Emoji. And then-- SURMA: No, it's one word. MARIKO: Thank you, very much for reminding me. So as I mentioned, I need to have Input button, so input. SURMA: We have the first question for you on the chat. What do you use to draw your diagrams? MARIKO: I use iPad. SURMA: There you go. MARIKO: And Apple Pencil. SURMA: OK. MARIKO: Do they care about the app that I use? There's a bunch of apps that I can recommend later if you want to do it. Yeah. SURMA: Speaking of, follow Mariko on Twitter as well. MARIKO: Yep. SURMA: If you want to have more drawings, that's the place to go. We have the link in the description. MARIKO: Cool. So when you have an input for element, you can specify what kind of input it is. And in this case, we're going to use file. And then, when you're doing the file input, you can also specify what kind of file this input accepts. So, accept. And this time, we want to only deal with image. Like, you don't want a user to accidentally load. SURMA: Like a JSON file or HTML. MARIKO: JSON file or something. It's just like [INAUDIBLE] everywhere. Let's do that. So image. And then let's say star, so that in PNG, JPEG, bitmap, anything, it will accept it. And just have an input. SURMA: Cool. Also it uses the MIME type, not the file extension. MARIKO: Right. SURMA: OK. MARIKO: ID, ah, input. SURMA: Because people, someone brought up that we are missing some meta tags in the header. This is a good opportunity to mention this is not production ready code. This is only supposed to work on Mariko's screen just now. Its more about the concepts that she's going to use and explain to you. You can then, later on, go to our repository on GitHub, grab the code, and add all the meta headers that you want. PR is welcome. MARIKO: That's good-- PR for PR. SURMA: Exactly. MARIKO: So choose file or something, right? So if I had that, I should have for input. And then let's leave out this file. And then I have file input. So right now, its very small. So make it bigger. SURMA: Yeah. MARIKO: If I click it, the file dialogue opens up. And then I can select the image and then open it. SURMA: And then nothing happens. MARIKO: But right now, nothing happens. SURMA: Why would it? You haven't written anything. MARIKO: Nothing written yet. So do you have this thing where you start doing this, and then unless you style it somewhat nicely, you can't really move, because your motivation is not-- SURMA: No. I am the exact other way around. I hate making my things pretty. I just want to get the core functionality done and then hand it off to someone else. MARIKO: So as you can see, I'm a visual person. SURMA: You don't say, the person who draws on Twitter? MARIKO: I mean I'm not, no way, like a designer or anything. But I'm definitely drawn to visual, shiny things. So let me just style that quick, first. SURMA: Yeah, go for it. MARIKO: So I'm just going to style it bluntly, and you can take questions. SURMA: I guess I can actually-- MARIKO: First of all, I have a question for you. SURMA: Oh, a question for me? MARIKO: I want to have a ID selection on my CSS. SURMA: Yes. MARIKO: This keyboard does not seem to have a slash. SURMA: So you are actually usually in the New York office. MARIKO: Yes. SURMA: Now here in London with me. She just came over to visit specifically for this live stream. Specifically for this live stream. So she's not used to a UK keyboard. Shift+3 is the combination for-- MARIKO: Wait. Oh, that was caps lock. Oh. SURMA: There we go. MARIKO: I'm sure I'll ask you. SURMA: What is it? On the American keyboard, you have a separate key for the hashtag, right? MARIKO: Well, where the British pound sign is, it is already listed as a pound. SURMA: OK. I see. MARIKO: I mean, pound, but like pound meaning like a hashtag. SURMA: Not our currency. Words are confusing. All right, keep styling. MARIKO: Styling-- yep. SURMA: I wanted to quickly answer Tim's question from the chat, on the video as well, because it is interesting. We have been talking about modules on the Chrome Dev. Pretty much, recently, it's been on the top of the topic list for many frameworks switching over to modules or supporting modules. And since we're going to use workers today, it's probably important to mention that no browser yet has support for modules in workers. The syntax has been specified-- how to load a module in a worker, but no browser has actually implemented it. That's something that I guess [INAUDIBLE] have on the road map. But I'm also assuming it's not a very high priority for most browsers because very few people actually use workers, which is what I'm hoping to change with this live stream. So maybe after this, we can exert some more pressure on the browser people to speed the process up a little bit. MARIKO: I, P, X. SURMA: So we have some more colors. MARIKO: Yes. SURMA: This looks-- MARIKO: Let's make it font size bigger. SURMA: I never use the EM type. Maybe I should use it more. MARIKO: Yeah, that looks good. So what I did was I've hidden a default Input button. And then I made the label part as a clickable. SURMA: Ah, that's a good old trick. MARIKO: Yeah. SURMA: You have to be careful with accessibility on this one. MARIKO: So I prepared for this. I care about this thing. I do front end development. SURMA: You go and explain this. MARIKO: So right now, if I tab it, I can't get to the input element which I should be able to because it is an input element. SURMA: Yeah. MARIKO: But the one that is focusing input element is basically [INAUDIBLE] overflow here. And that's completely hidden. And it's just the display is taking over SURMA: Practically invisible. MARIKO: Right. So I need to put a focus to this element. So, again-- SURMA: Oh, so when the input element is focused, you're going to change the style of the label. MARIKO: Yes. SURMA: Tricky. Because what a lot of people do is actually display none in the input field. And that is very bad flexibility, because then it becomes non-focusable for people who use screen readers. So this one is a different trick where you make it invisible by giving it a zero by zero size and then making sure the styles are propagated from the input field to the actual-- MARIKO: So I kind of cheated. Because I couldn't remember the order of pixel order, or style, or anything. But let's see if this works. So if I tab it, yes. SURMA: Nice. MARIKO: And then tab out. So now, I can select it. So now I can see this is selected. Enter, and then file opens. SURMA: Cool. MARIKO: And then select it. So cool. Now we have something to start with. And that's pretty much the only UI element we will have on this, so we're done. SURMA: Sounds good. Now we have to do something with the image, right? MARIKO: Yeah, let me just change the color. This is not fun. Color-- let's say F3, F3, F3. SURMA: You're just making those colors up, aren't you? MARIKO: Yeah. Blue is not cool. Teal? Yeah. SURMA: Let's go with that. MARIKO: OK, so now we get into the JavaScript part. So the input element, the native element, will let us have the model for the file and then let us give the information about the file that we selected. But we need to access that. And we need to write a JavaScript for it. So let's write a script. And I apologize. I'm going to put everything on index.html. SURMA: Yeah, that's how we roll here. No worries about that. MARIKO: [INAUDIBLE]. So let's do the JavaScript part. SURMA: Look at that auto-complete. MARIKO: Don't you think my Sublime setting is supurb. SURMA: We haven't had Sublime on this stream in a long time. Have you heard of [INAUDIBLE] code? MARIKO: Yes. SURMA: Just to be clear, before a flame-war starts in the chat again, your editor is fine. As long as you press a key and that character appears on screen, you're set for web development. I don't care about anything else. So if you use WebStorm, if you use Sublime, if you use Notepad++, it all works for web development. So don't ever feel discriminated if you use a different editor from what you see other people using. MARIKO: Yep, so while Surma is putting the disclaimer about the editor, I just put the-- SURMA: I like the shoutout to the old jQuery syntax. MARIKO: Oh. So is what I do. So whenever I do reference to the DOM element or HTML element that is already existing in the screen, even though I don't use jQuery, I just put dollar sign. So that makes a mental note of like-- SURMA: It's a signifier. I like it. MARIKO: You know, I can see which element object still lives in the memory and then which one is actually displayed on the screen. So in this case, input is already on the screen, so I just put the dollar sign. And I add [INAUDIBLE]. So change event is fired whenever user selects different files. SURMA: Yeah. MARIKO: So another apology. I'm going to console log the hell out of this code, because that's how I code. SURMA: That's how the professionals debug. I think that's perfectly fair. MARIKO: So let's see what kind of event data that we get. So let's tab, select picture. Oh, oh, oh, I need to to do the dev tool, don't I? Inspect, console-- something is wrong. SURMA: Oh yeah. MARIKO: Oh, oh, oh. SURMA: Capitalization of that function call is always weird. MARIKO: Consistency is something that we don't have on the web. All right. SURMA: So we've got an event. MARIKO: Evenut usually-- usually, it's in the target where you want the data to be, right? SURMA: Yeah. MARIKO: And I just happen to know that if it's file in the target, there will be files. SURMA: Ah, so we actually get-- MARIKO: And then that's where all of that information-- SURMA: --and that's an actual file type, so something you can read. MARIKO: Yep, so the name of the file, metadata of things. SURMA: That's actually pretty interesting because you selecting a file, it's implicitly granting you, as the website, permission to read that file. So we're already done. We can now read this fine and work on it, which is what we want. So that's cool. MARIKO: So let's say the file that we want to access will be const file equal e.target.files, and then the first one in there. Now we have access to all the information, but we have to actually load it in the browser. SURMA: Yes. MARIKO: We only got the metadata. SURMA: Yeah, it's like an object representing the file, not the actual contents. MARIKO: [INAUDIBLE] hasn't figured that out. So in order to do that, we make a file reader. SURMA: Oh, I have touched on the file reader API, not on stream, but I have used it before. It's not the nicest API to use, but I guess you'll see now. MARIKO: So file reader, as it suggests, it just reads the file. And it comes with a lot of methods to read. So one way to read a file is read as data URL, which basically returns-- [INAUDIBLE] if it's basic 64 representation of the file. So I created the file reader here on the line 30. SURMA: I guess interesting to note that it's like-- most of you probably have seen data URLs somewhere, like when you in-line a little icon in CSS. I think, in most browsers, these are limited to two megabytes. So if you want to use-- in this case, we might want to load a bigger image later on, so that would probably not be a good choice for us. But we're going to start with it. MARIKO: Yep. And then, once you read the file, you have to do something once the reading is done. Because it is done-- what do you call it? Asynchronously? SURMA: Yeah. MARIKO: You basically have to listen to onLoad event. SURMA: Oh, OK, yeah. MARIKO: So I would add a file reader.eventlistener, and then load. SURMA: So somebody asked, why are you using const? Is it necessary? MARIKO: That's a good question. I don't know. I started using const. I started basically ditch every var and-- SURMA: Exactly. MARIKO: --replaced it with constant. SURMA: I think, on some stream previously, we talked about this. There used to be everything in JavaScript used to be var. And now there is let and const with ES 2015. And I mostly use const, because it signifies to the next person who reads my code that the value of that variable is not going to change anymore. It's just something that makes-- like you have to juggle less state in your head when you read the code. So I try to only use const and let. And also, the advantage is they're block scoped, rather than function scoped, which in JavaScript is the default and very confusing at times. MARIKO: Yep. So I just created a file reader. Read it as a data URL. Pass the file. In the file reader, I added an event listener for load event. So now, if I load it, I get the event back. And inside of the event, again, within the target, I get the result here, which is a B64 representation of the image that we loaded. SURMA: It's beautiful. I can practically see the image. MARIKO: So let's say const image data. Well, that's going to be confusing so EMB is E.target.result, right? So now, we need to somehow put this data into the browser so that browser shows the image, right? SURMA: Yes. MARIKO: An easier way to do it is making an image object. So again, image, new image. Ooh, ooh, ooh. I just [INAUDIBLE] deleted the semicolon. SURMA: [LAUGHS] MARIKO: You made a comment recently about my code. SURMA: I did. I personally am a big proponent of using semi-colons in JavaScript. Mariko's not. I disapprove. MARIKO: I don't have any strong philosophical belief or anything. I just worked in a company for two years that-- SURMA: And I think that's the thing. It's mostly an acquired taste. The way you start coding is the way you're going to keep coding. MARIKO: I mean, if somebody makes me like, you know, you should-- let's say like our team decides everybody should write semicolons. I would happily adopt it. But there's nothing, no mandate here. SURMA: I mean, we have a Google eslint configuration, which will demand semicolons. But, you know, I have eslint now on most of my projects. But for this, Supercharged is a production-ready code, so who cares? MARIKO: Yep. So I created an image object on line 31. And then now, I assign the B64 representation of the-- oh, let's say this-- Base 64. And then SRC, much like the attribute on the image tag, 64. And now, once this operation is done, then the load event will be fired for this image object. So once that's done, I need to append that image object into the screen, right? So let's check if this works. So document.body.append child image. And let's see if this works. Click, clickity, click. Yay! SURMA: We just loaded an image with a file selector. MARIKO: Yeah. SURMA: That's pretty damn cool. MARIKO: Yep. For the reason that comes in later, I'm just going to wrap this in div so that the-- SURMA: You can always divs. MARIKO: Again, I just need to kind of, like-- I'm not a designer, but I need to style something, you know? OK, Oops. All right. So now that we have a user select image, data image is globbed from the memory, we put it into browser. Let's put it in so we can apply the filter, as originally planned, right? SURMA: Yes. So I guess you can't do that on the image element, but you need a canvas. MARIKO: Yes. So image element is great, but it doesn't have a finer way of tweaking things. I know you can use a CSS to put a filter. SURMA: But that's not the point today. MARIKO: But you know, yeah. That is a very specified thing. That's not the point. That is like you're offloading a mass problem to CSS. We want to do the math on the JavaScript so that we can use WebWorker. So let's make a canvas where all of this happens. SURMA: We just published an article about how expensive a blur is. And if you animate a blur, you will probably see a lot of jank. I'll link to it in the description later on, if you want to read that. And you should, because I wrote it. And I would appreciate you reading my articles. MARIKO: I did. It was a wonderful article. SURMA: Yeah. And the point is, today, we're going to use a WebWorker eventually to offload heavy work. But that article basically explains why you blur. It's so computationally intensive, even though it is a simple effect in terms of what it looks like. MARIKO: Get context 2D. So I suppose I should explain this part if somebody has not done canvas work. So Canvas, much like any other HTML element, you just create a canvas tile, right? SURMA: An element, yeah. MARIKO: And then you can reference it by ID, or class, or however you would do. SURMA: You typo-ed the ID. MARIKO: Oops. What? SURMA: The V is missing. MARIKO: Ooh, V-U. SURMA: And the I. There you go. MARIKO: So that's what's happening here, a dollar sign preview. However, in order to do a lot of computational work on Canvas, you have to define the language that they are speaking. So going with a planet explanation, let's say you decided to-- I don't know, you are a master creator. So you decided to create this planet, right? SURMA: Yeah, as you're known to do on Friday. MARIKO: You decided to speak. I'm going to speak this one language, which is WebGL. SURMA: Yes, which was [INAUDIBLE] last time. MARIKO: Yep. So you would say, the WebGL uses a specific thing called shader. And then that's how you communicate with this canvas planet. In in my case, I want to use 2D, which is another set of language. And that's called context. So whenever you define that language part of the canvas, you call getContext. And if you are trying to do the shaders, you would say WebGL. But this time, I'm getting the 2D context. And basically, preview ctx, context. Context is the one you interact. SURMA: That's the actual manipulation API. MARIKO: Yep. So the canvas-- you can maybe set the width and height of the canvas. And that's about it. SURMA: That's pretty much it. Like if you do the WebGL canvas, you get all the functions to load triangles to the [INAUDIBLE],, to upload textures. And in this case, you get functions to draw lines, draw circles, whatever you want to do as a 2D operation. MARIKO: Yep. So instead of loading an image as a child element, now I put a image into the canvas and call the method that canvas has, which is drawImage, which basically takes an image element and puts it into the canvas. So let's do the thing and see if it shows up. Oops. Hello. Oh, OK. When you're drawing the image, you're first argument is the image object that you're putting to. And then you need to give the location where you want to draw. SURMA: I wish that was just half-sensible defaults. But sadly, this function does not. MARIKO: So I want to draw it full size, so I would say that the top left corner has to be zero, zero, X, Y. So zero and zero, and hopefully, this should draw a picture into canvas. Yay. SURMA: I mean, part of the image is missing, but you know, that's good enough. MARIKO: So it's inside of the canvas, right? It's not an image element anymore. So I know why this is missing, because we only created canvas. SURMA: And we didn't div it. MARIKO: And default size for canvas, I think, it's 200 pixel by 400. SURMA: I thought it was 300 x 150. MARIKO: Oh, maybe. SURMA: Like an iPhone. MARIKO: I only remember 1 x 2. SURMA: Yeah, it might be true. MARIKO: So we just need to set the size. So in here, I would say, preview with the name of the canvas. So preview.width-- SURMA: Oh, so you're going to resize the canvas before drawing the image. MARIKO: Yep. SURMA: Which makes a lot of sense. Because a lot of people apparently are very interested [INAUDIBLE]. It is real, it's just not switched on. And why would it be? It would just be dangerous. MARIKO: Solving what? SURMA: The [INAUDIBLE]. MARIKO: Oh, yeah. Yeah, yeah, yeah. SURMA: It is real, I'll tell you that. MARIKO: There we go! So now-- SURMA: Hurrah! MARIKO: --it shows up on the great screen. SURMA: All right. MARIKO: Let's just make, maybe-- I'm going to do maybe a bad technique of putting BR. SURMA: [GASPS] I'm disgusted. MARIKO: Because all I care is how it looks. SURMA: And that's how bad websites are born. Welcome to Supercharged. MARIKO: Does that even work? Yes. SURMA: Of course, it does. MARIKO: Later, if I was pushing this, I will clean it up with nice [INAUDIBLE] and everything in TechWiz Designer, but for now-- SURMA: Right. MARIKO: What do I need to do? Oh, yes. So now that the data is in Canvas, we can also get the data out of Canvas. SURMA: We can read back the pixels. MARIKO: Yes. So let's just switch up this thing and make it like a function. So apply filter as a function. And then we will have a separate function. SURMA: I mean, I was about to say it's a function that GL's going to write. It's not a function yet. MARIKO: Right. SURMA: Now it is. MARIKO: Fun-- oh, I can't type-- function. SURMA: You have the excuse of having to type on a foreign keyboard, not only in terms of layout, but also on our streaming laptop, which you probably have never-- MARIKO: See, this is the thing. It's not showing up. But the enter key is so small on the British thing. SURMA: It's bigger than on the-- oh, I guess it's taller but narrower. MARIKO: Yes, yes. SURMA: --while on the American, it's like wider, but-- and whatever you're used to, you will totally mess up once you are on the other keyboard. It's horrible. When I go to America, I just can't type anymore. And for you it's basically the same just now. MARIKO: Yep. So canvas has this very handy method called getImageData and putImageData. Image SURMA: You wrote "with" here. I think-- MARIKO: Ooh. SURMA: How did this work? Just by coincidence? Probably. [LAUGHS] Love it. MARIKO: Maybe, yeah. All right. All right, apply filter. In order to apply the filter-- SURMA: Thanks for the chat. MARIKO: In order to apply the filter, you need to get the chunk of pixel data. And then you need to analyze those pixel data and then change something about that pixel data. Right now, we're only interacting with the HTML element. We don't have that data element, right? So in order to do those, Canvas has a method called getImageData and putImageData. So the easier way to explain, to me, is like this. So imagine this is a canvas, right? You have a canvas. You go through a context, right? Context.call getImageData. And then on the parameter, you can specify where that should start and how big. SURMA: So you can get a subrectangle of the entire image as [INAUDIBLE].. MARIKO: So you have four arguments. And then you get data. And then make it pretty. And then you pass that data into putImageData method. And then put it back into the screen. SURMA: OK. Cool. MARIKO: So that's what we're going to do now. SURMA: So basically, you're going to take the image out, do some crossing, and put it back in. And that's how you do effects. MARIKO: So let's see what that data that we've been talking about looks like. So say I already have a context, so preview context dot getImageData, and zero, zero. And it would be image dot width. SURMA: Oh, we were using that. That makes sense. MARIKO: [INAUDIBLE]. Yep. SURMA: Yep. MARIKO: And let's see [INAUDIBLE].. SURMA: Cool. So what exactly is-- like, what is the image data? Is it like a special type? Or is it just an array? MARIKO: So image data is a special, I guess-- oops. SURMA: It's an error. MARIKO: Image data is not a function. SURMA: Oh, I think the I needs to be capitalized. MARIKO: Oh, yeah. So it's a special-- what do you call it? Object or data type? SURMA: A type. It's a type. OK. MARIKO: So you can see-- SURMA: Ah. So-- OK, keep going. MARIKO: Yep. They have three data in there, width and height. And then inside of that, data is an array. And the array-- SURMA: [INAUDIBLE] typed array. MARIKO: Typed array, yep. Array is a-- SURMA: This is the feature I love DevTool to make. Like, how many-- 360,0000 element array, and you can inspect every single one of those cells. MARIKO: Yep. So you can see, here is the data of a whole bunch of numbers. SURMA: OK, but those are just numbers, not really-- what do those numbers represent? MARIKO: So, yes. [LAUGHTER] This represents the image that's on screen here. SURMA: Yes. MARIKO: It's loaded on the canvas, but it is arranged in a certain way. And it's a one-dimensional whole bunch of numbers. And the way I think about it is it comes in the set of four. So from zero to three is the data you need to represent one pixel. SURMA: Ah, OK. MARIKO: And you might have guessed it, it's RGB and alpha. SURMA: That's why every fourth [INAUDIBLE] just now is 255, because we don't have any transparency going on. MARIKO: Yes. SURMA: OK, so every group of four forms one pixel. And then these four elements in individual groups form the R value, the G value, the B value, and the alpha value, as you might know from CSS. So they can probably handle that. MARIKO: One thing that changed from the CSS is that, in the CSS, if you do LGBA to set the color, the A, the last value, it would be zero to 1. But in the Canvas case, it will be zero to 255. SURMA: Oh, OK. MARIKO: Yep. Because the thing that we are using is 255. So you may ask-- but it's flat, how do you know where in position that pixel is located? SURMA: That sounds like math. MARIKO: So when you are writing a letter to somebody-- and I don't know if you do this in German? I suppose you grew up in Germany. So in Japan, if you're writing a paper or letter, you would get this graph paper. So each square is for one letter, righ? SURMA: Yeah. SURMA: So in my head, I'm thinking in the one-dimensional way of, hi, Surma. It's like one-dimensional. I wouldn't think about, like, here is going to be a line break or anything, right? SURMA: That makes sense. So basically-- MARIKO: And then, I'm going to write it from the top left corner. Say hi, Surma. And then once I run out of the space, I go to the next row. SURMA: I see. MARIKO: And then fill in what's in my head as one-dimensional data, right? It's the same thing. So from here, the first four is the top left corner. And the next one is the first lower, but the second from the left. SURMA: So it goes to the right, until we reach the width, which we have in our image data object. So we know once we have 300 times four, we go back to the first pixel, the next line. MARIKO: Yep. SURMA: All right. That makes sense. MARIKO: So because we have the width and height and a whole bunch of data, we can deconstruct this. SURMA: OK, cool. MARIKO: And we know where exactly which number is for which pixel over which color channel. SURMA: And now we can probably jumble around with those numbers and make the image look different. MARIKO: Yep. So let's see, in order to do this-- oh, this is a very tedious part. So as I mentioned, we were just explaining this. We have to do this in code, right? SURMA: I'm smelling For loops. MARIKO: Yes. So for loops-- SURMA: So for everyone who has joined just a couple of minutes late than we started, welcome. This is Mariko. MARIKO: Hello. SURMA: I'm Surma. I mean, we said we were going to do WebWorkers. We haven't even touched the WebWorkers yet. So far, we have been loading images from the hard disk and drawing them onto a canvas so that we then can process them and show-- I don't know. Mariko's coding, not me. How would I know what we're doing? I'm monitoring the chat. So if you have questions, just put them in the chat, and I'll try to follow along. We have very many people today, so it's kind of hard actually to keep track of where I stopped reading and where I have to catch up. But yeah, keep sending those questions. And Mariko will tell you how to do image processing in JavaScript, and then later on, what WebWorkers has to do with it. MARIKO: Yeah. SURMA: So OK, we're doing the classical-- MARIKO: Yeah, if you've dealt with Canvas, this is engraved into your heart that you're like, oh, yeah, yeah, you don't do those things. But I will explain what's happening in a minute. There should be parentheses. And there should be D. SURMA: Are you sure? Oh, index. MARIKO: Oops. SURMA: Yeah, that's probably For, right? Should there also be a times and not a plus? MARIKO: Yes. [INAUDIBLE] processing. SURMA: We have done this before. I mean, not us, but I have done pixels reversion on images before. MARIKO: Right. So what's happening is, after For loop is X, so going through this direction. And end of For loop is Y, so going through this direction. SURMA: Yes. MARIKO: So in combination of those, you get to do-- SURMA: Every pixel. MARIKO: Every pixel. However, every pixel, remember, has a four values. So index has to be padded with four, every time. SURMA: Yes, so if we increase the index by one, we have to jump four fields. And that's why it's times four. MARIKO: Yeah. SURMA: OK. MARIKO: Can I show off my drawing? Because I'm really proud of it. SURMA: I would love for you to show off your drawings. MARIKO: Here is the visual explanation of what I just said, right? SURMA: Right. MARIKO: So the outer loop is the green. Oh, in this case, I actually did Y. Sorry. SURMA: It doesn't matter, really. MARIKO: Yeah. So the green one goes down from top to bottom. And then the orange one is the X. And go from left to right. And then inside of that, you have index. And you get to access each pixel by index plus one, index plus two, index plus 3. SURMA: Yes, that makes sense. MARIKO: And you just do something, cool thing happen, once you have access to those things. SURMA: We're going to do the cool thing, as well. Don't you worry. MARIKO: So let's see. Let's say changing opacity, maybe? SURMA: Yeah, that sounds good. MARIKO: That's an easy one. SURMA: That sounds easy enough. MARIKO: So the last one is the opacity. So alpha is image data that we have. Inside of image data we access data. And then inside of that, index plus three is where all of the alpha channel lives. And then right now, it's all 255. So I'm just going to set it to 272 or 27. And then let's see if I actually get to-- oh, I need to put back into the data. SURMA: OK, so now we have changed the fourth value in each pixel pack, the A value 247, which is basically 50% capacity. And it's plus three. Because as always, in programming, we start at zero. So zero is the first pixel. And so plus 3 is the fourth value. MARIKO: So I just changed all of the value which is in the image data dot data, right? And then I put dot data back here on this line. So hopefully, this picture will come as slightly opaque. Yay. SURMA: Nice. We just have done image processing. MARIKO: Yep. SURMA: We're done. MARIKO: [LAUGHS] We can totally do the thing where-- let's see, with changing the thing, I think Matt did a warm filter or something. SURMA: Yeah, he had a warm filter in the end. MARIKO: R is the red value. So I think what he did was increase the red value a little bit to make it like a more slightly warm. SURMA: Yeah, I think he had a factor. And he would add to the red and subtract from the blue, depending on how high the warmth value was supposed to be. MARIKO: OK. Well, let's just do the simple thing of red is where the first one. So index, right? SURMA: Basically, we're going to make Jake's face more red, which is what he looks like once he has seen the sun. MARIKO: True. Oh, that's a good one. And then times one-- SURMA: Literally burnt. MARIKO: 1.1 or something-- well, 1.2. Let's see. Right? SURMA: Because the first is the red value, you're increasing the red value. MARIKO: Yep. SURMA: And interesting fun fact. Because the image data dot data is a clamped [INAUDIBLE] data array, if we go above 255 it will automatically stick to 255. MARIKO: Yeah, I love this feature. I love it. SURMA: And the same with zero. You can't go negative with a clamped [INAUDIBLE] data array, which makes it super handy for this kind of image data. MARIKO: So choose Jake's image. SURMA: Definitely more red. MARIKO: Definitely more red. You seem a nicely tanned color. SURMA: I never do in real life, though. MARIKO: So that's good. SURMA: Yes. MARIKO: And this seems to be working fine. But you know, in real life, the photo we take on the phone is much, much bigger. SURMA: That's true. I mean this picture, I think, we saw in [INAUDIBLE] was 300 x 300. MARIKO: Yeah. Nobody takes those photos. SURMA: No, nobody does. MARIKO: And I want to keep-- I don't want to resize it to make it fast, right? SURMA: Yeah. MARIKO: I want to keep the original size. SURMA: Of course. MARIKO: I basically want to [INAUDIBLE] SURMA: You don't want to lose quality just because you did some touch-ups. MARIKO: Yeah. So I have a big file, the cat JPEG. And once I open it, visibly, this is very slow. SURMA: Well, nothing happened. Oh, it just-- oh, so like it didn't not work, it just took that long to draw and process the image. OK. MARIKO: Yep. SURMA: That is a little bit long, I have to say. And also, we wrote this on the main thread JavaScript. So probably, the browser just froze. MARIKO: Yeah. So let's investigate. So you may need to help me here because I'm not an expert on the thing. But as I've heard, you just hit record. SURMA: That is correct. MARIKO: And then do something that you want to record. And then wait for it to happen. SURMA: OK, so DevTools is still working. It still hasn't appeared on screen. There it is. MARIKO: Stop it. SURMA: And let's see what DevTools says. DevTools says there's one massive red bar at the top. You never want to see those red bars, because that's what we call jank. That is when the main thread is blocked and basically cannot react to user inputs, like scrolling or clicking a button. You never want to see those. If you do, you have a jank problem, most likely, and have to investigate how to fix them. MARIKO: Yeah. SURMA: So that screen-- so I think, if you remember Paul Lewis, he always said, you have a frame budget of 16 milliseconds. You shouldn't be doing any more calculation in your JavaScript per frame than 16 milliseconds. This was six seconds. That's too much, Mariko. MARIKO: Yeah. And to be fair, I doubt it will go down to 60 frames per second when it's 2D canvas. SURMA: No, the image is just that big. There's not much we can do about it. MARIKO: The image is just that big. But we can minimize it so that the user can have a brake point so that they can interact with the UI. SURMA: Oh, OK. MARIKO: So it's like the perception of the speed is faster. SURMA: OK. MARIKO: You know, fake it until you make it. SURMA: That's right. That's what we call performance. MARIKO: Yes. So let's do this. The first thing that is very blocking-- and it would help me if you can point it-- the loading the image part. SURMA: I mean, there's the load event. Oh, that's when it's already loaded, right? MARIKO: Yeah. Function call, add event listener. SURMA: It's [INAUDIBLE] quiet. What are you looking for? MARIKO: The image loading part. I suspect this chunk is where we-- yep, file reader. We were reading the file. So I happened to know the-- it's not that new, but it's newer than WebWorker. SURMA: True. I mean, pretty much anything is newer than WebWorker, almost. MARIKO: [LAUGHS] So do you know what it is that I'm going to use? SURMA: Is it create image bitmap? MARIKO: Yes. SURMA: Yes, it is! MARIKO: Yay. So there are the-- what do you call it? API? SURMA: Yes. MARIKO: Call create image bitmap, which allow you to pass a file data and magically creates an image for you. SURMA: So this will allow us also to not only make the image decoding be a janky process, but it will also avoid the file reader API. MARIKO: Yep. So I do not need file reader API anymore. SURMA: That is so much better. MARIKO: I don't need to listen to the thing. I don't need to listen to the image-- oh, I still do, maybe. SURMA: Yeah, you still want to know when the image-- MARIKO: Right, but I can delete the file reader. SURMA: And that's good. MARIKO: For sure. Create image bitmap is a promise based. SURMA: Nice. I'm a big fan of promises. MARIKO: Once things are done you call it withstand and then-- SURMA: Or an [INAUDIBLE] function. Or we can use then, it's fine. It's completely valid, just saying. MARIKO: Do you want to do it? SURMA: No, no, no. This is your code. If I would take over right now, the first thing I would have to do is add semicolons to every line. So we're not doing that. You keep coding. MARIKO: So bitmap, see. Now the return value from this create image bitmap promise should be the image, right? So you can append that to image.soc? Wait. No. No. You directly go to the camera. So let's just [INAUDIBLE] like this. I don't even know what it was. SURMA: OK, yeah. So basically, you want to just see what kind of type you get back. MARIKO: Yeah, so let's just do the small one before we go into the thing. OK, so [INAUDIBLE] bitmap. SURMA: Just as height and width. MARIKO: Yes. SURMA: Done. MARIKO: And then I remember this API only exposes width and height to developers. SURMA: As properties? MARIKO: Right. Yeah. SURMA: But they can be methods? MARIKO: Yes, it is a representation of the data. Right? So I can directly draw that into Canvas, I think, because it's already image. And Canvas already have a draw image method. SURMA: OK. MARIKO: So let's see. I take this code here and then move it to the inside of that. SURMA: So you actually don't need the image event listener here. MARIKO: Yeah, I think we can delete it. SURMA: That's cool. MARIKO: So preview width would be the bitmap width. And then the preview height will be bitmap height. And then preview ctx draw image would be the bitmap. I don't need a console log. And fingers crossed, this image will load. SURMA: I have the greatest of faith in you. MARIKO: Uh-huh. Uh-huh. SURMA: Still works. You're good to go. MARIKO: Yep. SURMA: All right. So we now have avoided the image element. We have avoided the file reader API, which is good. So create image bitmap-- I think the reason it got introduced is exactly for this reason. It can decode an image, get the image data, without having to jank the main thread. It's in Chrome. It's in Safari? MARIKO: It's in Firefox. SURMA: It's in Firefox. MARIKO: But not supported in Edge or Safari. SURMA: But they have it on their radar, as far as I know. I'm not sure if they have it under consideration or in development, but they definitely know it's a thing. And they know it's a thing at developer one. MARIKO: Then as far as I know, in Chrome, they do this cool thing where the decoding document, which is the most extensive part, they do it off thread, off the UI thread. So you can see those in a network. Start recoding. Do this thing. Stop. And then you can see less-- SURMA: [INAUDIBLE]? MARIKO: Yeah, like much smaller thing. However, this here-- SURMA: The task [INAUDIBLE] render a foreground worker. Now that's a name that's great. So that's basically-- MARIKO: There you go, image decode. SURMA: So the image decode is happening in a worker that Chrome spun up, which means it's on a different thread. So it doesn't block the main thread. And that's what we want. MARIKO: Yeah. SURMA: So that's good, especially for bigger images. MARIKO: Yeah. I think, as of like a year ago, it was decoding images on the context dot code. So if you coded from UI thread, then it will decode it in the UI thread. SURMA: Yeah. MARIKO: If you coded from WebWorker thread, then it will recode it in Worker thread. And I think Paul Lewis wrote a helper library to make it easier for you so that you can load it fast. And I'm sure you can find it on our GitHub thing. But Chrome, since then, changed it so that any image will be off the thread, which is amazing. So that was one part of it, but then we haven't figured out the apply filter part. SURMA: So the apply filter part is the one that still makes it super slow and not nice. MARIKO: Yep. So apply filter. We can delete this part. And this is when we get to use WebWorker. SURMA: Finally! After a good amount of set-up work, we now have reached the point where the workers come into play. MARIKO: So what we've got to do is, as we saw it, this part of going through each pixel and doing something was really expensive. SURMA: Yeah, if you have the other images, like what? 4,000 x 3,000 or something? So it's like 12 million pixels. That's going to take a while in JavaScript. MARIKO: But the lucky part is that this doesn't touch the DOM. This doesn't touch the UI. This doesn't have to do anything, it just needs to do the math. SURMA: It just has to have the array, right? MARIKO: Right. SURMA: Yeah. MARIKO: So we can load these to the Worker thread. So referesher of how Worker works. SURMA: More drawings. I love it. MARIKO: So again, there's the two threads that we're dealing with. One is a UI thread or main thread that you call it, which is where you deal with the DOM and UI. And then you spawn up a WebWorker thread. Let me go dive into the code. SURMA: Yeah, go for it. MARIKO: I really like the style of annotating the code and kind of like picture of the code. So let me explain what's going to happen. So inside of your application, we are going to create a worker, which is a new WebWorker. And then you pass a name of the JavaScript file that you want to execute in the Worker thread. That is kind of like launching an International Space Station. Now, you are starting-- SURMA: We are launching International Space Stations! MARIKO: --something you can communicate with, right? So now, go back to the Worker thread side. If you want to use external library, I think it's similar to ServiceWorker, right? Import scripts-- SURMA: Yes, it's exactly the same thing. MARIKO: --is the word you use. SURMA: Just to be sure, ServiceWorker is not supported in all browsers. Like edge is just now working-- I think they closed the logic on us. Apple has announced they're working it. Firefox has it. Chrome has it. Workers, without the service bit, every browser, even old Internet Explorer, has these. MARIKO: Yep. SURMA: Just to be very clear about this, this is not like leading edge technology. This is like 2001 technology, I think, or something. MARIKO: So yeah. You create a worker JS with whatever that you want to do. You launch it from your application side. And then, now, it lives in a different thread of the memory. How do you communicate those data, right? I'm sure we use satellite to send the data to our International Space Station in real life. I don't know what kind of technology they use. SURMA: Lasers. MARIKO: Do they use Internet? SURMA: It's probably lasers. MARIKO: Anyway, so that communication is done by post message and all message event. So from the application side, you call post message with the data you want to pass. And then on the worker side, you listen to on message event. And I kind of drew it like you do, all the clicky thing while expensive stuff happens on the worker side. SURMA: That sounds good. MARIKO: And once the worker is done, then they use the same thing-- post message to send the new data or new information that they [INAUDIBLE] back to the main side. And now main side can listen to our message. And if you need to terminate it, you can terminate it. And I kind of like put it into guiding them to-- SURMA: That's horrible. We have this man-made, glorious object-- the International Space Station. And you want to throw it into a black hole. MARIKO: I couldn't come up with a good ending for WebWorker. SURMA: Well, I mean the other thing would have been just send it into the Earth's atmosphere and let it burn. MARIKO: Yeah, that's sad. SURMA: It's just a satellite. MARIKO: A black hole is a little more romantic. SURMA: Let's go with black hole. It's like a new frontiers kind of approach to things. So let's go with that. MARIKO: Yep. So let's creae a WebWorker-- worker new worker. And then I need to pass the file. So I need to make new file. SURMA: Oh, new file. MARIKO: What's the shift key for this? [SIGHS] [LAUGHTER] SURMA: Every key is different here. MARIKO: Yeah. Worker JS. So now I can reference this with-- SURMA: So that will basically just download-- the browser will go down at the file, create a new JavaScript thread, load that file in the thread. And then you have control of a separate thread just for itself. MARIKO: So as I mentioned, worker takes a listen to on-- ah, let's say the post message first. So I created the worker. I want to pass the data to worker so that worker can deal with it. So worker dot post. Is message M capitalized? Again, API is so hard for me. SURMA: So if you haven't used post message, it's just what it sounds like. It posts a message over to whatever you're post messaging to. And post message can send JavaScript objects, but only objects. So you will lose, as it's called, the prototype chain. So if you have a class instance, it will not arrive as a class instance on the other side, but as a symbol JavaScript object. But it's usually good enough. If you just do a little JSON style object. Be like, this is what I want to do. This is my parameters, which is probably what you want to do right now. MARIKO: Yeah. So I created the post message, send the image data, as I mentioned. This follow-up needs to go to Worker thread. So let's go to Worker thread-- Worker file. And this one will come into play later. But let's create a message handler. How would you do this? Self dot message on message? What do you usually do? SURMA: I would usually just say-- and I have to blame Jake for this because he basically said self is unnecessary, so I stopped using self. I would just say add event listener message. But if you want to use the on message, I would probably use self on message. MARIKO: Do I need to reference anything here? SURMA: No, you can just-- MARIKO: Oh, interesting. SURMA: Yeah, I know. Right? MARIKO: Because I think, on the drawing, I still use the self dot on message. I think I just use whatever the Google Developer site explains to me. Or maybe HTML5 Rocks explained it to me. SURMA: There's probably an HTML5 Rocks out there for this. MARIKO: So message event will be fired. And let's see-- so this, let's call D, data, should be the data we passed. And I want to see what this looks like, actually. So again, console log, the greatest tool. SURMA: That's also something that is good to know. If you want to work with Workers, the debugging story around Workers is actually fairly good. So console logs from your Worker will just appear in your Devtools just as well. So you will be able to use this approach to debugging. MARIKO: What is duo? Index 44-- something is not working. Oh, oh, oh, oh, because we're not using that image anymore. We're directly loading that to the thing. SURMA: Correct. MARIKO: So this should be the size of preview now, because we set the width and height there. So I can reference it with canvas. OK, so let's hope this works. Do the thing. There. Message went. And then inside of that, I have data where data is exactly the representation of the image data we dealt with. SURMA: Yeah. MARIKO: So inside of the Worker, I get to access data dot data dot data. SURMA: So this was a big image, but transferring it was surprisingly fast. Why? MARIKO: Oh, well supposed to be this shouldn't be fast. SURMA: True. Why was it fast? Either way, so the image data contains an array buffer, a typed array buffer. And typed array buffers are JavaScript versions of actual chunks of memory, rather than abstract objects you can pass around. And post message has the ability to transfer those, which means instead of copying the entire image, it will actually transfer them. So no copying necessary. The main thread will lose access to this typed array buffer, and the worker will get access to it, right? MARIKO: Yep. So basically, let's say you and I are a memory field, right? I have this image data here. And then I want to pass it to Worker. Worker, if I don't, on this line 44, if I don't have anything specified-- SURMA: We copy it. MARIKO: --then this is literally copied into your field. SURMA: Yeah. MARIKO: However, if I specify an argument, which we'll get to, then it basically just moves the pointer. SURMA: It moves ownership. MARIKO: Yep. SURMA: Like you'll lose ownership. I get ownership. And no copying needs to happen. MARIKO: Yep. SURMA: And that's good. MARIKO: And it's the weird API where you have to pass an array. SURMA: It's a bit weird. MARIKO: And specify things. So in this case, image data dot data is the typed array. SURMA: That's the actual array. MARIKO: Yep. Dot buffer. SURMA: Right. Because typed array buff-- like, there's array buffers, which are the chunks of memory. And then there's the typed arrays, which are views onto these buffers. Because you can interpret the same chunk of memory as a series of floats or a series of 8-bit integers. And we want to transfer the buffer, not the interpretation of the buffer, which is I guess the distinction. Which it's sort of a bit weird. But maybe that's a good way to think about it. MARIKO: Yeah. This is a little quirky bit that when you're dealing with Worker that you have to encounter, I guess, unfortunately. So inside of the Worker, the image data is the one that we want to access. So let's say image data is D dot data, right? And then we can basically access same thing. So let's do the same computation of making the face red inside of-- SURMA: The face red operation. MARIKO: Well, warm filter, not the face red filter. SURMA: I like face red operation much better as a name. It seems like better branding to me. MARIKO: So I have a whole bunch of weird references that I need to-- so let's say, width is inside of image data. So width W is image data dot width. Height is-- SURMA: Oh, you're just making it more readable. That's good. MARIKO: Yep. Dot and then data. The one that we are actually dealing with is image data. So now I need to tweak this a little bit. Oh, just-- ah, [INAUDIBLE]. SURMA: Backslash. MARIKO: Ah. W-- oops-- height, index. SURMA: Yes. MARIKO: This will be W and data index. SURMA: All right. It's just data now. Yeah. MARIKO: Mm-hm. SURMA: All right. So we sent the buffer to the Worker. The Worker did the same thing as before, like went through all the pixels, did all the right manipulation. Now we just send it back? MARIKO: Yep. SURMA: OK. MARIKO: So we need to send it back on a post message. So wait. If you are in the [INAUDIBLE] event listener, how do I send it to post message? SURMA: Isn't that global? Just post-- I think in Workers, it's just the global. MARIKO: Self to post message. SURMA: Yeah, just go post message. MARIKO: OK. SURMA: It gets more complicated if you talk about ServiceWorker. Because everybody can talk to the ServiceWorker, but the ServiceWorker can talk to all the open website. So you actually need to define which window to talk to. And that's a whole different story. In this case, we have it nice and say, we just call post message. MARIKO: Yeah, it's weird for me to not reference self. But I guess if Jake says self is not necessary, then it's not necessary. OK, so supposedly, we do all the things and then use the post message to send the data that it was passed. Because we manipulated inside of that data in this follow-up. SURMA: Wait. Is D the data? Or is D the event? Because you're not sending back the event, and you want to-- MARIKO: Oh, that's true. So I have to do the image data, yes. SURMA: And also you have to do the transfer bit again, right? MARIKO: Yes. SURMA: Sorry. [LAUGHS] This is where you can tell the post message API is really old, because it feels pretty inconsistent with the rest of the web. But that is also, you know, the charm of the web. Kind of like, that's how it landed. And that's what we've got now. And this all works. So we'll make it work. MARIKO: Yep. So now, sent it, but then we need to listen to it. So we can-- ah, this is [INAUDIBLE] doing it. Would you do it outside of this function? SURMA: Yeah, you've done it so far. Why not? Yeah, just do the-- MARIKO: [INAUDIBLE] an event listener message. And let's see. Inconsistency, let's make it D. And if this pattern is repeating, then D dot data should be image data. SURMA: Sounds about right. Ah, we're copying and pasting lines now. This is typical reuse. MARIKO: And then put that data into the canvas. SURMA: All right. I'm nervous. MARIKO: Let's hope this works. Yes! SURMA: So it looks the same, but something a whole lot different just happened. Actually, yeah. Let's do the performance check right away. So what is going on now is that we're doing the same thing as before, but all the expensive processing is happening in a different thread, meaning there shouldn't be any red bars if we do a performance analysis on this. MARIKO: Record. Set it. Done. How's that? SURMA: OK, that looks pretty short. And we can see the dedicated Worker thread is what we are using. It has some work to do. MARIKO: So function call to Worker JS, happen in dedicated Worker thread. SURMA: OK. MARIKO: So previously, all of this part was clogged inside. SURMA: You can mark regions with shift, by the way-- shift and click. MARIKO: Shift and click? What? SURMA: Shift, click, and hold, and it can mark regions. MARIKO: Ooh. SURMA: And it can measure how wide they are. MARIKO: Ooh. TIL. SURMA: Performance pro tip. MARIKO: So previously, this whole chunk of yellow was living in here, which means it was blocking users' interactions. If they want to click on something, or you want to do another JavaScript operation, it was just blocking. SURMA: Yeah. MARIKO: And now you put it into Worker thread. SURMA: I mean, the ultimate test now is load the big image, right? MARIKO: Yep. SURMA: And see if we have a six second frame, or if the frame rate keeps going. MARIKO: Something better, right? Yeah. So let's do record-- SURMA: Recording. MARIKO: Big image. SURMA: Get that cat in there. That was also quicker. MARIKO: Yeah, visually quicker. SURMA: So here's an interesting fun fact, something I recently learned-- if you look at the bar graph at the top, you know the little mountains thing, when something is striped it means it's off main thread. So it means something is happening, but it's not blocking the main. That's good. And as you can see, there is no red bars. Because we're never blocking the main thread with this version. Because we're using de-code image, get image bitmap, create image bitmap, and the Worker. MARIKO: Yeah. SURMA: So good. MARIKO: Yeah. So That's pretty much it, right? SURMA: Nice. MARIKO: Do you want to do anything? Do other things? SURMA: No. I mean, we're perfectly on time, once again, as on Supercharged, it is common. Thank you, so much, for traveling all the way just for this. MARIKO: [LAUGHS] You're welcome. SURMA: As Mariko promised, she is, of course, going to clean up the code or just give it to me. I'm going to put it on the GitHub repository, which I'm going to put in the video description once the video is up on YouTube. Thanks to everybody for coming and talking to us in the chat. It's been super active. I was really, really happy to see that. As I already announced on Twitter, this is the last Livestream for the 2017 season. It's time for a little Christmas break. But I'm going to be back, we're going to be back in 2018, with many more things I want to try. I hope you enjoyed this. I hope you learned something. If you have more questions, you can ask Mariko, not me. Or me, you can ask me too. MARIKO: Yeah, Twitter, or they can ask ChromiumDev Twitter. SURMA: Also good, ChromiumDev. We are pretty responsive there. MARIKO: Yeah, which actually we are the two active persons who's watching that. SURMA: You are mostly going to get replies from either Mariko or me if you tweet at ChromiumDev. If you want to stay up to date with Supercharged live streams, microtips, maybe even totally tuning tips, who knows, subscribe to this channel so you get little notifications when we put up a new video or we go live the next time. Thanks, for watching. And I will see you all in 2018. [THEME MUSIC]
Info
Channel: Google Chrome Developers
Views: 32,970
Rating: 4.8764162 out of 5
Keywords: Chrome, Developers, Google, Web, WebWorkers, PWA, Progressive, App, Mariko, Surma, DasSurma, Kosaka, Kosamari, live, livestream, Coding, Code, product: web, fullname: Surma, Location: LON, Team: Scalable Advocacy, Type: DevByte, GDS: Full Production, fullname: Mariko Kosaka
Id: X57mh8tKkgE
Channel Id: undefined
Length: 66min 34sec (3994 seconds)
Published: Thu Nov 02 2017
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.