 All right. Cool. So let's do this. We're going to perform a perfaudit of your Polymer app. That's a lot of words. Let's shorten that up. It's more like performing a PA of yo, PA, or we can go shorter. Anyways, let's get into it. There's a word that I want to just bring up. Slow. It's just like, it's this word. I don't love it, because the challenge with the word slow is that it's just kind of ambiguous. And slowness can be a lot of things. It's like, I heard that animating things with jQuery is slow, and a script in the head is slow. But how do you compare these things? And what actually matters more? It's really hard to pull it apart some. So is 10 milliseconds slow? 10 milliseconds in the page load of an e-commerce site? 10 milliseconds delay? It's really not going to show up in the page load. But 10 milliseconds in a WebGL, 60 FPS experience, adding 10 milliseconds to every frame is going to completely decimate the experience. It's going to be terrible. So that, certainly, 10 milliseconds makes a big difference here. So it's contextual, right? But that's not it. It's not just when it happens, but it has to do with what the user is thinking. So we've been thinking about this on Chrome, trying to come to a better understanding of how to think about performance, and slowness, and fastness. And we're like, we need to construct a nice model for this. And we went back to the 10 things. I think it's like the 10 principles of Google. And number one is this. It's focused on the user, and all else will follow. Like, OK, I like it. Let's think about how we can be extremely user-centric when we talk about performance. Cool. All right, so how do we do that? I don't know. First up, the way that we all think about performance is basically that faster is better. And just make it faster, and it gets way better. And so it's just this linear relationship between the two. But along this line, there's a few important points that happen. At the very bottom, when performance is really poor, it's bad. I mean, you load up some experience, and either it's taking too long to start, or as you're using it, it's just really having a hard time. You quit, right? You're just like, nope, got things to do. And it's a little bit faster. At some point, you're just like, yeah, that's not great, but I can deal with it. And it's bearable. Faster than that. And you're just like, everything's good. I'm very happy. It looks great. This is awesome. And then even faster than that, it could get faster, but it's harder to actually see the difference sometimes. So maybe the relationship here is not so linear. Maybe it's a little bit more like this, where we have this trough in front of everything, where basically in between this really bad performance and bad performance, it's just not good enough. And your users are going to bail. But at some point, it's good enough. And then they're happy and delighted even. So there's this area right here, kind of in the middle, where that's where you want to be. But what are the numbers? How do we quantify this area? All right, so let's take another look at this. These are the kind of numbers. And you might have seen these before. This is the result of kind of decades of research into humans and perception and response times. Basically trying to get a gauge of like, people don't need things to be truly instant for it to feel instant. There can actually be a fair amount of delay, and they still think it was actually instant. But there's all these sorts of things that were between our brain and the computer. There's kind of like some wiggle room sometimes, but there are definite points at which you change your decision. You're like, nope, I'm impatient now. I'm not gonna wait for this, you know? That just happens. So what if we kind of take these ideas and apply them to this model? So instead of thinking about kind of just what is slow, we think about what does the user feel? And that's how we've been thinking about kind of all of performance. So let's take a look at what a user might feel. So I'm gonna load up. This is just kind of like a typical journey. I'm clicking through on a search result, loading up this year's IO site. It animates in, I click on the hamburger icon, and that kind of opens up. I tap on that guy right there. Loading, animation, that's cool. Ooh yeah, this is nice. Scrolling, good. And tap on that little icon, and then it loads in. Cool, all right. So a bunch of stuff, right? Ah, but this actually, you know, here we are, this entire user journey was comprised of these more atomic interactions. You know, like I was, we were loading, and then we were like waiting, and then there was an animation, and then tapping on the icon, and then loading, waiting for the page, and then there was another animation. Like there's these individual unique things that kind of happen along this entire journey, and breaking it apart into these atomic components makes it a lot easier to understand the whole thing. So we've been thinking about these and kind of these little sections, if we kind of break them apart, there's like four of them, four categories here. There's page load. There's idle where like, you know, you're not really doing anything just yet. There's responding to input. Like, you know, tapping, clicking, something's happening, and then there's scrolling in animation. And for each of these things, we as users bring different expectations to them, and certainly have different, you know, the amount of time that we're willing to put up with for each of these things is different. So the way that we think about this is we kind of embody in a acronym, we call it RAIL. So you might have heard this. This is kind of the name of the performance model that I've been talking about, and this is a very fast introduction to it. So I apologize. But it basically ends up, if we take all these numbers from research and apply them to these components, we end up with something like this. Now, there's a lot on the screen, but the ones that I'll really highlight at this point is load, where the goal is really to have it ready to use in a thousand milliseconds, or a second. It's aggressive, but it's also doable. Over on response, the goal is from any sort of tap, any click, going from the tap to the paint, where you actually see a difference, having that in under 100 milliseconds. Hitting that means it is instantaneous to the user. So those are our primary goals, and so I wanna look at how we can kind of apply these goals in the real world, and evaluate the performance of things using this as a framework. All right, so we're gonna look at a few sites, and the first one that we're gonna look at is Reddit. All right, this is some cool stuff. So recently Reddit redid their mobile site, and so it's a really nice kind of mobile web app, and I mean, I use Reddit sometimes, and I was on it, and I was looking at this, and the image hasn't loaded yet, and I mean, none of the images have loaded yet, but I was looking at this for a long time, and I was like, what is going on? And so I had to plug in my phone, and start remote debugging, and see what is happening right now. So I did that, and when I record it, it looked like this, which is, there's a lot going on, but one thing that I'm gonna point out is, the end up here, this is 50 seconds, this is almost a minute, and this is the page load experience. And I was like, wow, and usually with a page that takes a long time to load, it's because they have a million files and network activity, but in this case, they really didn't have a lot of network activity, they just had a lot of JavaScript to run, just a lot, and I was like, okay, you know, what is all this stuff? And so, you know, start digging, start looking. So we're gonna zoom in a little bit, and I found, you know, we can kind of piece this together in four big acts, and so basically we start off, react one, then there's kind of the booting up and initialization of some things, then we really get into the components, and then we do some other stuff. Anyway, I'm not gonna get too deep into this, but it was really helpful to kind of break this apart into the primary phases here. But I still had a lot of questions as to what the work was that was going on in here, and one thing that you can do, Reddit did not do this, but one trick, this is kind of a pro tip, in your code you can just drop in console time and time end, and it'll spit into the console, but in addition to what it adds to the console, it'll add these actual measurements into the timeline and dev tools, and so you'll be able to see those kind of measurements added into the flame chart, so you can kind of coordinate what is happening in the JavaScript engine, along with what you've actually defined. Well, this is this thing, so that helps a lot, but they didn't have that, so we're looking at all this activity, and I'm like, I don't, this site is actually, the app is made with React, we're seeing a lot of this mount component, so it seems like, that's why I call it component party, a lot of stuff going on, right? And I'm just like, I don't know, but I needed a way to pick it apart. The size of the total JavaScript bundle, they browserify it, they send it down in one big chunk, it's a meg, 1.1 megs GZipped, which is, and it's 3.3 megs, not GZipped, that's like a lot, you know? And so I took it to this tool, this is a tool called disk, and yeah, I'll just bring it up, it's like, it's really cool, so basically you can take a browserify bundle, let's see if I can zoom this guy, take a browserify bundle and give it to disk, and it'll kind of visualize things. So this is, it takes up space where there's file size, kind of like, you know, when you're trying to find what's consuming disk space on your hard drive, like the same kind of deal. So actually over here, this little quadrant, this is their app, this is the Reddit, the Reddit mobile app. And then here's their node modules, a lot of stuff, Babel, the Babel polyfills, some DOM serializer, this green sock, for animation, 100 kilobytes, and actually while they tried to do some animation, it was happening in 40 seconds worth of JavaScript and you never actually see anything, so that was one opportunity. Here's Lodash, there's a React down here, and actually there's another Lodash inside of here. Yeah, so it's just like interesting, you know? The fact that it's so much JavaScript is not necessarily a bad thing, like you can still, things can be fast even with a megabyte of JavaScript, but it was helpful to identify, you know, that some of these things. So this gave some insights, but we still needed to like pull it apart a little bit more. And so what it did is it took some of the React perf tools and kind of injects it and the nice thing that it does is instead of seeing mount component, mount component, and just having no idea what it is, it actually tells you, you know, these are the actual components and this is the mount time for each individual one. And I was like, yes, awesome. So here we actually see, you know, like, look at the top, a SNU icon is our number one guy, like, buy a lot. And you're like, icon, an icon is like the number one most expensive thing in this, like, six seconds for an icon. And you look and you're like, what is this new icon? And it turns out it's this little dude, right? It's smiling so smug. He's like, yeah, six seconds for me, bro. And, okay, it gets better. All the mount time, you're like, why do we have mount time for this? So he's SVG, which like, you know, is a little bit more complex than like a ping, but like, sounds cool. He's SVG so that when you mouse over him, he can animate and like smile and wink and do like a, like it's really kind of cute. It's awesome. But that animation, like I said, is on mouseover. And this is a mobile site. So it turns out, it doesn't really happen ever. At all. And so the most expensive thing is spent doing an effect that is completely wasted. So that was interesting. Yeah, there's a lot of like, pretty interesting things that happened, digging into this. And so it's all actually documented in a big issue thread on GitHub. And it was fantastic because the developers from Reddit were involved and they've already started improving, like they fixed this icon really fast. They've improved a lot of things already. And some of the React team also was like engaging and helping people understand what was going on. Good stuff, it's cool. All right, let's take kind of the same ideas but like apply it to Polymer. We're gonna start off with Google patents, which was recently redone with Polymer. And so we're just gonna kind of like do, you know, some demo-y stuff and we're just gonna load this up. Okay, here's the new Google patents and I'm just gonna type for Polymer. Seems like a good thing. True story, my dad actually has a patent relating to Polymers, which is just, I mean, it's random, but that's also cool. All right, we're gonna come back. All right, I'm gonna open up DevTools. Where are you buddy? Come on, come on. Yeah, that's my guy. All right, so we got DevTools. And what I wanna capture, like the key interaction, anytime you do profiling, you're like identifying an interaction that really matters. For me, it's just clicking on the search result and seeing the page come up. So I'm gonna capture that. Here we go and yep, I'm on timeline. I'm just gonna hit record and we'll click on the second guy. To do spinner and there we go. Okay, cool. We're seeing that and there we go. I'm just gonna pop this guy out to make him full screen because we don't really need to look at the page for right now. Okay, so the flame chart. This might be where you're like, hmm, and I'm not really sure where to go next. Which is a reasonable response. But let's get uncomfortable and try and figure out what's going on. All right, so we see these two big stacks, right? And height doesn't really matter so much. Height is just the stack depth. What really matters is width. We see two and the reason why is because here we have the click and then here we have the XHR coming back. But that's kind of interesting, right? Like just clicking on that guy was about 600 milliseconds, which seems like a fairly long amount of time just for the click handler. The XHR is another one and a half seconds. So in total, we're looking at about three seconds. So this is certainly beyond our budget of load, which is one second. But, I mean, this is a web app. I would even expect a sub one second for this little state change. Okay, so we want to kind of understand what work is happening here so we can find out why it's so silly. So we just zoom in a bit and we're just reading the call stacks to see what they tell us. So what I actually see here is we have push state coming in and then we have a pop state event. So it looks like basically on the click we update the URL with the push state API and then as a result pop state fires and then when pop state fires, there's like a bunch of stuff that happens, which is a bunch of stuff. Yep, yep, is that it? Yeah, yeah, everything is hooked on to pop state. Okay, cool. This kind of immediately stands out to me, right? These are style recalcs and they're happening via JavaScript. And so this is like a reflow, commonly called a reflow. Any style recalc or layout that's forced by JavaScript is usually not great. We could dig into this now, but we're gonna get to this bit a little bit later. I wanna come over to the XHR. Okay. Bunch of stuff. It looks like a lot, but again, we wanna break this up into phases and understand what is happening. So I'm just gonna zoom in a bunch and start reading it. Oh, okay, okay. So we have result response coming in and then load HTML. So basically, the XHR is being handled here and then it looks, this is interesting. So object, define properties, setting the inner HTML and then as a result of that, we are, it looks like we're clearing the DOM and so we're removing a bunch of stuff from the DOM and so that's this whole section. In fact, one nice thing that you can know is the coloring of all these little rectangles. For all the JavaScript stuff, the colors are based on the file. So it's a unique color profile. So it's kind of nice because this stuff here, this like yellow is coming from the actual search, like the patent search app. This is Polymer Mini and then this is Polymer. But it gives you a nice kind of indication of where the code is. Okay, so we got all that stuff. We're clearing the DOM and then this next section, which looks a little bit different. We are still in the result response load HTML in your HTML set. But this time, what do we have? I don't know. There's some stuff running here that we're not ready to talk about. I don't know. Add features. It was like, yeah, I'm not sure. But it seems to be initializing some new components based on the fact that, oh yeah, over here we see we're stamping out a template. This is all happening as a result of the HTML. Okay, okay, okay, okay. This section over here, and this is what this is all about. It's just the zoom in and the watching and the, because we were reading the narrative. It's like a bedtime story. It's just really deep inside a JavaScript engine. Just like your best friends and you just give them names and put funny hats on them. All right, this time we're adding nodes. Adding nodes when we're setting the HTML seems really good. And we get through all that. We distribute some content to our shadow DOM. Oh, yeah, render. Okay, I think we're done. We're done? Rendering. Yep, we render a bunch of stuff. That makes sense. Okay, cool. So that is basically the story of these one 1,300 milliseconds. All right, cool. But there was something that was like, a bunch of this work had in common, right? Something I feel like that kind of stood out. Anything, anyone? The... Yes! It was the... No, just take credit. It was the inner HTML, okay? So that's like kind of interesting, right? Like all this work is happening because of this inner HTML. And so like you get a little curious and you're like, well, what is this? And so you wanna like click through. And so I'm just gonna click into search up and then you're like, oh, obviously. No, okay, let's click the button in the bottom left. And there we go. Cool. Yeah, all right. We'll zoom in a bit here. Yeah, okay, cool. Here's our result response. And then here's load HTML. Nice. And then check this out. Polymer DOM, this we're just doing about wrapping around our guy with the Polymer DOM stuff. .inhtml. So we're using Polymer's inner HTML kind of wrapper to set basically the payload coming in from the XHR. So the XHR is returning a bunch of HTML and we're just inner HTML leading it in. Which like is certainly one way to do it. But it's not dumping an entire page worth of HTML at a web app that's initialized and has bindings everywhere. It's kind of self-destructive which is basically why we have to destruct like the entire world and then reconstruct it in order to show the page. So basically inner HTMLing like we're essentially removing all the content and then like pulling it apart, removing it gracefully and then dropping in new stuff and initializing all that and doing that every single time. Not the best idea and so a better approach is just like returning JSON in the response and just data binding like normal. So there were some opportunities certainly here to adjust that if this was done not through inner HTML but through proper data binding, we certainly wouldn't be doing all this work and I imagine that most of our rendering work also we would not be doing because the components would already be built and so I imagine that we would essentially end up with about 10% of this work actually left with just that small change returning something different. Okay, one more thing I wanna show here which is like there's a lot of information in here and sometimes it's a little hard to pull it apart, right? Like we're just going millisecond by millisecond. So this is fairly new. We can also view this data similar to how you might have viewed things in the CPU profile over here but it's down here in aggregated details and so what we basically have, let's see, yeah, cool, is by function. So all of our functions sorted by self-cost but the nice thing is we also have things like recalculating style, garbage collection layout, things like that all kind of merged in so you get the full picture of all the work that's happening sorted by where the time is being spent. So this is really kind of a nice, you can also group it by URL. So here we can like see the distribution between Polymer Mini, Polymer and their code but another thing that I really like and I'm just gonna reload the page to get this capture here, do you done? Yep, is in addition to grouping all the work by URL perhaps better on like large sites, publisher sites where you have like third-party content, other scripts coming in is understanding like where all the scripts are coming from and so grouping all the work by domain and subdomain so here we basically have like we see the work coming from patents, Google, here is like APIs, Google, this is actually part of Google Plus, down here is Google Analytics, here's some of the Google Plus integration so you can get a nice view of like all the third-party content, how much cost that is adding to the page and the other thing you notice like a bunch of Chrome extensions like see the actual impact of the Chrome extensions that you're running and what they're actually doing to the page. So, yeah, this is a kind of a pretty enjoyable way to understand who is spending time on the page. Okay, that seems good for the patent site. Now we should check out one more. I'm doing a point now and actually the patent site, we just recently found this inner HTML kind of faux pas and we'll be working with them to fix it so. But it had, yeah, there's areas to improve, always. The Polymer Summit site is a very nice site but it is my responsibility to also find areas where it can improve, so we're gonna do that. All right, cool. Good looking site. We could watch this and see if we could get like the doon doon doon doon. That'd be dope. All right, but we won't. Schedule, speakers, I like this. Okay, so what I wanted to actually do, I'm gonna profile just clicking, just navigating across these guys because it feels pretty good as far as response time is concerned and I just wanna get a better view. And so, yeah, all right. Let's check that for the moment, see what happens. All right. Do-do-do-do-do-do-do-do-do-do-do-do-do-do-do-do-do. Yeah, do-do-do-do-do-do-do-do-do-do-do-do-do-do-do-do-do-do-do-do-do. All right, so before I kind of skipped like what the very top of everything was showing us. So quickly, the green is frames per second. So when it's tall, that's great. And when it's short, that's not great. And then here is the main thread activity, just kind of like a visualization of what's happening beneath. When it's tall, that's bad. And when it's short, that's good. And then on the top, it's just kind of like a responsiveness indicators where red is bad and red is bad. So that's easy enough. But underneath, you see these new guys. And I really like this, because we basically took screenshots during that entire recording, a screenshot every single time we put up frames. And that means that we can actually just kind of like play back the activity as it happened. And so just like understand kind of what happened in this animation, which I really, really like. Yeah, so this is cool. So the nice thing here is like you can walk through it this way, or you can even like click in to a specific frame, let's say like in here, and just like use your arrow keys and just see the specific things down the bottom and then be like, oh, that one's very interesting and try and find out what exactly happened in that specific frame, kind of coordinate it with what was on screen. This is cool stuff. All right, for the moment, I'm gonna turn that back off. We're gonna look at what the profile actually showed us. What do we got? Zoom out. All right, so we got these three big humps, which makes sense because those were my navigations. All right, there's a bunch of stuff. Whoops, oops, oops, oops. If I look down here, yeah, it's like my time is actually split between script and rendering. Which is weird. So if you wanna move this up and down, you grab it and drag it or pro tip, shift, and then drag will scroll it. I actually only learned this, this one, like three weeks ago, and I was like, seriously, never told me this. It's really useful. Oh my God, okay. We're gonna make this better so that I don't, okay. All right, so yeah, these call stacks are very tall. Like I said, tall is not necessarily a problem. We're gonna just read things, function call, we're going in, yep, yeah. So here is our rendering cost. We're doing a recalc. So this is a forced recalc, and it's being, you wanna figure out why, why is this happening. It's being called by new underlying animation for keyframe effects, which you're like, I don't know, I have no idea. So this is deep in the guts of Polymer, and it turns out, it's pointing to this line right here, turns out that we're actually just calling the animate method on a function, and it's actually currently forcing a recalc, which is unexpected, and it's actually, we think it's a Chrome bug. So we'll probably just be fixing that in Chrome so that the developer of the site doesn't have to worry about it. That'll be good. But let's go over here to this handsome stack. Where are you, buddy? Hey, hey, what am I, did I, oh yeah, scrolled up. Okay, cool, cool. Cause I was looking at this one before, and it's a little different. This is when we clicked back to the homepage, and we're just gonna scroll down, and okay, again, a forced layout and style, and if I look at the little pie chart for this guy, yeah, like, going back to the homepage, there was like 10 milliseconds worth of JavaScript, but pretty much all of our time was spent in this forced recalc, which you really don't want, so why did this one happen? A little different of a reason, so Polymer Select changed, what are you? We click in, and yes, okay, see this right here? So here, we basically asked for the page X offset, asking for, the reasons why you get forced layout is you are usually requesting dimensions, you wanna know the metrics of the width of this, the height of this, and in this case, asking for the page's dimensions, requires a layout of the things inside of the page for a big, ugly explanation that I don't love, but the short version is scroll bars. It's rough, anyways. So the key is, you certainly don't, we don't want to be spending all that time here figuring out what these numbers are. So the fix is basically, if we need those numbers, and we need it somewhere around this time, what you wanna do is request it at the beginning of all this work. Basically, you wanna request it before you change anything about the DOM, because that makes sure that we already know the metrics from the last time we like painted everything and figured everything out, so we could just reuse those numbers instead of recomputing the world to give you the new ones. So if we just ask for the PageX offset, like up in this first part, it'd be good. All right, all right, I think that's it for Polymer Project, the Summit site. It is actually a very well-put-together site, so not much to complain about. Okay, so this stuff is pretty fun for you and you want some more. I showed a number of things from the DevTools, some of the new things that have landed in Canary. I went through some of these, but not some of the later ones. So there's more stuff coming soon, so keep your eyes out for that. There's this kind of journey of going through an audit of in detail of what happened in this 100 milliseconds. We've done this a number of times with a number of different sites, and you're very welcome to just learn from them, click through them. There's a lot of really good stuff in here, especially some of the more recent ones, like the ESPN and the Verge, it's good stuff. But even more useful than reading about some of these is going and doing it on your own. This is actually a picture of the Wikipedia engineering team, and what they did is they took the timeline, they just printed it out on paper, which is dope. So cool, it was like paper, yeah. And then there's markers and sticky notes and just being like, this is this, and this is this, what is this? Just trying to figure that out. And it was fantastic, because not only was it a good exercise to go through, but just recently, this is the time to first paint for Wikipedia, and they made it, it's now 200% faster than it was. And this is as a direct result of the performance auditing that they were doing beforehand. So Wikipedia is faster now, so that's really good. But anyways, I encourage you all to take that same initiative and take a same kind of look at the work that you're doing and figure out how you can match it up against user expectations and dig into it and make it even faster, do some good stuff. Anyways, thank you guys very much, appreciate it. Thank you. Thank you.