 This is a talk about performance and user experience. My name is Davey Shaffer. I'm the release manager for 1871, which is kind of cool. It's also a three-year commitment, which I did not realize when I signed up. I have a release that's got to go out today, so I'm going to work on that at least. I'm at Davey Shaffer on Twitter, so I'd like to put it first. If you have questions, please reach out, and I have my phone here, maybe I'll see you. Which probably grew up as the world's largest CDN. We also do some really cool security and other products as well. Create APIs to check us out at developer.acmi.com. And this may be a little bit too much, but in every single topic, I always went to the problem, which I co-organized with PGA. So Justine did not give me URL, which is image.com.org. This is really important, so please do check it out. All right, so let's get started. Woo! All right, so I'll try to do that slide, because you might get them to come back. So first of all, why performance matters? So essentially, there have been a number of studies about this. One of the most important ones probably is Amazon. So Amazon loses a 1% of their annual revenue per 100 milliseconds in their cycle slot. So what that means is for 2015, they would have lost a billion dollars. And to put that into perspective, that's 15 cents for every single person on the planet, or $3.32 per US citizen. And that's per 100 milliseconds. Google, some of you have probably heard of, they found that if they were half a second slower, they'd got 20% less searches. Bing, when they were two seconds slower, they got 4.3% less revenue per user. GQ, popular magazine, they found that when they caught load time by 80%, traffic went up by 80%, and time spent on the site went up by 32%. Some other case studies really quickly. Walmart got one second improvement, like 2% increase in conversions at sea. They found that by adding 160 kilobytes additional imagery, they had a 12% increase in bounce rate, so that people coming in and immediately leaving. And statements, 1% improvement led to a 10% increase in conversions. So what we can conclude from this is that users could receive tiny changes in performance. And that's actually as little as 14 milliseconds, which is infinitely small. And slower sites make customers less happy. Less happy is a poor user experience. Pretty easy question. Now, this slide will not make much sense, but if my slides had been coming up, you would have noticed that every single slide was 100 milliseconds slower to render than the one before. And it's a really interesting thing when you kind of click onto that, like sort of 400, 500 milliseconds, then you're like, wait a second, something's not right. So there's an old sort of maxim, which is 10 seconds. That's what you have. 10 seconds to render everything, and if you don't get it, your users are going to go away. That's no longer true. It's very far from true. It's actually more like 4 seconds these days. And just yesterday, somebody's slide is totally up to date, Google released a study that showed that you have about 3 seconds, but more than 53% of your users on mobile will just go 3 seconds. And imagine numbers that turn out to be. So who is responsible for performance? The answer is everybody. Everybody is responsible for performance. It does not matter if you are a designer, sysadmins, devops, back-end developers, front-end developers, browser vendors, everybody has a role to play when it comes to web performance. So hoping this is where it's likely to be really necessary. So modern web pages are getting bulkier and bulkier. And what we're finding these days is I have a beautiful bar down here, like it's just gorgeous. 63% of web pages today are images. 17% is JavaScript. We have 3% is HTML and CSS. Also 3% fonts are 5% and then other, whatever that is, 90%. But 63% is images. So anything you do to make your images more better is great. Page weight also is going on quite dramatically. So while 60% of sites are under 2 metrics which is still quite large, we have like 8%, 3 to 4 megabytes in size. Did anyone see there was an article like, like in the New York Times or something, it was a one-word article with that headline. And it was something like, when you receive a CC to the entire company, should you respond and be asked to be removed out of the CC? And the article, the whole article was no. And it was a 6 megabyte page. Additionally, the number of requests per page is going on hugely. Actually, one more thing that will happen. The average page size now is larger than new, the original new. So it's over one and a half minutes. So the number of requests per page is also unknown. So this is a request for sub-resources, images, JavaScript, CSS, etc. Where you have 18% of sites now loading over 15 resources. And even on the very high standard, more than 150, you have 15% of them. It's huge. So let's talk about how we can fix some of this. So as I said, everybody has a role to play in this. So are there any designers here? I don't know, at least one, just to speak on the road there. Number one thing, compress your images. That sounds silly, but if you don't, we're going to do it for you. And we don't know necessarily what you were going for in terms of quality. So be careful with that. Pressure if it is or we will do it. Is this Agents, Dead Opsi folks? Anybody? Every few? Okay, so number one thing for you, please enable HTTP2. It's potentially an incredible performance when it's completely transparent. Just go turn it on. Amazon now supports it. Acquire obviously supports it. Just go for it. But along with that now, all browsers require SSL or TLIs actually. So check out Let's Encrypt.org. This is one of the slides that did not convert revenue. Let's Encrypt.org is a fantastic certificate authority. It's completely free. It's transparent. It's open and it's automated. So you can get these fantastic 90 days certificates that work in every single operating system. Go back to HTTP, the older IDs, every single browser. They're completely free. As I said, they're automated. You can track and rotate them every 90 days. Something else that you can do is you can use the cloud to scale based on the perceived performance. So typically when we scale, we're looking at metrics like load, memory, CPUs, network utilization. One metric that we don't use, and I think we can use to further inform our scaling decisions is perceived performance. So there's something called a speed index port, which is from the WebHTest site. And there's a node module called marsildurant slash webHTest API. You can use this to go ahead and grab the perceived performance, the speed index of your site at the current time. So everyone can link that. Try and follow through this. So basically it's really just simple JavaScript node stuff. So you pull in the module, WebHTest, great to go away. You're then going to go ahead and instantiate that, and you're going to ask to run the test. And so here I'm running it again, stateshap.com, my site. I tell them I want the page speed, and then you have this callback. And what that callback will receive is the URL at which the results will end up at when they're done. So this is not a quick test. You could spin up your own WebHTest instance, and then you're not sharing resources, so that's an option for this. But essentially you get this URL back. And then I have this check response call that's going to go ahead and pull that URL till I get an actual response. Let's see if I can make something else a shot. So basically I have a check response callback. It does a git request on that URL that was pulled, where my results are going to be. It will continue to retrieve the data until it has it also. The way the JavaScript works is there's a data event. So as data is streaming back, you will get that. You just sign it somewhere and then when it's complete, you can then run more. So I have this on hand, which is the end of it. This is when we've got the entire response. And we very simply here just say parse the JSON, this is all JSON APIs. If we get 200, yes, then we finally finish our, the whole response is now there. They've actually finished the test. And we can actually go ahead and get both the first view, which is an uncached view of our website, speed index, and also a repeat view. So it actually adds the ability to catch the resources that are accountable and give you a speed index with that in mind. So you can take that information and make decisions to scale on. So what you're seeing here is basically the test story in every five seconds of people until it gets a response. In this case, I have the two speed index shown. All right, so back-end developers who would consider themselves a back-end developer. Okay, and I know all of you full-stacked people like you can just do all of this, right? So this might seem obvious, but cache aggressive. There's many levels of which we can catch. So native-based caching, which is something like Memcache or Cassandra. Full-page caching using something like Memcache or Cassandra again, but also varnished squid. There's also something really cool about the next slide, including which I had not run into before, and if you don't know it, they're also known as ESIs. They were created by Acline and some other companies I don't care about. And they are partially supported in varnished squid and other open-source products. So I'm not trying to sell you things. I'm trying to make you clear this is available through open-source stuff. And what these are are special HTML tags that you can put in your output that you can then have different caching requirements around. So you can say this fragment has a different TTL. This fragment does not get cached at all. You can do it per user session. So if you have dynamic stuff, you can cache a small fragment just for that user. You know some things like geographic area and stuff like that, which is really cool. So the way that these work is you have two tags. You have the ESI include tag, which is at the top here. So they're XML tags, really, I guess. ESI include source and then whatever you want it to actually include. So this is what your varnished or squid is actually going to pull into the software. But this is the cache resource with whatever settings that we have on it. And then you also have the option to have an ESI removed. And what this is, is a more static version that is less memory-intensive, potentially generic. And that will be removed if the include is successful. So here what I have is I'm including a greeting and it's going to be personalized. So you know, David, otherwise we'll just get a generic hello. So nice follow back there. And that will work with any language that's all up on the caching area. Alright, so let's talk about images. As I mentioned, images are a primary source of paintwork. Anything you can do to improve your images is going to have the most drastic effect on the performance of your site. So the first thing is formatting your changes. So, typically, you will look at an image and go, alright, it's kind of a photo. So, copy it to the J&M, or it's a small number of colors, it's blocked, maybe we'll look at if, or jiff, and paint, or pfg. There are no new formats. So there's WebPaint, which is supported by Chrome. And there's JPEG XR, which is supported by the latest IE and Edge. And these are closer to JPEG and that they are full-colored formats. But they've got much better compression, potentially much better compression. The same thing where you test, like as a PNG24 versus the JPEG, you can see which one's smaller. You can do the similar things here. So what you can do is you can make changes on the server side, compare the results, and decide, okay, this smaller is WebP, so for Chrome, I will serve them a WebP image instead of the original JPEG. So to follow along with that is just compression. So, who's familiar with the JPEG level? Zero, 1200. Who knows what they mean? They don't need anything. So they don't need anything. It's actually what, so it's completely down to the compression, as to what they mean. So, if you have different tools, 60 is not 60 everywhere. So we ran into an issue just this week where LibGD, which is one of the image fibers that PHP uses and WebPageTest also uses, their 60 is different to our media that we use on the Apple App. You have the same image quality, the same size, but 60 is not even right. So JPEG levels are kind of useful. You just say, yeah, we just have generic 60, 80, whatever, we'll just pass everything through that, we're okay with that, but you get decent images that are okay size. But there is a better way. So let's talk about perceived quality. So as I mentioned earlier, as a designer, if you want high fidelity in your images, you should be responsible for compressing. But I'm going to cheat a little bit and say as developers, we actually have a great way to compress in a way that this idea of perceived quality. So perceived quality is quality that humans can see. It's not how computers can derive what humans can see. So nobody can see that, but it's an amazing image of a lady standing in her own starting. And the trunk here is like a terrible renderer. So I had an image that was originally 16.8x, and it was just huge. To make it look terrible, I had to resize it down to 50 pixels, because I literally did the JPEG slider a little bit underneath. So I'm like, okay, resize it down to 50 pixels, and then resize it back up to 5,000, which is completely bracket. But using those JPEG numbers, the original is 16.8x, 90 immediately drops to 5.8x, 84.2x, and I go all the way down to 0 here, which is 393 kilobytes. And what you can't see but I can, is that there is very little difference between the two images. Very closely, especially on a display like this, as opposed to like that, you can see a little JPEG harder acting in some of the more detailed parts of the image, and maybe as a designer, you wouldn't be happy with that. But maybe not. So what can we do to actually compress in a way that is doing it in such a way that it is about perceived quality and not about just size? So how can we programmatically what number we can get to as far as that compression level before we start to get degradation in that image? So there's a really cool algorithm called SSIN. It is actually an Emmy award-winning algorithm. I don't much like to go out on the stage to accept a statue, but this is the truth. It won an Emmy, and it was originally developed for like video compression, so individual frames. So what the SSIN algorithm does is it is not only is not only determining three different actions, brightness, contrast, and structuring, which is a pre-visual part of an image that we assume is perceived quality to be around. And most importantly, SSIN is fast at doing it. But what we can do is we can use DSSIN, which is a way to measure the distance between two SSIN scores and determine how much degradation is happening in reception. I'm hoping you don't be guessing. So with the SSIN tool, it is possible to render these awesome eight maps that you can actually see visually. You know like the FLIR, X, Y, R and the red and the digital, like yellow is hotter, etc. You can actually see that kind of information where the degradation is happening. That's useful for humans. But what we can get out of it is these scores, so these DSSIN scores. So where we went from 16.something next down to 5.something next for that 90% or 90 compression ratio, we get a DSSIN score of 0.09. So that's how far it is from the original source. What we can do is we can set a perceptive quality threshold. We can say that we are okay with that image becoming within a certain distance of the original. So for example, we decide that our threshold is going to be 0.2 or 0.0 to a sorry, that we can compress it all to different levels. Until we get a compression level that is within that threshold but no more. So at the original working point, I'm sorry, and then at 30 is where we get 0.017. As soon as we get on to 20, it's 0.2, what was it? 0.20, so we're over the threshold. So we can make this decision. And this is actually a discussion that you can have with your designer. You can say, look, let me know when you start seeing degradation that you're unhappy with and we will set the threshold. So there is an open source tool called SSIN, there's many implications of it. Some of them suck, some of them set fault. But they are out there, go and check them out. But long and short of it is in this particular example, we save over 90% of the size without losing any perceptively visual inquiry. Say what? I cannot believe this part of the image but it should be if it's not. Because it's kind of awesome. If you didn't, I mean, I should gather like really anyone here in the building. I'm glad that there's a Wikipedia page, that's where that came from because I know what it means. So moving on from the back end, I have a few people here. I have a few. Everyone has a multiply. So for front-end people we have what's known as predictive browsing. More commonly called pre-browsing. And pre-browsing is a really cool technique which is really new. And what it allows you to do is to preemptively perform some of the necessary parts of the connection for subsequent navigation. So there's four main parts of pre-browsing. There is DNS pre-fetching which means, you know, let's go ahead and fetch the DNS entry group and give it your up. Let's reconnect to a server. And I just sent a request which is to open up a TCP height. There's pre-fetching which is getting the data and then finally there's pre-rendering which is actually rendering the requested data off-screen as if it were visible in the browser and it navigates that. So if you've seen any sites that do like full-page transitions and like immediately the next page loads that's how that's happening. So let's see, I have pretty diagrams of all this work. So if you have a Chrome browser or any browser the first one is DNS pre-fetching. This is the first part of making your request. So when you go out to the DNS servers you go ahead and resolve the DNS. We then open up TCP connection to reconnect to the server pre-loading, pull that data down we just hold it in memory, we don't do anything with it and then finally there is that pre-rendering where we run it off-screen so that's kind of a whole new request. And these things are all really actually simple to do. So they're all using link text in your head. So here we have link, rel, DNS, pre-fetch pre-fetch, href, equals and then there's no problem just slash, slash and then you know what I mean there's no problem with the DNS so just look up the example where we get the DNS entry for it The next one then is pre-rendering it's pre-connect So here we now specify the protocol because now we're actually out of making an HTTPS so we need to know where we're going to open up a TCP connection so very similar except that it's well equals pre-fetch pre-fetch well equals pre-fetch this time you can use a relative URL because it's in their own page and then finally pre-render which is basically the same word now I want to caution you, awesome image if you use pre-render you remember earlier those pretty bar charts and stuff that have to happen to render a page those still have to happen and if you're still doing stuff then you may be running into resource intentions trying to render something else so that's something to bear in mind you do like JavaScript to add the pre-render after your existing page to render for example to kind of solve some of that just be cautious especially on mobile because you could be loading a lot of tables On top of pre-routing there is a new standard that is being work on which is locally known as rel equals pre-load and it's similar to pre-fetch so the difference between pre-fetch and pre-load is all the pre-routing stuff is to do with subsequent navigation so you're saying you're coming to the home page for a site that 90% of the people are going to click on excellent next so we're going to do all pre-routing for that the pre-load however is to do with the current navigation so one of the things about it is subsequent navigation and optional pre-load is meant to be a management thing and it's a high priority and it's for the current navigation so you can say I want to pre-load my CSS or my fonts and typically it sent this ahead rather than the link because of that link slash resource 70 home and rel equals pre-load if you request a site typically the browser has to pull down the HTML parse through it, find the CSS add by the JavaScript add, etc then the CSS has some resources to respond to the CSS and has to part through the CSS with link pre-load what you can do is just say based off the thing you're going to need and you can start fetching those during those parsing pages and by the time it eats them you're going to have your own cache and that's really cool when you have really high bytes so with all of these things we start to look at new architectures and essentially if you take nothing away from this talk if the basics we want sucks and the reason it sucks is we don't have to come up with a number of tools that are quite frankly genius but also they're hacks so minifying and concatenating JavaScript and CSS to minimize the number of requests that are being made we also do inlining small projects from CSS called critical path so we will take just the amount of CSS and JavaScript necessary to render what's above the fold what's visible on the page and we'll put that in the HTML so there's no suffering last year there's a problem with that there's an outside of that which is that it's in every page which are paid the main page and 80 URIs which are also paid we also do things like domain chart so all browsers have a limit of the number of concurrent connections they can make to the same domain most browsers is 6, i.e. is 8 but that's not many we're now loading 150 resources so we'll chart, we'll do s1, s2, just write the load across the main even if it's the same servers in the background so as i mentioned all of these things are hacks they're really clever hacks but they aren't so with htt2 we have something called multiplexing which is this really cool idea of using one connection for many arrow over buttons and along with that we also get server push which is very much like link preloading except that the server is just saying here's the error you can also do things like set dependencies between resources so you can say if you are now loading this i also want you to now load this but not until it's done so if you're now loading the css i also want you to now load the fonts but get the css first and we can also assign links which is a great way to actually say the priority of the three things you're sending and then between the browser and the server you'll negotiate and the common resources you get to use things so with htt2 we get this fantastic priority tree which is still being worked on for the browser but we have this idea that like all of these different things that come together to determine how pages deliver across the wires that let's just send everything out at once and see what happens so when we look at delivering a page now yes what we can do now is things like this so we have a browser and a server we send an http request and we get a response we can now also instead of inlining our critical path we can do server push-ins with separate files which are individually casual so we know whether they need it the same way as we do with any request they can just say I've already got this don't send it to me again we've got the last mod up we also send like our loader that's really important during the rendering we can send them and force those down we can also say well in sending my critical path but we also want the fonts because we have headers that are shown at the top of the page so let's make that a dependency when you come downloading the CSS grab the fonts also grab the rest of the JavaScript because they're probably going to scroll at some point we really hope they're going to scroll and then finally we follow along with the last CSS like the majority of our CSS the minor part so this can get really really interesting now I want to point out that this is all new this is an idea this is not something that is I'm not saying that this is the best practice like I wanted to get there everybody is discovering all of this stuff right now so you have a role to play in this you're interested in performance you should be looking at these types and these different architectures and checking it out so in summary performance matters time is money we know that it's user satisfaction so we can say performance is your experience and all of that is money so I'm at Shaffi on Twitter I am bshaffi.com the slides will be on the big shaffi.com slash slides and I would love to have questions thank you so the question was how do you fight the battle between shipping new features and adjusting for performance performance is money so while features are also money like we know that losing money is the opposite of making money and bad performance is losing money so it's juggling out every single thing has as much priority as shipping features and you just make the trade-off as you do between different features like I don't think it's a step for concern it's in the same place alright thank you very much