JSJ 315: The effects of JS on CSS with Greg Whitworth
In this episode, the JavaScript Jabber panelists discuss the effects of JavaScript on CSS with Greg Whitworth. Greg works on Microsoft EdgeHTML, specifically working on the Microsoft Layout team, is on the CSS working group, and is involved with the Houdini task force. They talk about JS engines and rendering engines, what the CSSOM is, why it is important to understand the rendering engine, and much more!
Special Guests:
Greg Whitworth
Show Notes
Panel:
- AJ O’Neal
- Aimee Knight
Special Guests: Greg Whitworth
In this episode, the JavaScript Jabber panelists discuss the effects of JavaScript on CSS with Greg Whitworth. Greg works on Microsoft EdgeHTML, specifically working on the Microsoft Layout team, is on the CSS working group, and is involved with the Houdini task force. They talk about JS engines and rendering engines, what the CSSOM is, why it is important to understand the rendering engine, and much more!
In particular, we dive pretty deep on:
- Greg intro
- What is the Houdini task force?
- Extensible web manifesto
- DOM (Document Object Model)
- Layout API
- Parser API
- Babel
- jQuery
- Back to basics
- JavaScript engine and rendering engine
- What is the CSSOM?
- Every browser has its separate JS engine
- Browsers perspective
- Aimee ShopTalk Podcast Episode
- Why is it important to understand how the rendering engine is working?
- Making wise decisions
- Give control back to browser if possible
- When you would want to use JavaScript or CSS
- Hard to make a hard or fast rule
- CSS is more performant
- Overview of steps
- And much, much more!
Links:
- Parser API
- Babel
- jQuery
- Aimee ShopTalk Podcast Episode
- JavaScript
- @gregwhitworth
- GWhitworth.com
- Greg’s GitHub
Sponsors
Picks:
AJ
- Microsoft Surface
- Microsoft Cursor
Aimee
Greg
Transcript
Hey folks, I'm a super busy guy and you probably are too. You probably have a lot going on with kids going back to school, maybe some new projects at work. You've got open source stuff you're doing or a blog or a podcast or who knows what else, right? But you've got stuff going on and if you've got a lot of stuff going on, it's really hard to do the things that you need to do in order to stay healthy. And one of those things, at least for me, is eating healthy. So when I'm in the middle of a project or I just got off a call with a client or something like that, a lot of times I'm running downstairs, seeing what I can find that's easy to make in a minute or two, and then running back upstairs. And so sometimes that turns out to be popcorn or crackers or something little. Or if not that, then something that at least isn't all that healthy for me to eat. Uh, the other issue I have is that I've been eating keto for my diabetes and it really makes a major difference for me as far as my ability to feel good if I'm eating well versus eating stuff that I shouldn't eat. And so I was looking around to try and find something that would work out for me and I found these Factor meals. Now Factor is great because A, they're healthy. They actually had a keto line that I could get for my stuff and that made a major difference for me because all I had to do was pick it up, put it in the microwave for a couple of minutes and it was done. They're fresh and never frozen. They do send it to you in a cold pack. It's awesome. They also have a gourmet plus option that's cooked by chefs and it's got all the good stuff like broccolini, truffle butter, asparagus, so good. And, uh, you know, you can get lunch, you can get dinner. Uh, they have options that are high calorie, low calorie, um, protein plus meals with 30 grams or more of protein. Anyway, they've got all kinds of options. So you can round that out, you can get snacks like apple cinnamon pancakes or butter and cheddar egg bites, potato, bacon and egg, breakfast skillet. You know, obviously if I'm eating keto, I don't do all of that stuff. They have smoothies, they have shakes, they have juices. Anyway, they've got all kinds of stuff and it is all healthy and like I said, it's never frozen. So anyway, I ate them, I loved them, tasted great. And like I said, you can get them cooked. It says two minutes on the package. I found that it took it about three minutes for mine to cook, but three minutes is fast and easy and then I can get back to writing code. So if you want to go check out Factor, go check it out at factormeals. Head to factormeals.com slash JSJabber50 and use the code JSJabber50 to get 50% off. That's code JSJabber50 at factormeals.com slash JSJabber50 to get 50% off.
Hey folks, I'm a super busy guy and you probably are too. You probably have a lot going on with kids going back to school, maybe some new projects at work. You've got open source stuff you're doing or a blog or a podcast or who knows what else, right? But you've got stuff going on and if you've got a lot of stuff going on, it's really hard to do the things that you need to do in order to stay healthy. And one of those things, at least for me, is eating healthy. So when I'm in the middle of a project, or I just got off a call with a client or something like that. A lot of times I'm running downstairs, seeing what I can find that's easy to make in a minute or two, and then running back upstairs. And so sometimes that turns out to be popcorn or crackers or something little, or if not that, then something that at least isn't all that healthy for me to eat. Uh, the other issue I have is that I've been eating keto for my diabetes and it really makes a major difference for me as far as my ability to feel good if I'm eating well versus eating stuff that I shouldn't eat. And so, um, I was looking around to try and find something that would work out for me and I found these factor meals. Now factor is great because a, they're healthy. They actually had a keto, uh, line that I could get for my stuff. And that made a major difference for me because all I had to do is pick it up, put it in the microwave for a couple of minutes and it was done. Um, they're fresh and never frozen. They do send it to you in a cold pack, it's awesome. They also have a gourmet plus option that's cooked by chefs and it's got all the good stuff like broccolini, truffle butter, asparagus, so good. And you can get lunch, you can get dinner. They have options that are high calorie, low calorie, protein plus meals with 30 grams or more protein. Anyway, they've got all kinds of options. So you can round that out, you can get snacks like apple cinnamon pancakes or butter and cheddar egg bites, potato bacon and egg, breakfast skillet, you know obviously if I'm eating keto I don't do all of that stuff. They have smoothies, they have shakes, they have juices, anyway they've got all kinds of stuff and it is all healthy and like I said it's never frozen. So anyway I ate them, I loved them, tasted great and like I said you can get them cooked. It says two minutes on the package. I found that it took it about three minutes for mine to cook, but three minutes is fast and easy and then I can get back to writing code. So if you want to go check out Factor, go check it out at factormeals, head to factormeals.com slash JSJabber50 and use the code JSJabber50 to get 50% off. That's code JSJabber50 at factormeals.com slash JSJabber50 to get 50% off.
This episode is sponsored by Kendo UI. Kendo UI allows you to build better apps faster. They have a comprehensive library ranging from data grids and charts to buttons and sliders. Plus, you can use their components as plain JavaScript as well as in Angular React and Vue. They have a large collection of customizable popular themes like Bootstrap and Material. Go check them out at javascriptjabber.com slash kendo UI.
AJ: Hello, hello, welcome to JavaScript Jammer. I'm your host, AJ O'Neill, and today on the show we have Greg Whitworth.
GREG: How's it going?
AJ: We also have Amy Knight.
AIMEE: Hello from Nashville. It sounds like we have a new host.
AJ: And I'm your host, Alvin Alexander O'Neill Jr. Senior Esquire of the O'Neill Estate the 3rd.
AIMEE: Oh my God.
AJ: No, not your God, just your host. Alright, anyway, so with all that shenanigans out of the way, Greg, why don't you give us a little intro about who you are, what you do, and then Amy will actually kick us off with the questions because she's got them hot and ready.
GREG: Yeah, I work on Microsoft Edge HTML, specifically layout, and the layout team. We own pretty much everything from CSS cascade and parsing through building up the layout boxes before I pass it on to the render team who owns painting and stuff. So that's kind of where I live. I'm on the CSS working group involved with the Houdini task force as well. So that's kind of me in a nutshell.
AJ: Oh, that's way cool. So what is the Houdini task force?
GREG: So everybody that uses JavaScript DOM APIs. It's kind of like an overloaded methodology. We allow you to do like get CSS styles and all kinds of things from the DOM. But it's actually the worst spot for you to get that information from, because a lot of times it requires us to kind of flush the pipeline. And so the Houdini aspect is basically, hey, we now all kind of have similar engines and similar aspects, so why don't we give them JavaScript hooks at those points rather than via the DOM, where it then has to go all the way through. So it's very early stages. Some of it is not like even the V1s of like the Paint API, for example, what it basically is allowing is, I don't know if you've heard of the Extensible Web Manifesto, but it's really trying to buy into that premise that the standards bodies, while we all have a lot of knowledge, we also aren't on the front lines developing websites all the time. And so while we know a lot about how browsers work and how to implement things, we don't know necessarily the best things to standardize. And so this just gives a web developers much more performance hooks to be able to go create conduct gradients or any number of things. We basically have like the paint API is one that's actually you know, in a working draft. The layout APIs are actually very close to being complete as well in regards to the working draft. There's still a long ways to go. And they also definitely don't offer me this, the same capabilities if you were to come right in C++ and one of the engines, but it's a great process and along the way, one of the things I'm excited about is how covering all of these things that web developers have always hated that are helpful no matter if you're going to go write those things or new layout types or painting APIs. For example, like one of the ones I'm excited about that hopefully we'll get to work on the next year or so is just the parser API. Just because we all have parsers in our engines, but hey, if you're a JavaScript developer and you want to understand the you know CSS you have to go roll your own parser, which makes no sense. And, and the typed OM is another one, you know, Hey, I got these styles from this DOM element and it says 25 pixels. Well, now I have to like, you know, to explode that string. So I understand and convert that to an end. So it's 25. So I can do some math on it. The typed OM now actually takes all that CSS and builds an object model that actually has types. So you can actually say, you know, I just want you to add these two things together because they're already integers. Um, so it's just wonderful things are coming out of it, uh, know, extensible web manifesto kind of purpose.
AIMEE: So what I've heard a lot of people compare it to just kind of at a very high level is like we have Babel for JavaScript and this is going to kind of enable some of the same things that Babel does, but for CSS now at a high level.
GREG: I actually don't use Babel much. So like if I recall correctly, Babel basically, if you end up doing like, it allows you to write in like ES6 or ES2017 formats and then it'll transpile it down to lower level, correct?
AIMEE: Yes.
GREG: Yeah, so it's kind of the, I guess somewhat, but basically what it allows you to do is let's say, hey, This is actually a really good example with the layout API. Hey, I want to be able to write my own Pinterest type layout where it's got that stacked columns and stuff, and everything fits nicely. This will then allow you to go and do that, and much more performantly than if you were to try to do it now with absolute position on DOM elements and doing all the math yourself and stuff like that. And then you then can just roll that as a library and it can even be used by everybody else in just regular CSS using custom properties. And then it'll just kind of work everywhere. And then as the standards bodies in the CSS working group, we see this take off, and it's used everywhere, very similar to jQuery. And all of a sudden we can say, okay, well, let's go standardize this. We actually already have an implementation and we can even look at what's most commonly used and standardize those and then go implement them in C++ and heavily optimize those.
AIMEE: Awesome. I want to back up a little bit and I invited you on, I guess you had, I did an episode for the Shop Talk show where I kind of went through this talk I've been giving that the stuff that you've been talking out about and the stuff that I've been talking about parallels a little bit. But for people who are not familiar, can you kind of take us back to basics a little bit and i think even like some beginner developers probably are not aware that the JavaScript engine and the rendering engine are separate things. And then also you talked about the CSSOM. Can you talk about what the CSSOM is? So two questions there.
GREG: Yeah, so by the way, I love that podcast. And I love that you took the time to go do that because so many JavaScript developers don't take the time to go figure out what CSS is doing and understanding the rendering pipeline in general. But to your point, yeah, every browser has a separate JavaScript engine and it's like its own got its own pipeline. It's got its own ways of working. I was about to use Microsoft terminology and be like, imagine it's its own DLL.
AIMEE: Yeah, like it's even interesting to me that you work on a separate part of the rendering engine. But anyways, I won't go down that rabbit hole that you finish.
GREG: Yeah, yeah. So what ends up happening is there's from a high level, basically what ends up happening is there's the pipeline, if we're gonna like simplify this, is basically there's networking, then there's a parsing and a DOM structure, basically all the content is built up. Then we go through parsing and CSS styles, and we cascade, we build up the layout box tree, then we move that onto painting, and then finally rendering and compositing. And so that's kind of the steps that it goes through. And so the CSSOM is actually built up after parsing. That's actually when the CSSOM is created. And basically, that's what you end up seeing if you do.style on something and you read something back. That's actually what you're looking at, or you do get computed style. That's, it's in that same object. And that's basically what it is. And that's initially created at parse time. And I forget what your other question was.
AIMEE: So you kind of answered that. So I wanted to make sure that people were clear. They understood, you know, we have the.. the JavaScript engine and then we have the rendering engine that's responsible for parsing our HTML and CSS. So that was like point A and then point B, at least for me, the first that I had ever heard of the CSSOM or CSS object model was when I started digging into this, I knew about the DOM, but I didn't know about the CSS object model. So you did answer those two questions.
GREG: Oh, okay, cool, perfect.
AIMEE: So I guess, you know, a follow up question to that, which is what I was kind of starting to go down this rabbit hole about. So now that we were like talking about just the rendering engine specifically, can you kind of talk through from the browser's perspective, um, at least for edge, since that's what the team that you're working on, you know, we have layout paint and composite and those, it sounds like those are three different teams on edge.
GREG: So it. It's it's it gets very fuzzy because yeah, because I mean some things we end up having to pass off to other teams because they handle like for example animations and that's primarily on the compositing side. Slowly for the reasons you've highlighted in your talk and in your discussion on shop talk. But we end up doing all the parsing and and stuff of that nature and there are separate teams and that's kind of very similar across all browsers where they end up drawing that line is a little bit different, Because it takes very different skill sets to truly, really know layout and truly, really know like painting and rendering and all the optimizations that go into each because browsers are really complex. So you rarely have something that's just kind of spanning all of them at a very deep level. You may have somebody that's like architectural lead over many, but so yeah.
AIMEE: So I have my own thoughts on this, but I'd be curious about yours. Because we're on a JavaScript podcast, why is it important for us to understand not just how the JavaScript engine's working, but how the rendering engine is working if we're front-end developers?
GREG: That's a great question. I think it's really important not necessarily to know it at a really deep level, but I think it's important to at least understand what the engine is doing, kind of like what I was referring to earlier of that pipeline, just so that you're making the wisest decisions you can. Like you may ultimately end up in that situation where there's no other route, but to do custom layout in JavaScript, because, hey, your designers and your business stakeholders have defined, hey, this is how it has to look. And unfortunately we can't accomplish that with CSS grid right now or some other manner, but it's important to know that so that you're not writing, you know, JavaScript that is actually crippling your users experience. A good example of that, and it doesn't even have to do with layout, is if you were doing a set timeout and you were calling this method faster than the monitor can even paint. And that's where Raph actually comes from for those that don't know request animation frame, which is basically, hey, there's no sense us using CPU cycles and trying to paint something when the monitor can't even do it. And so I think it's really good to kind of understand how the engine is working so that you're writing your most performance code. And that's the case with CSS, JavaScript, it really doesn't matter because at the end of the day, a lot of times the engine is better at understanding the hardware that we're on. And we do a lot of work to make sure that, hey, if you're on a HoloLens, for example, where we only are given so much RAM or GPU capabilities, we need to make sure that we utilize that correctly. So you're not gonna be able to test every single so if there's a good API for you to be able to hook into and allow the browser to then say, okay, well, we know how to optimize this away where we're running. It's best to give that control back to the browser if possible.
AIMEE: So another point to this too, and hopefully this is something that you'd be able to speak to. Part of the reason that I decided to dig into this topic was because it's kind of fascinated by I came from you know, feeling pretty good about JavaScript and went to this front end role where I felt, you know, like my CSS skills are pretty poor. And it was interesting to me as I was working alongside what were in my mind, some really great designers who really had a mastery of CSS. There's tons of times as a front end developer where you're asked to implement something and you could implement it in JavaScript or you could implement it in CSS. And so as somebody who works on the rendering engine, can you kind of talk about when people might reach for JavaScript when CSS is actually a better option?
GREG: Yeah, that is such a common problem, unfortunately. So we do too.
AIMEE: Like I know for me, like I reached for JavaScript when I started this journey, like I reached for JavaScript probably 99% of the time. And slowly realize that a lot of times CSS was going to be easier or less code and more performant.
GREG: Yeah, there's a, we actually, we meet with a lot of partners, you know, big, small, and usually they're just, it starts off as, hey, we found a performance problem. And usually we kind of have to untangle that and like work backwards. And we end up noticing, hey, why are you doing custom layout, you know, for this nav menu, for example, and they'll be like, oh, well, we had to, because there was no other way around it. We had to do custom layout. And usually what we just come back with is the second that you start involving JavaScript, and it primarily, some of it is the platform's fault, which we're trying to, Houdini is a good example of, is you're going to be slower. The second that you start doing things in JavaScript custom, you're going to be slower than areas where we have heavily optimized. We know the most common patterns. We know specifically what Grid and Flex are trying to do, so we can to some extent take shortcuts. And sometimes the inverse is true as well. It's really hard to just make a black and white statement of always just use CSS or always use JavaScript. But CSS, probably nine times out of 10, if you're able to solve it with CSS is going to be more performant. Because we know, hey, we know I've done the optimizations to do like partial layout. Hey, we know where the hit testing occurred. Whereas a lot of times you're gonna be listening to events in JavaScript. And so you're like, oh, well. they clicked this thing, so let's go do our logic and make sure something didn't change. We know exactly what changed in the tree, whether or not it should or should not change, and then go run through the logic of updating the trees as necessary, recomputing styles if they are or are not needed. It's just, it's one of those things where we have, you know, roughly 20 years of optimizations built in, whereas a lot of times JavaScript developers are kind of rolling their own at that moment, and so they don't necessarily get the benefits of that.
AIMEE:Definitely. So
AJ: So can I back us up for a second? Because you guys have mentioned these layers several times now. But what the heck are they? What? Paint and render and composite, all that? Can you give me the 15 second, 30 second overview of each of those steps?
GREG: Yeah, so I tried to go through it quickly, but just I guess to dive into it a little bit quicker. Basically, there's the DOM. And that's where the DOM will go through and they'll take all that HTML, they'll parse it out, and they'll build up the document object model, which a lot of JavaScript developers are really well aware of, and basically make it so that all the elements have everything hanging off of them that you're expecting them to be there.
AJ: So I feed the browser HTML, that's a text file, the browser turns the text file, the HTML, into the DOM. Has a weird name, but it's the same thing. Okay, got that. Continue.
GREG: So and right now I'm solely referring to the rendering engine. I'm not jumping into, for example, in EdgeWave Chakra and Chrome the FBA. I'm not jumping into, for example, them opening up and jitting and doing all their wonderful JavaScript stuff. But then after the DOM is set up, basically, we then go on and start, hey, now that all the elements are there, we can start hanging styles off of these elements. And we'll go through. We'll parse all the CSS out order them according to you know specificity as well as the the origins that they're from and then finally origins.
AJ: What do you mean by origins?
GREG: So this is actually one that's not commonly known by web developers but there can be for example user style sheets there's author style sheets and then there's UA style sheets so the most common one web developers are used to is hey I need to reset the browser styles and that's because we have our own styles baked in to have like an input element look a certain way. And so the web developer then writes a style, and those in and of themselves are ranked accordingly. And then once you're into the web developer styles, for example, then specificity comes into account. And a good example of where this is affected, if you happen to be on a Windows machine, you can also see it probably in on Mac as well. If you turn on accessibility capabilities that change like the colors or something of that nature. In Edge, at least, what we do is we actually use CSS to do that. We use this logic of origins where we end up taking, hey, the origin for the user has said high contrast needs to be turned on. And so their origin of being a user wins no matter what the web developer set those things to. Because at the end of the day, the user is king. And that's where the origins come in. So you have UA. web developer and then user.
AJ: So that, I don't want to sidetrack us too much, but you've piqued my interest.
GREG: Yeah.
AJ: So if the user has high contrast on or something like that, and the webpage is supposed to be, you know, say black on white, is the high contrast going to override and make that white on black or?
GREG: It solely depends on what the user selected because we have multiple themes and they can even create their own It's solely what they end up selecting. So yeah, and I actually have a complete blog post on this because we also have CSS properties, MS high contrast, where you then can kind of control this. But I have a blog post on it solely because of the fact if somebody is using that, it's kind of, the design has disappeared. The design, it has nothing to do with your design at that point. It's all about the user experience. So if you're testing out your site in high contrast on Windows, somebody is using that just so they can consume their content better. And so we also offer you color keywords. So if you want to be dynamic and say, okay, whatever they selected for the foreground color, use that here. I don't really care what that is, but I want to like make sure that my style looks consistent and you can then do that. I have examples on that blog post as well.
AJ: Oh, that's interesting. Yeah. Please link to that. Cause I think, I think a lot of the listeners would, would like to hear about that.
GREG: Yeah, that's a good example of one we've tried to get standardized, but it's really hard cause it's OS specific. And we're kind of hopeful that Apple proposed, I think roughly a year ago, because of their new iPhone 10 with that notch, they wanted environment custom properties. And so we're hopeful that we can get some of those things back in there so that there's a standard way rather than using the MS properties. We just gotta get around to standardizing it.
AJ: Okay, so we've got HTML goes into DOM, CSS comes from three different sources, the user agent, the browser default, the author of the site and then the accessibility agent or accessibility profile.
GREG: Yeah, like you had it right, let's leave off the accessibility agent because that's actually like, that sounds kind of like a term for, there's accessibility tools that actually are referred to that.
AJ: Oh, okay, so that's different thing, but. A user style sheet, a common use case of that would be an accessibility tool would turn that on.
GREG: Yes. Exactly.
AJ: So those three get parsed and then they get attached to the DOM. Now we're at the point where what do we do next?
GREG: We cascade them all and we figure out which rules win via specificity as well as origins. And then once we're done with that, we take those styles and we hang those off those DOM elements. And so now, hey, that DOM element now has style with it. And so we have...
AJ: What is this called? Is this still a parsing phase or is this?
GREG: No, that's the cascade.
AJ: This is the cascade phase. OK,
AIMEE: is this now when you are when you're saying like hanging them off? Is this now the render tree?
GREG: Not at that point. No, that's actually going to be the next step. And so yeah, we've now we hang those like you know if you're in JavaScript, you do element style. Basically that's what we've just accomplished. That information is now hanging in there. We've created the CSSOM. That stuff is now available to us, but we don't have boxes. We don't have sizes. There's nothing to paint yet. That's kind of where we're at.
AIMEE: Perfect.
GREG: And so, yeah, once you have that, then it's time to go do layout. And basically what ends up happening at cascade time, you end up trying to compute everything down to auto, a percent, or an actual number, or its keyword. If it like, for example, display grid. Obviously, that doesn't need to be computed, but the computation you try to get to percents auto or an actual value, a pixel value. And so when you go into layout, at that time you start just walking down the elements and you start producing boxes for them based on their styles. And this gets kind of complex, and that's where like going back to my talk where I actually walk you through this with visual examples is kind of helpful because you can see, okay, yeah, there's the styles hanging off the DOM elements and okay, we're gonna create a grid formatting context. And then it goes down to its child boxes and starts constructing, resolving all the math and geometry that it's allowed. And then in your case, yeah, we'll go ahead and finish this thought here. So yeah, we go through, we size, we position, we place all the boxes in certain areas. And that is the render tree of what you're referring to. And we then pass that on to painting, where they go and they actually paint just a bitmap, like if you were to open Canvas and paint a bitmap of that now it gets more complex like you got into Amy in your talk where we end up having different layers and some of them may end up being their own, just own bitmaps because we want to optimize that away so the compositor can do work. But if we keep it simple, hey, there's one bitmap and then the render part of the pipeline passes that off to compositing, which then truly smashes it all together and puts it on the screen for the user.
AJ: So during the paint phase, I could consider this in my mind like, one of those like movie style blowouts where there's 30 pages laid on top of each other and each one represents an element and then the composite phase they all squish together and get the opacity or they don't.
When you start a new project typically you need things like a domain name, hosting, things like that. When I choose hosting I pick mine for the options it gives. I like to know what I'm getting and set things up just how I like them. This is why for your projects you should check out Linode. Linode servers feature native SSD storage a 40 gigabyte network and Intel E5 processors. That's all the power you need to run VMs under full control or Docker containers, who doesn't love that, encrypted disks and VPNs. Plus they have 10 data centers across the world and add-ons like backups, node balancer and long view to help you control your server costs. They also offer block storage for your static files and you can get started with a $20 credit if you use the code Java That credit is good for four months on their one gigabyte server that's a lot of time to try them out and see if they're the right fit for you. That code again is JavaScript Jabber 2018. Also, if you're interested in working for Linode, they're hiring. Head to Linode.com slash careers to see their available positions.
GREG: Yeah. The way I've always thought about it, if you've ever used any program that is a paint program, for example, Photoshop and you create numerous different layers. Technically you're painting everything there, but the paint phase is where you kind of like right click and you rasterize all the layers together and now they're smashed. And so whatever is top most is visible. And then compositing then just puts that on its own layer and renders that to the user. Where things get interesting is, for example, Amy was alluding to some of the optimizations you can do in CSS, for example, is we can then see certain properties and say, for example, if you set a will change on something, we can then say, okay, well, we're gonna take this area. And we're not going to paint it along with this other one because we're going to paint its own bitmap. And now we're going to produce, we're going to call into the composition engine and we're going to say, hey, actually create two layers. Here's the bitmap for this one. And so then the composition engine isn't having, we're not having to go through paint over and over and over again, for example, for an animation. And that's a good example of where if you were in JavaScript and you're sitting there on RAF and you're trying to do animations via JavaScript that has to sit on the UI thread and you're trying to move this box via, again, Dom APIs, and you're like, okay, well, let me see where it's at, let me set it, let's keep moving, we'll keep this for loop going, and it's gonna be almost impossible to get 60 frames per second out of that.
AIMEE: Yeah, so to kind of like take a step back and review for a second for listeners, so, and correct me if I'm wrong, but it's my understanding that in order to run, Like these are all contingent upon each other. So layout, paint and composite. So if you want to speed things up, you know you would want to try to only trigger composite. Your next best bet is to trigger a paint and composite. And then worst case would be if you have to run layout because then you have to do layout paint and composite.
GREG: Yeah, that's, that's exactly it. Like, so we parallelize every, every browser does like crazy. We have numerous threads for numerous different things. But yeah, at its simplest, even though they may be on separate threads, they have to come back and start talking to each other and sync up. So then that's usually called the main thread or the UI thread, depending on who you talk to. And they all do have to follow each other. But that's, again, where you just had a great example of where you're able to bypass. We have optimizations built in. For example, one of the ones I use in my talk is, hey, one of the things that can invalidate this pipeline and cause it to flush is user input. So if you take a very simple CSS aspect of colon hover, what you end up – if we remember the pipeline that we just went through, at the end of the day, we literally only have a picture. It's not actually interactive. It's just a bitmap. It's like a picture if you were to take off the wall. That's all it is. And so now we have to give the illusion of when you moused over this thing, stuff happens. Okay, so how do you do that? And we end up having to go back. The hit testing algorithm has to occur because we need to know where the cursor is and we need to figure out what elements, it's not actually elements, but which boxes under the render tree those are. And then we have to say, okay, are there any styles associated with this that may change? And sure enough, there are and we would let's not get complicated. I was going to say if there's event listeners, okay, anyways, but like we then say, okay, there's styles have to change. We go down to style and we recompute those. And let's say they're only changing the background color. Well, we go. We know for a fact we don't have to do layout. That's a paint only change. So while yes, they're dependent on it, we go, hey, we know we only have to paint. So we're gonna bypass layout completely and we're gonna go paint and then hand that back to the compositor to render to the user so that we go as fast as possible. And that's not to say you couldn't accomplish that in JavaScript, it's just, again, you're leveraging what's already there rather than rewriting it yourself.
AJ: So when I hover over a button and it goes down and to the right by one pixel to let me know, well, maybe that's not what I'm hovering. Maybe that's why I'm clicking, you know, goes down into the right by one pixel, let me know this is actually being depressed. That goes back into the layout phase because it's changing position.
GREG: It depends on how you're doing it because you could achieve that same effect just via changing like painting. Because you could be like, hey, the border is actually now two pixels on the top and the left and the bottom is two pixels top to the left and the border is always there at that size. And so you're giving the impression that it's moving down to the right but it's still only a paint effect.
AJ: Yeah. And so we're a gradient.
GREG: A gradient is a good example of hacking that. And but what you just described is exactly why the pain TBI exists. Because so many people are like, hey, when I click on it, I wanted to do this crazy like bubble thing. And I want it to be where the cursor is, and all these things that are like, very hard to go standardized and then implement and all these things for a lot of times, very specific needs of the web developer. And that's precisely what it gives you gives you a canvas context. And it basically says, hey, when this thing happens, go run that canvas JavaScript stuff I did and put that in a bitmap and render that. And so your thing would be very simple to do in a canvas context and guarantees no layout is occurring.
AJ: I noticed recently, I don't know how recently, maybe this is years ago, but to me it's recently, there's now a hidden property on elements in the DOM that seems to accomplish the same thing as display block versus display none, where if hidden is there, It seems like it's the same as display none. Do you know why that is? Is that like a performance thing or a convenience thing or do you know anything about that?
GREG: To be completely honest with you, the only hidden I've ever used on an element is the one on inputs to pass information to the server side. So I actually don't have an answer for you on that.
AJ: Well, just open up your F11. What's it called? F10, F11?
GREG: Oh yeah, it's F12.
AIMEE: F12,
AJ: F12, sorry. Yeah, you just open up your F12 and right click on an element, type hidden, it just disappears. It's pretty cool.
GREG: Sure, yeah. No, that is, that is, that's... Yeah, I don't have a clue when that... Again, that's a good example of where it's a completely different team. And so they probably went in there into the engine and added some styles, and at that point we actually don't care in our part of the team. It's like, did we not paint it and everything? Sure, cool So we did our job. So did you have a question about that, Bill?
AJ: Yeah, the thing I'm wondering is the difference between, let's say, I remove an element is one way of doing display none. I actually say, you're no longer in the DOM, which I'm pretty sure would cause a, the whole process would have to go through again in the naive implementation. But if we're saying the element's still there, but we're not going to display it, layout doesn't change. And I was, I was wondering if like the thought occurred to me, maybe this whole thing with hidden is so that it like it's a signal that this only occurs in the last step. Don't do any of this other stuff. Because, like if I you know, as a developer, you have different ways to choose to make the same exact experience come about. And I'm guessing that, you know, like you've been saying depending on what you do in JavaScript versus adding or removing a class versus adjusting a style, you're going to get a different effect on how it changes the render process and the layout process. And I call that whole thing render, perhaps mistakenly, but that process.
GREG: Yeah. No, you're correct. It's actually in spec terminology we refer to it as the rendering pipeline. You're right. And Yeah, looking at it, I would expect that's doing the same thing as display none. And to be completely honest with you, probably under the hood, that's exactly what's happening. We're just setting in line styles on that development because we do that all over the place. It's one of those. That's actually a good example of where web developers like we make like the engines are really complex, but a lot of the stuff does work exactly the way you would expect. So we probably just set on that element, hey, you're displaying none so that we don't have to do any other work down the down the rest of that pipeline. But yeah, like to your point, there's a lot of ways of getting content out of the, to the visual user. But one thing like I really want to stress is while to Amy's point, opacity would be faster. It's always important to take into account the accessibility implications. And unfortunately, I can't speak for like all engines on this because we have UIA, a lot of people have IA2, it's a different accessibility things that they map to and different stages in that implementation. But that's always something to take into consideration because if to the end user it's gone, then you obviously want to make sure that it's also gone to the accessible user.
AJ: Interesting.
AIMEE: I want to talk about, as we're talking about layout, paint, and composite, let's drill down a little bit further into layout. Can you talk about for people who are not aware how stacking contexts work in the layout process?
GREG: Yeah, so stacking contexts, just so that we're on the same page, technically occur at the painting stage, and it's on the same tree. And so what ends up happening is stacking contexts just change the order in which we paint. And so if you've done any computer science, you're kind of used to traversing a tree. And what that ends up doing is, You go from the top of the tree down to the bottom of the tree following regular painting order by default. So basically, you start at the parent, walk down, keep painting, and basically that ensures the back, the content is over top of the background, all that kind of stuff. And what the stacking context allow you to do is, hey, if I, for example, set z index 2, and this other box is z index 1, maybe the one that was now set to two should have been painted later. It creates a new stacking context and the paint algorithm will now go to that one after the Z index one. And so that allows that Z index two to now actually be painted on top. And this is actually a good example. When I first got here, I met with some of the people that were on the compositing team and was like, no, but those are, cause they would keep referring to layers. And I was speaking regarding z-index, because as a web developer, it gives you this feeling of having control of layers. When in actuality, it's not. You're solely painting the same pixels. You're just painting over the pixels. And so-
AIMEE: So the pixels are like that way.
GREG: Exactly. And so it would be as though, like if you just took a canvas context and you had two areas that wanted to consume the same pixel, whichever one painted later is gonna have that pixel. And that's precisely what occurs in the engine. And so when people are, browser engines are referring to layers, they're usually referring to compositing layers. Um, so yeah, and I, in, in my talk as well, I have an example of that where the stacking context show two examples where how stacking context affects paint order. And this gives you that capability of feeling like you have control over content over top of another content. When it actually, you're just filling in pixels in a different order.
AIMEE: interesting man my brain is like going to something that that's super deep that way i won't go into it
AJ: okay uh well i have one more question that may not be in your wheelhouse but i've noticed i don't know if it was like on twitter or something but it just it sounds like there's more people interested in doing styles in javascript um and i've i've heard like from people i think they're more like novices in the React community where they're just like because it's easy and they don't have to open up two files. They can just have one like they have all of their HTML and all of their JSX and all of their style all in one single page. Is is is this is this okay or is this bad to try to do styles that way?
GREG: I actually really appreciate bringing that up. That was one of the one things I definitely wanted to talk about. And it goes to my earlier thing. And this is why web development is good and bad at the same time. It's really hard because I never want to make a blanket statement. Because I've worked with a lot of partners where being the CSS team, we go in and we go, why on earth are you not doing this and using the cascade and you're trying to bypass it and all those other things and we would have been much more performant had you not been touching those DOM elements or whatever But I but it's it's always important to go back and say why are they using it and I think that's one thing that You know, I've at least tried to you know, really Understand is and it almost always comes back to manageability I don't I think some people reach for it because it's what they know and they're comfortable with JavaScript But I think that there is an important problem that it is solving and it's a completely valid problem of, hey, I want to ensure and test and make sure that this thing is working the way it is. And right now JavaScript tooling is remarkable at that. And it gives you a great capability of saying, hey, these styles will always be here. We won't regress anything. We're not inflating our CSS styles, you know, by like 7 trillion and making the cascade do all kinds of work that it doesn't need to. It's actually a great example of, in a lot of ways, you'll be really performant that way. One thing that I'm super excited about, and I can't wait to see it kind of take off, and this is kind of approaching the same problem but from a different lens by somebody who really, really knows CSS really well, Chris Epstein from LinkedIn Engineering, that I don't know if you all have seen it, but CSS blocks. And I think the thing that I'm really excited about is it looked at the problem space, and this is why CSS is so hard to debug, and CSS is so hard to manage, is because of the fact it's right in the middle. Like it depends on DOM and then it produces some stuff after the fact. And it's really hard to keep track of that because of the fact that you have to have the DOM or else the CSS by itself means nothing. You have to have them together in order to do, you know, selector matching and to actually then render something. And CSS blocks is great. It's a, it's a, it's a large buy-in similar to, you know, switching to react or switching to view or any of those other JavaScript frameworks because you end up having to set up your HTML code following CSS block like template language. But the beauty of it is once you decide to dive in and take that, you can then say, OK, I want you to tell me whether or not I have CSS that is being unused. But you can write it just using SAS or regular CSS, any of that stuff. You can do it your own regular way. But because of the fact you've bought into that, it then is able to tie the DOM to the CSS and be able to give you that answer. And that's primarily what's missing is that because it depends on the DOM and the selectors have to look at the DOM, you can't just do static analysis of just CSS and say, hey, tell me what's unused because JavaScript can affect it. The JavaScript can come in and add a new element. And now the selectors technically do match that. You know what I mean? Because it's right in the middle, it's a really hard thing to debug. And that's, to me, one of the main problems that JavaScript based because of the fact that they don't understand and can't manage specificity within their team. And by adopting one of those,
AIMEE: yeah,
GREG: you end up being able to control that really well. And so the one of the negatives though, because I've had a lot of meetings with folks because they end up going, well, now that we've got control of the specificity, we've now lost the capability of pseudo selectors and, you know, colon hover. And so now we're doing more work.
AIMEE: Yeah, I do fear like sometimes that is used as an escape hatch instead of understanding how specificity specificity actually works.
GREG: Yeah, and again, it's one of those things that to some extent, you can come back and say, hey, solve that. And we actually do. Leah Rue actually approached and it's one that I've kind of toyed with. She actually had a much better proposal, though, but it's basically a function that ends up giving you the capability of nullifying everything within that CSS selector to have zero. So it's one of those things you can then use it to select, but you're not creating a more specific element. And so it's a little bit more verbose, but it's kind of an infancy. But it again is trying to solve that problem. Like if you're a developer that is putting an entire build process and all these other things in place using React and View solely to nullify specificity, then this may be a good out where you can now use this. And you can make it so that other people can consume your component using raw CSS without necessarily having collisions and other people needing to learn your specificity or following BIM or some other naming schema. So yeah, I think that there's a lot of legitimate reasons why people reach for those. And I don't ever want to just flat out shame. It's one of those things where it'll depend on each team arm yourself with the knowledge of at least what the rendering engine is doing. You don't have to dig in real deep or say, hey, I want to go join the CSS working group or anything of that nature. But if you start understanding what it's doing, you can then make a very informed decision of whether or not to do custom layout or anything of that nature. And one, I actually had a talk with a team at Microsoft and we were investigating things and there was this performance problem that they were having. And I ended up just flat out saying is there a chance we can just get the design team in here? Because I really want to know if what you all are fighting against is worth the design. And sure enough, the design team was more than happy to say, oh, yeah, we don't want it to be, you know, eat 400 milliseconds solely to achieve this one little look if you can't make it work across. Because they basically had to support some lower IE versions and stuff like that. And so it was like, yeah, we can come up with a different one that will work across browser. And I think a lot of times, web developers don't do that. They don't say, hey. Yes, I can achieve this in JavaScript and it's eating up 400 milliseconds of my time, but was making it look exactly like the designer wanted worth that 400 milliseconds.
AIMEE: Very mature approach to it.
AJ: So I've got one last question for you, which is when does it even matter? Like whether I'm taking so many milliseconds or whatever. I mean, is it. Is it because I care about how much battery the person's using? Do I actually need 60 frames a second? Like when do these these things matter other than like, I think everybody should know it because it's way cool to know. But when does it matter?
GREG: Oh, goodness, that's a really broad question. Like, I would say it almost always matters, solely for the reason that at some point, you're gonna end up in this scenario of where you're working on a team and it's not your own personal website where you actually don't care about the demographics and the clients. The one thing that we always try to push with folks is... With Microsoft Edge, we ship on so many different devices. We ship on IOTs that have very, very low memory capability. We ship on HoloLens. We ship on Xbox. We ship on tablets and really hardcore PCs as well. And so it's one of those things that it actually really drives me crazy when web developers sit on their high-end laptops, Macs, it really doesn't matter what device, and act as though that's everybody's bar. In most cases, especially with the proliferation of mobile, it's really low. And so I almost would love for the default to be, hey, is that like question every single UI thing? The second that you say, oh, well, the only way to solve this is reaching into JavaScript. That better be serving a very, very, very important purpose because you will be impacting your user's experience because you're gonna have to bypass optimizations. And so basically have that business discussion. Is this going to earn us an extra percentage improvement on profits? If it isn't, then it's probably not worth the performance hit. To me, that's why it's very important to know as much of this as you can. Solely, again, just so you can make an informed decision because you can't make that informed decision of whether it's worth it or not solely on the business because you can't say, oh, well, I know that this calling get bound in client racks every single ref and forcing layout to know where this is and doing layout thrashing, to insert and re-analyze stuff, solely to achieve your experience is worth it. So I think it's really worth knowing how the rendering engine works. And there's more and more browser developers and engineers getting bugs back. And it's solely due to the fact of abuse of the engine. And then on top of that, the platform not providing the right hooks. And thus, unfortunately, for the web developer to solve the problem, they had to abuse the engine. So yeah, it's kind of like getting your role changed, I think. Not everybody needs to be a master mechanic,
AJ: but. Well, one last comment. I've noticed that you keep on saying RAF over and over again. That's request animation frame. Is that what that stands for?
GREG: Yeah, sorry about that. Yeah, it's short term. I apologize.
AJ: No, it’s Ok I'm trying to catch those things to help out with listeners and I actually didn't know what that one was, but I kept hearing it. And then I realized what it was and I was like, Oh, anyway. Well, I think that's time. And I'm really glad that you are such an experienced and knowledgeable person and you and Amy both have done so much research into this. It's been a great show. Before we close up, we do picks and hopefully you were informed of that. If not, we'll have Amy go first and she'll show you how it's done.
Do you run your own freelance business? Or maybe you're thinking about picking up some business on the side. Well then you need FreshBooks. FreshBooks is the quickest and easiest way to get invoices out to your clients. It's easy to use, it works anywhere, available from any device, on the desktop, iPhone, iPad, Android, and all of your data is backed up and secure. And it makes it really easy to get organized and get paid. You'll be tracking time, logging expenses, and invoicing your clients in no time. You can also save time billing, freeing up several days per month to focus on the work that you love, and you get paid faster. FreshBooks customers are paid, on average, five days faster because there's a link on the invoice that says pay me now. And it's a great way to grow your business. Plus, FreshBooks is offering a 30-day trial. That's right, 30-day trial if you try them out. So go to gofreshbooks.com slash dev chat and enter dev chat in the how did you hear about a section. Once again, for a 30 day trial, go to gofreshbooks.com slash Dev Chat and enter Dev Chat in the How Did You Hear About It section.
AIMEE: Okay, so I am actually going to pick Greg's talk because I thought it was an excellent talk going even deeper into the stuff than I had and I learned a lot from it. So that's going to be my first pick. And then my second one, speaking of conference talk. This looks like an older blog post that I stumbled upon this week by Sarah May on, it's just called What Your Conference Proposal is Missing. And that will be my second pick for today. And I will cut it short there because the internet here is really bad.
AJ: Alrighty. And Greg, would you like to share some picks?
GREG: Yeah, I definitely would like to second Amy's Shop Talk podcast because I think it's a great example of a JavaScript developer coming and learning CSS and how to debug it. I think it's a great thing for everybody if you're primarily a JavaScript developer to learn how to do and at least start getting more comfortable debugging CSS. My second one is just kind of remarkable. He's got a blog post on it and also a talk but Jake Archibald, he's from Google and he has a Tasks talk that he gave. I highly recommend all you have to do is search for Jake Archibald tasks, microtasks and queues, and he does a really good job of outlining a lot of the JavaScript aspect of the rendering engine and how it handles the tasks that you kind of set up without even realizing you're kind of setting them up, whether they be promises or intersection observers, what have you. But yeah, I think that's a really great one to look at and understand because it just, again, helps inform how the rendering engine is handling your code.
AJ: Okay, my first pick, I'm going to pick, well, kind of two things, but I'm gonna talk about it in the same go. So the Microsoft Surface has the most beautiful display. It's absolutely something that you should not be developing on for accessibility and color correctness. And well, yes for color correctness, but not for Like what you were saying earlier, everybody needs to have a $200 Dell laptop so they can test their stuff and see what the rest of the world experiences. And the Microsoft Surface is absolutely not that. And there was my wife was showing me something on it and she was in Word and there was just something that was happening that was beautiful. And I was like, what is going on? I didn't know what it was yet. And then I was like, the cursor, the way the cursor moves. So even on Macs. The way the cursor moves is it jumps from before the letter that you're on to after the letter that you're on. So whether you're in the URL bar or whatever. And I don't know if this is throughout Windows or if it's just in Word, but when you hit the arrow key over, the cursor actually gradually slides over. And if you hit a key and a new letter appears, the cursor will just slide with the thing that's pasted or that's appearing. And I just thought that that was kind of incredible. I have not seen such finesse and I don't know what the, like attention to detail in the design of the way that a cursor moves ever. And it just blew my mind and it made me wish that I had that. And I wish that I had that. So that's gonna be my two picks or the Microsoft Surface beautiful display. And then the way that Word or whatever it is, is moving the cursor. Just amazing. Thank you. Appreciate you being on the show. You were excellent. Amy, you were excellent. AJ, you were all right?
AIMEE: Excellent as well. Thank you for hosting.
GREG: Yeah, thank you. Thank you both so much. It was a pleasure.
AIMEE: Awesome.
AJ: Adios.
GREG: Adios!
AIMEE: Bye!
Bandwidth for this segment is provided by Cashfly, the world's fastest CDN. To live your content fast with Cashfly, visit C-A-C-H-E-F-L-Y dot com to learn more.
JSJ 315: The effects of JS on CSS with Greg Whitworth
0:00
Playback Speed: