Class-based Tree Shaking - HTTP203

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
JAKE ARCHIBALD: I'm supposed to be-- we're supposed to be doing this now, aren't we? All right. Well let's-- SURMA: That's our intro. JAKE ARCHIBALD: OK. Excellent. [THEME MUSIC] YouTube comments. SURMA: They're sadly a thing. JAKE ARCHIBALD: They are sadly a thing, but we have been listening to them. SURMA: Some of them, yes. The ones that actually have a point. JAKE ARCHIBALD: Well-- SURMA: Not all of them do. JAKE ARCHIBALD: There's some good points that are being made-- recently increasing. So people have been noticing my impending baldness. That's something that has been coming up in the comments. Thank you for everyone who has been-- SURMA: And noticing me that I don't ever let you finish a sentence. JAKE ARCHIBALD: Has that been noticed? SURMA: Yes. JAKE ARCHIBALD: Oh, well, we could talk about that in a bit. But one of the things I-- we have noticed and listened to is people saying, when we talk about code, can we show some code? SURMA: Yeah, that might be helpful. JAKE ARCHIBALD: So-- SURMA: Could be nice. JAKE ARCHIBALD: We thought like-- we've got a camera-- we got an iPad here with some code on it. So tree shaking. SURMA: Oh! So let me guess. You're just doing this so we can put a nice buzzword in the title. JAKE ARCHIBALD: Yes. SURMA: 12 things you didn't know about tree shaking. Number four will blow your mind! JAKE ARCHIBALD: Class-based Tree Shaking is the title of this I think. So here we go. We've got a code example here. I'm importing a load of stuff. SURMA: Plugging your own library are we? JAKE ARCHIBALD: It's based on a true story, like all good stories are. I'm importing a load of stuff. This file has a lot of stuff in it, but I'm only using two of them. And like modern tools like roll up-- SURMA: Then why are you importing the other ones? JAKE ARCHIBALD: Well, just to show that they're there. Yes, technically I wouldn't have to import them. SURMA: I mean, commonly, I guess, you would import this as import IDB key valid from-- put it all of them in an object so you have-- JAKE ARCHIBALD: No. No. SURMA: No, you wouldn't. JAKE ARCHIBALD: No, you wouldn't do that. SURMA: I wouldn't do that. JAKE ARCHIBALD: Good. So in this-- each of these methods is individually exported, and that means that tools like roll up and Web Packer can go, you're only using two of these or three of these. And it goes, well, I'm just going to take the ones you're not using and delete them. SURMA: And that's tree shaking? JAKE ARCHIBALD: And that's tree shaking. And that's good. SURMA: Oh, because the tool can figure out what you're using, because if you don't import them, you can't use them. JAKE ARCHIBALD: Right. SURMA: That's how modules work, right? JAKE ARCHIBALD: Right. So in the days where we would import jQuery, and you've got 101 methods, and you're only using three of them-- tough. You were taking the full weight of each query. And with tree shaking, that's not true, because you're only using the stuff you actually import and use. So, yeah, this is great. This works fine, but I ran into this problem. So say this is a library, real library, and someone said, well, it's all fine having set and get and all of these things, but I want to create my own store with-- that doesn't clash with another store. I was like, well, I know how this works. So I made it happen. And so I thought, well, it could be like this. SURMA: Now you're importing a store? Oh, yeah, that's the common-- you now wouldn't just [INAUDIBLE] the thing, but you have to instantiate the whole thing first. JAKE ARCHIBALD: And it knows all of its stuff about where the database connection is and all of that, and it can go. But the problem is classes can't be tree shooken-- SURMA: [LAUGHS] JAKE ARCHIBALD: I'm sure that's the right way of saying that. SURMA: Oh, so, OK. So you have a class. It's called store. In the constructor, as we can see here, it gets the backing store name, the IDB-- did it call a store an IDB? JAKE ARCHIBALD: Yeah. Object store. SURMA: And then the class of it has all these methods, like get and set, but also the other ones we saw previously, like keys and whatever that was. JAKE ARCHIBALD: Yeah. SURMA: OK. So but if you don't use one of them-- ideally you wouldn't-- load the code. Right? JAKE ARCHIBALD: But it's not statically analyzable in the same way a function is. So here I'm using dark keys, but I'm not using the delete method. I'm not using the clear method. But it has no way of being sure about that. Because keys like this, it looks like that static in the analyzable. But there are many other ways-- SURMA: That's what I meant. You can do very weird things. JAKE ARCHIBALD: Right. Exactly. So you can do as a string, but that string could be like two strings added together, or it could be some sort of functional-- SURMA: If I ever see anyone writing code in the last line, I will hunt that person down. JAKE ARCHIBALD: But there are legitimate reasons to do that. You might have a series of method names, and you want to append on to the start or remove from the start. SURMA: Yeah, I've done that myself. If you build your own little meta-programming thing where you generate event headers on the fly, this can happen in real production code. This is not you being stupid. This is-- this can happen. JAKE ARCHIBALD: It can happen. And so my question really is, how do we solve this problem? And spoiler alert, I don't really have the answer, but I've seen other libraries have done. So one example is this is the style of RXJS. So here we're importing the store. So we got our store. It doesn't have the keys method on it, because that's, let's say, a less common method to call. SURMA: Sure. JAKE ARCHIBALD: But you import another JavaScript file, which has the keys implementation in it. SURMA: And that just mutates the prototype? JAKE ARCHIBALD: It mutates to prototype. Exactly. So this would be the implementation. SURMA: I mean, it works. I totally get it. JAKE ARCHIBALD: Yeah. SURMA: I'm always wary when suddenly the order of imports matter. I feel like that's a dangerous path to go down. And generally, like, mutating the prototype is-- it's been done for years. I'm not saying it's bad or stupid. It's just-- it feels dirty. It feels like that should be a better solution. JAKE ARCHIBALD: Absolutely. And part the problem with this as well is if you import it but don't use it, tough. Because it's not statically analyzable once again. You know, roll up or a [INAUDIBLE].. SURMA: So it shifts the burden onto the developer rather than just being a tooling issue? JAKE ARCHIBALD: Yeah, and it means you end up doing this import for every method. It's kind of long strings. It's a bit messy. So thinking about other ways of doing this, and there's a JavaScript proposal which I really like, I'm a big fan of, called the bind operator. SURMA: Yes. I remember the bind operator. JAKE ARCHIBALD: So here we're importing store and the methods-- SURMA: So store, basically, just in this specific, then it would practically more or less be an empty class. That's not much in there. JAKE ARCHIBALD: Exactly. And you would call it like this. Store call it, call on set. And that's essentially saying call the set method as if it were an instance of store. SURMA: If you have a function in JavaScript, you can use dot call. You cannot just use parentheses to invoke it, but you can use dot call. And then you give it what should be this inside the function like this, what is this supposed to be, and here I have an N, what the parameters are. And the bind operator just says, take my left side as this, and the right side just do a normal invocation. And this-- JAKE ARCHIBALD: Technically. SURMA: So the set function kind of thinks it's being called on store even though it is-- there is no tight coupling between those two things. JAKE ARCHIBALD: Exactly. So you use this just as you would in a class, and this will refer to the store as it would within the class. And this can be tree shaking and all of that stuff if you don't use it. SURMA: I've used this in Babel a couple of times. But I don't think this has shipped yet anywhere. JAKE ARCHIBALD: No, and this makes me sad that it looks like the whole proposal is dead. SURMA: Oh, that's sad. JAKE ARCHIBALD: That-- it does make me sad. SURMA: Do you know why? JAKE ARCHIBALD: Well, because another proposal has started taking-- caught people's attention for doing a lot of the same stuff. And this is the direction that the RX folks have been looking at. So same again-- you import the store and then separate methods. SURMA: Like same as before. JAKE ARCHIBALD: But-- [HUMS OMINOUSLY] SURMA: OK. JAKE ARCHIBALD: So this is the pipeline operator. SURMA: What's the difference? JAKE ARCHIBALD: Well, so what this is saying is coal-- they will take the right hand side, treat it as a function, and pass the left hand side to it, and call it. SURMA: So set right now it is a function that you invoke, and it returns another function. JAKE ARCHIBALD: Yeah, great, isn't it? So that's-- yes, so your implementation of set would look like this. So here we go to a function, which returns a function. The first one takes the key and the value, and the second one takes the store. SURMA: I see. The ugliness is hidden, but it is ugly. JAKE ARCHIBALD: Yeah. Yeah. And this is the way the RX folks are looking at-- I think it's OK. I think you're right-- writing it is confusing. Explain to someone that, oh, yeah this is a function, and it returns a function. That's how it works. SURMA: So I think I've seen this operated before-- the exact same operator in F sharp. JAKE ARCHIBALD: Yes. SURMA: It works differently there, though. Because there, basically, what is on the left hand side will become the first argument of the function of the right hand side. JAKE ARCHIBALD: So in this case, it will become the first argument, but it will be-- SURMA: But of the function that it returns. JAKE ARCHIBALD: I see. SURMA: That would be injected in front of the other argument. So you don't have the necessity to create a new function first before you can start using this. JAKE ARCHIBALD: So there is an alternate proposal, which looks like this. Here you're using a question mark to say where a store would be passed into. SURMA: I see. JAKE ARCHIBALD: And this is the hack style of it. SURMA: So where's this at? Is this-- JAKE ARCHIBALD: So this is stage 2. There are two main competing proposals for the pipeline, and that spawned another 12C7 variants of the two ways of trying to combine the two. So that's, yeah, it's very much experimental, still discussing the features land. But I keep going back there. Yeah, I keep going back to bind for things which are instance methods. And I feel like even if this ships, I feel like I would end up going for something more like this. SURMA: Oh, that's actually not too bad. JAKE ARCHIBALD: Like where I have a do method that takes-- SURMA: Legit just under the hood, probably, switching it around right? JAKE ARCHIBALD: Which are legitimately under the hood is just going to do-- yeah, it's just going-- SURMA: It's going to do? JAKE ARCHIBALD: The argument's this? Exactly that. SURMA: I like this pattern, honestly, because this you can do today. And it would allow you to do the tree shaking. JAKE ARCHIBALD: Exactly. The downside to this pattern is I don't think it's possible with TypeScript, which I know it shouldn't hold you back from JavaScript but if you're-- SURMA: Why not? JAKE ARCHIBALD: Because in the do case, the second and third and to infinity arguments, their types depend on the the thing of the first argument. SURMA: You can do that, but then the type would have to know about all possible functions. JAKE ARCHIBALD: Exactly. SURMA: It's like they do with event listeners where they define the type depending on the string value of the first argument and then define what the event type will be. JAKE ARCHIBALD: So you can do that with a string. I don't know if you can do it with an object. You maybe can. SURMA: Good question. I actually don't know. But it's definitely more complicated than it should be. JAKE ARCHIBALD: So, yeah. So that's the problem I have to say. That is probably the best solution I've got or just a function, which will take the store object and-- SURMA: Or just stable the bind operator. JAKE ARCHIBALD: Or just be able the bind operator. SURMA: It still ended up-- the plug in still exists. JAKE ARCHIBALD: Yeah, but to go for something which is not going to be pursued in JavaScript, maybe, it feels like the wrong direction to go. I don't know. There's one more proposal, which is just being talked about, which I-- it would be a way of having an instance and a declarative way of saying, take these extensions and apply it to this class but only in this scope. SURMA: OK. JAKE ARCHIBALD: And so it's a kind of way of-- SURMA: It's very specific to this problem then, though, because I feel like-- JAKE ARCHIBALD: Absolutely. SURMA: Bind operator would be a more powerful generic even-- or a better solution of the pen operator would be more generic, more powerful tool to have. JAKE ARCHIBALD: And that is-- yeah, that's my worry about it as well. Is it solving that specific problem whereas bind solves that problem and lots of other problems? SURMA: Yeah. JAKE ARCHIBALD: So, yeah, I'm curious to see where it goes. We've got hacks we can use in the meantime. SURMA: Yeah. JAKE ARCHIBALD: But I just-- yeah. I want bind or a way to do this in TypeScript, which might already be possible, and if so, someone should tell me in the comments. And this is me farming off my work to other people. SURMA: [LAUGHS] Should we introduced 0HTB codes? JAKE ARCHIBALD: [LAUGHS] Negative HTB codes. SURMA: What if we reach 100? JAKE ARCHIBALD: Oh. SURMA: What do we do when we actually shoot HB2 or 3?
Info
Channel: Google Chrome Developers
Views: 22,275
Rating: 4.9416909 out of 5
Keywords: class-based tree shaking, tree shaking, tree shaking javascript, tree shaking webpack, javascript, webpack, dead code, removal of dead code, bundling, clean up your bundling process, dead-code elimination, code clean up, what is tree shaking?, how to clean up code, http203, surma, jake archibald, chrome, chrome developers, web developers, developer for the web, google developers, devtips, GDS: Yes;
Id: lsd2-TCgHEs
Channel Id: undefined
Length: 12min 16sec (736 seconds)
Published: Tue Apr 10 2018
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.