Hello everyone, how's, it going good. Ha okay. So. The. Slippers are over there I'm just in my socks for now yeah so oh. My, it's the uniform, okay kiss disconnects oh oh okay. I can, pick it up from see so early, this year fewers, went on a fact-finding, mission to India to see how, folks here use the Internet, and one thing stood out to us yeah and that is that feature phones are back yep. The future phone market, doubled. In 2018, in India and the six sale of the smartphone flattened, a current, lates 400. Million, feature phones will be sold in India this year yes. And whoever's. Controlling the speaker if you could make the music stop coming out of it because I feel like I'm on a really weird music video right now, thank. You that's good okay, so. These phones they're pretty different from. Smart phones right yep but, your phone for instance is 400, 240. Pixel, wide display, single. Density no, touchscreen, the processor, is awful. But, they're relatively cheap right we all know that your phone is very cheap and it's getting millions of people online, for the first time who couldn't afford it before yes. Also the geophone is a web-based phone is running iOS which, is a fork, of Firefox OS so it's running well, Firefox of 48, we've seen some running 42 48. I. Think. Kai OS 2.5, is running for Firefox, 48, and, a lot of companies India here are produced, a web app for these phones such as z5 but, we wanted to see if by ourself - how far, we could put these, tiny, devices yeah. I'm gonna see if I can get my clicker working again here we go. Hahaha. No yeah, well do you know it's, good redundancy, that we have two clickers yes because, you can take over so, yes a little team of us got together consisting, of America, yep, and Jake and. Sama. He's. In England yeah, yeah he's in England it glints that way I think works out well yeah maybe that way I don't know if you go far enough I think you could go both ways yeah.
We. Wanted, to see if we build an interactive, web experience, that will land on devices. Like this but. With, responsive, design in, progressive, enhancement scale. Up to something that look great on desktop, right I think I've been going now so that thing became. Procs. Did you press out yes, I did okay, fair enough you can continue doing that it's approximant, if you like minesweeper, you'll like rocks because. It's the same yeah, so here, it is on the desktop how, many of you have seen props before oh great. So. We've sewn a lot of animation, and stuff at it but it scaled, down nicely and displayed, and playable, on feature phone using, same, Kuroda base you only have one quarter, base yeah, we've put in a lot of effort to make it fast so we figured would go through the tricks and techniques that we use because none, of this is really unique to games not, if it's really unique to this particular app it's stuff that you can do on any web. App or website yep. But before, we dive in let's. Tackle the question that crops up on the Twitter a lot yes. Should. I care about. Performance. Should. I care about performance. Should. I care about performance. Yeah. Yeah yeah yes. Yeah. I'll, go to article, for this is this one-on-one, for web fundamentals you, can find it at this bitly. Link here, it points to web performance studies, carried out by a variety of companies yep. So such as Pinterest who produce lead user perceived to wait time by 40% and, so 15%, increase in signups, yes I'll cookie reduce that load time by 850, milliseconds, and saw an increased conversions in session time well the baby seafood lost additional 10% of users every additional second developer pays to kernel also. Anything reduce the face all the time by half and so a 12% boost in sales or double Kofu found a couple issues with the size of is loaded with five seconds. Of. Course, terms and conditions apply although. That's a large variety of sites and we've seen folks that say it doesn't apply to them because their site is somehow different yeah there's like doesn't exactly, matter what we see on the case studies, therefore, they. Don't think it's evident, that it doesn't have play to them we. Don't buy that no, I think everyone in this room is a user of software, right late and we all know how frustrating it is when something, performs, badly and, low time is a huge part of that right so the performance optimization. We're going to look at today are pretty, simple dead easy literally. Two minutes on paper, but. When you've got a build system wrapped around your project sometimes. Adding an extra tag can be a real real pain so we're gonna look at that side of things as well yep let's, see why in the, first version the alpha version of procs before, we do any, optimization. Yes it's totally the original, alpha version not just one we've invented for this talk, okay. Aside, from being a bit so, it wasn't, all that different, from your average JavaScript. Driven applications no. So our HTML file it, looked a bit like this this might be familiar to you in a few projects it's pretty basic just a bit of metadata the, JavaScript include there that takes care of populating, the page we've, got a stylesheet there but that is just for, a web font the rest of our CSS is embedded in our JavaScript via post CSS so.
The Notable different from the most web apps is that, we use pre-act instead, of react so, the act is 33. Kilobyte in Toro react, is 3, kilobyte, we, didn't need any of the additional features that the Act provides, so it was no brainer that we use react. 30k. Kilobytes, saved for free yes, the other difference is that. We used, roll-up. Basically. We wanted to give roll-up a try but we've used roll-up for libraries before but not for full web apps yeah so we see last. Year, we, built another web app called Skoosh and to, build Skoosh who, used look, back and, we say we. It's. Really just our colleague, Jason. Handle. The web back side of things yeah, Jason's, in America we think America is that way as well I mean what is that way, yeah. That's, America, ok he. Had to make use of a lot of undocumented, wetback in Toros just to do basic, stuff. He has years of web pack experience, and no inside up but we, don't yeah, so as a result we didn't real understand, the project build system and if anything went wrong we were kind of just waiting for Jason, to wake up so he could help us with it yeah then talking to other teams we. Hear same story, it's like maybe one or two webpack, whisperers, set up all of the build, system and no one else really understand. How it was made and maybe, this sounds familiar to you yes, so, when. I use webpack I don't, feel like I'm using JavaScript, I feel like I'm flipping switches in like a massive, config objects, and like herding lots of plugins of varying quality that often don't really play well together yeah. So, we. Thought we'd give a blow, up a shot we. And we found lots of pregnant, at our varying quality, that, often don't play well together but and, this is the key difference mere. Mortals like you and me can write our own plugins, like roll up has a simple, well-documented, plug-in, system it's, really easy to get involved in the innards of the build seriously. If you know enough JavaScript, to wrangle a web pack config you know more than enough to, write a rollup plug-in yeah, also because we knew, we were gonna have a tough time using. You know the application, wants a lot of animation. And things so we, knew that it's gonna be tough time running, everything, on a single thread for, these feature phones so walkers, the web workers, were a core part of our architecture. From the very start yeah we use a little, library called comlink. To facilitate, communication between the main thread thread and the various workers that we used, so. That library is needed in both places well it's needed on the main thread and it's needed in every worker as well this is a little library that Surma built it makes it really easy to communicate with workers, unfortunately. Webpack cannot, share chunks, between workers and the main threads so the, user would end up downloading the common link code while, at least twice once the main thread and then once for every worker yep, and this could happen on each shared, a dependency, not just comlink so Lola handled this out of the box leaving, choice of, the format for developers, like us but, it wasn't just JavaScript to me it's a handle we needed HTML, as well yeah so there's a whip pack climbing to Cle help, create HTML, for your project, but.
Here's, A code for, that plugin it's, massive. It relies on a lot of undocumented, parts of the web pack yes, this plugin so big that actually has his own plug-in ecosystem. It doesn't really want you touching the HTML, itself, instead, you have to learn its configuration objects and all of their quirks your skills in HTML, and not, really useful here yeah we couldn't find a good equivalent. For roll-up so we, decided to write, our own, loader. Plugins, or, functions. That they turn object, the objects, have a name key just, so that Lola can provide better debugging, information when, something goes wrong the, list of this object is callback for various stages of the build and they're, your all document. Did yes, so the callback we were going to use is generate. Bundle so generate bundle gives you the these couple of arguments here the first one is the options, that the that roll-up was called with the output options but, it also gives you this bundle object, and this object is amazing, so we'll take a look at that it, tells, you everything about. Everything. About the build like all of the bits and pieces for, it yeah so for JavaScript, files you get the code initial, past a file name which, has been hashed to make easier to cache but, also laws, of data, about the dependency, of the file has and everything, it exports. For, non JavaScript, I said you, get less information but, still get access to that data yes. Indeed, so now we can create our HTML, so what we're going to do is we're, going to load a template this is just an EJ s template we decided to use we just picked EGS it's what we want you to use roll-up doesn't care what. Templating, language you use as long as it returns a string and. Once we've got the string of the HTML we want to use we then use this emits, file method and we say this is an asset here's the file name and here's the source code for it and now roll up will write that file along with everything else right so here's, our template, we've, got a placeholder here for, the javascript URL we. Don't know what. It is right now because that's more up that's going to add the hash to it we, need to pass the URL of, the GS after hashing and we, can get this from the bundle, object, since it is it, tells us the post input, and output. We've. Created a little helper here for the get Jas this, search is the bundle, for the correct entry, absolutely. So now, all we need to do is add, let's plug in to our set of roller plugins there and, that's it we're done now you know everything you need to know to write a roll-up plugin yep I. Know I said this was a lot of words that we just thought at you but, compare, it to the, web pack version we. Don't do that the one we wrote were much simpler. Just a little bit. Everybody. In your team should be able to understand, and adjust it yes, and even better like we're writing code to do what we want rather than wrangling, config like if we want our HTML to build slightly differently if we want those tags in a different order we, just go in and change the code change the HTML code yep. But what, do we actually need to change yeah so we, needed to find out where procs was losing, performance our. Tool of choice for testing, this situation. In somewhat, the old world situation. Is our, web page test org it, lets you test on real devices and. With excellent, shortening, yes we're gonna be testing on a Moto G, for this is a fairly. Old mid-range, phone but not dissimilar to the kind of devices people are using all around the world we're, also going to test on a 3G, connection yep, sweetie is good speed to measure because some of the time you will have 4G, but due to signals, or conditions, you'll, be experiencing, speed more like soo easy or worse yes, so here are the results for the very first, version of procs the the one that wasn't optimized the, first thing I tend to look at is the filmstrip strip here along the top because this shows what the user is seeing as the app is downloading, yep so let's break, this down for. The first. 4.2. Seconds, that, user see nothing.
But. That's what nothing looks like yeah quite literally nothing's, yeah, totally Finglas yeah, so, but the out, of the nothing here, comes our first lender. Yep, this, is the first render but we can't really count this as ready until the user sees something, more like this with the full UI and interactivity, and. The user doesn't actually get that until they have been waiting for a whole 5.1 seconds, so that's not so good yeah I know but, it was like, we said we're targeting these, feature phones, so and, of course like internet. Speed in India much. Closer to 2 z right and then like especially in rural areas where these feature phones are popular so, to Z but user gets. 8.1. Seconds, of nothing, then. A like. A pretty useless lender oops sorry pretty, the user slender are almost, 11. Seconds, until they are able to play the, game 11, seconds let's put that into context, Usain, Bolt can run 100 meters quicker, than, it takes to Road a dumb game over 2g you know that's terrible yeah so but user had to download, 64. Kilobyte. Before. The site was interactive, surely. We, can do better but. How much better I asked Jake to figure that out yes so I did a little bit competitive, sis, on this so. This is a graph that shows the size of Windows minesweeper. Over. Time so, it. Started out as 11 K in windows 3.11, and then it, actually got smaller in Windows 95 I think that's actually pretty incredible, so it's only 9.6, free kilobytes, that's that's. Amazing that's much smaller than procs, the piece-of-shit app we made first but. Then, in Windows, 2000, what look, what happens there jumps. Up in size doesn't it is become seven, times bigger 70k now it's bigger than procs at this point and the, size crept up again in an XP is well up to sort of 80k. But. Then. BAM. It became 50 times bigger that's three point eight four megabytes in Vista, and it, sort of roughly the same there in Windows. 7. But. Then. BAM. It became 25. Times, bigger still, this is a hundred, and four megabytes, in Windows, 10 that's unbelievable, minesweeper, is actually growing so fast here, to make sense of the graph we have to switch it to a logarithmic scale. So. If you wake up at night worrying, about your how, much your CSS flowers are growing in size this, is way worse yeah, we've actually been analyzing, this trend and seeing where it might go in the future when we predict by 2025. Minesweeper, will be 2 terabytes, in size. By. 2030, 2/3 of the planet's surface will be covered by a single, hard drive containing, 1 copy of Windows - we yes so greater and activists, are doing great, to support spreading, awareness of climate change but surely, the biggest threats to the kind is Windows minesweeper. Yes, absolutely. So in conclusion props, 62k. Great. Report, so, we, know minesweeper, can be done in 10 kilobytes, right that my, super started in ten kilobyte our version, has a little more going on like graphically we have animation, but still it's, 62, kilobyte. To interactive, we should probably do, stop yes we probably should so if you want to improve the performance of your site that you only have a few minutes identify. The important, resources that start downloading, a little bit too late, so looking at the timeline here we're getting to render at 4.2, seconds, a bar, JavaScript just fully loaded at this point so the site is ready to go but, it is useless, because. There, is no text, here yeah because you know we're using web fonts we're. Using space mono from google fonts both the normal version, and the bold poison, they, are both 10 killed by each which, isn't all, that bad, so. Why, is it you know giving us trouble yes, to find that out so we are going to take a deep dive into the network waterfall in webpagetest, which is very similar to what you'll get in chrome dev tools as well and this is the pattern we were seeing first, up HTML. Downloads, yeah thus in our line here, it's convention, boss webpagetest, and dev tools uses it means that it's setting up HTTP. Connection, and the thicker one here. Represents. That it is a liquid in response, time yes, and once the HTML is downloaded, we then download, the CSS, and we, download, the fonts as well it's. Worth noticing when when you're comparing things like a network waterfall to, like rendering on the page they don't add up perfectly, they, don't align perfectly because, you know once the browser has downloaded the fonts it needs to parse them it needs to process them and then it sends it off for painting and then finally all appear on the screen so you might see like a couple of hundred milliseconds, delay between those two things happen yeah but, the LED flag here is the CSS.
And The fonts both have these thinner, lines meaning, they, are setting up connections this. Is because the CSS is on another, server from Google. Pio so calm so it has to start near connection, for new domain and, however if we look inside the CSS as well we, can see the fonts they come from, another. Server Fahnestock, G static comm so that's yet, another connection hmm, so a quick fix here is to copy the CSS and the font onto our own server then, the way you can. Hardly be, used the existing, collection, for the index.html, and in theory, that should improve things by a second, wait you, can't just do that fonts. Are protected, by various intellectual. Property, laws including trademarks, copyrights, and design patents copy them to your server may violate, the policy of the rights holder but. Why. Our studies may be true for many font providers, it doesn't, apply to google, fonts. So. You allow, to host, and them, on your CSS, and on your servers Oh disaster. Averted, I for one will be able to sleep at night it's great. In. Fact this, is so small we may as well just inline. It in our HTML what. About these fonts right the browser tries to be smart when it comes to font downloading it won't download the fonts until it finds something on the page that actually needs them and that means it has to wait for the CSS to download and it has to wait for an element to appear on the page that contains text, that, needs that font and, this is good in some ways because it means the browser can avoid downloading fonts, that it doesn't actually need on the page but in this case we know it, needs those fonts yes so the answer here is link, rel Pluto attacks in the header of the document this tells the browser to download that phone file the particular thing, that you want to use and then hold it in memory until. It's needed and with, those small changes we should see, this yellow line shrink, when, we next passes, through the web page test well, at least that's the theory anyway but. We have to get this working with, our built tools so, here's, the create HTML, plugin that we that we created earlier what. We're trying to do here is going to inline CSS for the fonts and add, a preload tag for each of them I'm not going to go through it step by step because we only have 40 minutes here it looks a little like this there, it goes just. A few seconds yep at, the start of the build we use the low-lux emit a set method. To bring our, fonts, into our build and then mean this, means rule that will handle that file name hashing, for us then when it comes to generate our HTML. In this plug-in we, passed that the into, your template. So. Where this helper gives us the final URL for, the font exactly. So now we can use this data in our template so what I'm gonna do here is iterate, through the the, font data that we put into the template and we're gonna output a style tag that defines the font and that's just using the data that we passed, in via, the plug-in and.
Then What we're going to do is just, output a little, pre. Little tag for each one I guess. Yeah. There. We go there's a pretty low tech yeah. What. I like about this is that Lola plugin, is handling, the stuff that's specific. To the Lola like hashing the files getting, their name, for. The HTML, part, the one that we know you, are writing HTML not, the law lab specific, HTML right, roll-up isn't preventing, us from rearranging. The tags or, adding new tags yes but we. Are not done yet, fonts. Aren't the only asset that's loading too late at the same time we download our script it also downloads, other scripts that it depends on this, is because of the code splitting that we explained, earlier between the main thread and the, various workers however, bit. Like the fonts we know that the main page always needs, all three of these scripts so we, should preload those as well yeah but how can we figure out which script to write, low-lux, bundle, object keeps this answer, I remember, it gives a lot of information to us developers, so for each bit of output Jas it, gives us an array of files, it directly, imports, so, we pass, it this property. Into the our template, and a back over in our ejs, template, and we can loop over those, dependencies, and output little tags yep just like that so we've moved the fonts onto our own server and we've added some preload tags to to them and to our scripts as well this is all better in theory but what does webpagetest, actually tell us about the real world yeah, so. We've eliminated that, no fonts vendor as soon as it lenders, everything. Else is ready to go that's one, second, improvement on 3G and a massive, three seconds, improvement, on TG so we have a medium impacted. The LED bar though that's the part where. The users see absolutely. Yeah and four seconds that's a lot of nothing on, - jeez eight seconds that's that's a lot, a lot of nothing and this is the part of the loading process where the user doesn't even know if the server's responding, they don't know if they're ever going to get an answer from the server right so looking. At webpagetest. Network waterfall confirms. That, we achieved, what, we set out to do everything, important. Is loading, in parallel, right but, it's just taking. Too long yes. We have two options here we, could try and just make these, bars shorter, by reducing the code or we. Could just make it matter less yeah. So right, now we, are fully, reliant, on JavaScript, for our first lender, let's, put a stop to that and let's do solver site meandering or but, like in the build time so we call it the plea tender or static, lender yeah, we want these to see something like this. Isn't. Interactive, at this stage so we've removed any of the buttons that require, JavaScript, but this can appear while the driver scripts downloading, and it improves the perception, of performance because, the user sees that something is happening and, then once the JavaScript loads it, can enhance the page just like this yeah there are a few ways to do this every. Dom orchestration. Framework, that's worth using have, some kind of way to generate HTML from. A component in project, and leoch to its lender to string this. Is pretty, fast not, as fast as other template languages, but it's fast, enough that large scale sites run, in on every, request sometimes, although, we. Were only generating. HTML at, the build time so, performance, isn't something we, were too, much, like you know caring, about however. It. Wants a node and we, actually see that as a downside, see, like if you have any code, that assumes, it's learning in browser for, example you may be accessing, indexeddb, it's going, to fall down from here to. Fix it you'll, have to like end up with a lot of code blanching, still, like Len dota string it's probably, the ideal, if your code base can adapt the, rest of the code for it to kind of make it nicer but, it's not what we needed, ended, up using no we actually we looked at Jazz Dom which. Is like a kind of browser, that runs with, note the, problem there is the word kinder, it's. It's like a completely different browser that you have to support so we try to use it this is what we were intending on using but. We found these sort of weird behaviors one, weird behavior it kept on losing, some. Inline. Background, images we had set on, on some elements and we, dug into wine it turns out the chest Jess Tom doesn't understand, linear gradients, and you. Know as per the, web specifications, browsers, ignore, inline styles that they don't understand, and j/s tom was behaving, like a browser but a browser that doesn't, understand, linear gradients, also. For it's worth it's slower than rendered to string so. Isn't something you would often, want to be running on every request yeah so in the end we went with puppeteer.
Puppeteer. Launched is a headless, version of clone so you can load pages execute. JavaScript, and, then lead the result out of that your, code is running on the actual, chrome so, it like it's not like you're supporting new browser but. However, it's. Sort, of lender to string a little slower than JSTOR but not that much, it's. You know we only need to money it once per build so it like for us it wasn't a big deal, it's need easy to install and use but, adding a whole version, of Chrome to your build it's a pretty big jump in complexity. It's. What we ended up with proxxon it wasn't. No. It was okay so how do we actually get it working Wow we. Wrote another plugin didn't we there it is I'm. Not gonna go through it line by line but just wanted to show you that it's a relatively small chunk of code like, puppeteer let's has launched like this invisible version of chrome ruin our JavaScript, and then we can collect the HTML, that it generates from up from all the Dom elements we just serialize those also. Since our CSS, was in our JavaScript it. Created style tags for all of the components, that were used in that first render so we've collected those up as well I mean we kind of got CSS inlining for free yeah so one bit we haven't covered is how, do we prevent the Pretender from then doing elements, that are interactive. What were we, sorry. What we want it's something like, this. Yes. Absolutely. A simple solution to achieve this is to give a little to code like this to puppeteer and, that can run before the rest of our script and that means in our app we can branch, on that and we can do something different such as hiding, buttons, and, since this is only true in puppeteer it's, not going to run those steps for real users yeah but like it miss your shipping clean and local to the user code, that they don't like, need and it's probably, not a lot of code but it's probably not worth putting the effort into. Shipping it, yeah. We probably actually don't need to worry about this I think it's fine it's like. Shall. We fix this yeah. Go on let's fix it good. So, our, aim is to remove, this code from the bill that leads the user right, this code only needs a clean. Under build process, so, here. Is our current set of plugins. Can, you guess what we are going to do now I have literally no idea well we're going to write, another plugin. Means. That we can write a code like, this and the. Value of pre-render here so we, will be whatever we pass in to write that pretender and, our build, script, yes. A boolean like this I use this on a lot of projects now it's really it's really good for lots of kind of constants, like version, numbers Flags boolean, is like this I've. Seen similar plugins, that don't, require the import statement like we've used here they just change some JavaScript file you throughout your code and I, kind. Of hate that I don't, I don't like that because it's not obvious to the reader of the code that something, build magic, is going to happen there whereas, here I see. This and I see this is a special, import this is some kind of magic, import it's not a valid URL so, something, special that's happening in the build system I can search for that code and I will find the rule of plug-in that's actually handling it and, also rollup is actually really smart here so if we do a build where. Preload, is true. What. We're all will do is it will actually optimize, this bit away so it is just the block, there but more interestingly if we do a build where it's false it will optimize this to. This yep.
That's, What we did we. Created to build one for users and one for puppeteer, so let's, take a look this. Is an entire plug, in the plugging only does something, when the import start with Const, and if. You find such an import it generates, a curve containing, a default, export on the fly, but. It that's, all. Yes, I use this plug-in everywhere okay. So here's the comparable, webpack plugin to, do the same thing, if. You want to benefit from the dead code, elimination side, of things as well again this is not something that I would feel comfortable hacking, around in now, it you might feel that we are giving, webpack a bit of a beating here. It's. Because we kind of are but late the honest truth is that the difference between working on a project with webpack and working on a project with roll-up has been night, and day for us they weave roll-up not only did we feel that we understood what was happening but we felt capable of changing what was happening if we needed to yeah especially with, lestrade and past like making, workers on, the integral, part of our architecture it, was invaluable, yes, absolutely, so now we have this optimize, server render what do we win what is the real world impact well here we go we've, pushed that read nothing render time right back we've cut almost, two seconds, of white screen on 3G, three, seconds, on 2g this, is a massive, improvement to, the perception, of performance, yeah so the yellow earlier, the present time that we've Leonard, but up isn't, yet interactive, because the Jas hasn't, lured it but at least the user is seeing some progress, on the screen it's not the white page so, what's, next, looking. At the network waterfall the, symbolic, at the start of the connection, setup it's, a setup and, the thick block is everything, between the liquid starting, to the final, bite of the responsive, being received yes. And there's another feature that we can look at here that says a feature that's also in a, web. Page test and also chrome dev tools we, can look at the time to first byte and this is how it tends, to represent, it this is the time taken up by the request and waiting, for the server to start sending, the response yeah, as you can see there's, a pretty big gap between the, receiving, the HTML, and getting, the first byte of those important, assets it's about 400 milliseconds. On 3G and a second, on 2g, yeah there are two solutions to this number. One is HTTP, to server push no, no. No. A stupor. It's, incredibly. Hard to get right we've, seen teams of a good number of experts, trying to use it and they, barely, break even on the performance, side okay, so that leaves the alternative, which is inlining we take these assets and we put them straight into our HTML yep. So first up our fonts, so in lining both our fonts are at least twenty kilobyte remember each bold, and the normal is ten kilobyte each to. Our HTML which is kind, a lot yeah, so I took a look, inside these fonts and I, found some interesting stuff, here I think. Three-quarters. Upside. Down question, mark. Surprised. Face. Once. Again don't know what that is this is for cases where you need a P and a B at the same time we've. All been there and, this one this is like I know this looks like a sort of elephant that's sitting. Something. Something like that does that make sense yeah. So. The point is none. Of these characters, are in this, set the set of characters, that we, are using on, this. Opening, screen right all of the characters so we figured we'd just enlightened, that you. Know kind, of like a tree seeking for the code in. The phone people. Call it sub setting they are command line tools for this but, most, of those phone tools use Python, and I don't need any like Python so. There's. A little-known feature in google, fonts the. URL, for the font CSS. Can include, a text, poem I like. Places. If. You include the text plum the font in the style sheet will be subset, it just include those character, Jake for. Those summaries characters, so we, use that to subset our fonts and then went, into the style sheets to download the result yes. And then we use our build script to to open these files and spit them into the template as base64. URLs, and this added only 4.5, K, to the HTML, like much less than the 20k, for the full fonts and we still load the, full fonts we, load them lazily in the background because we need them for future. Parts of the game like the main part of the game the screen things like that but we don't need them for that very first render right so let's look at how we do this here's, our create HTML.
Programming That we looked at earlier or at least a part that feeds the data into the template, so for each font we are passing in the weight in URL but, we're also going to pass in the line in line font as a basics. You for encoding string yeah and this is just using built-in, node, API right but we're also going to pass in the. Character. Sets this is this is the for the Unicode range for each font if you've dealt with web fonts before you'll. Have seen that you can specify this in Unicode range and that tells the browser what's inside the font and lets it optimize some of the loading that it can do we. Use this library from NPM and character set you can just give it a load of characters and it will figure out the most optimal, unicode. Range for that will be handy so. Now that we are passing everything, into the template that we need in line the font but, what about JavaScript. What about JavaScript, so here's. Where we're getting the the filename for the main javascript that we're passing into our template but roll up will. Also give us the code, that's part of the bundle object as well so we can just change that job done there we go we're also passing in the file names here for all of the dependencies, that's how we were creating the preload tags before so, instead of this what we're going to do is go. And find the actual codes for each of those using a map and get the code for each of those and there we go. So. We actually had to change the template as a result of this but, again it's. Just using our skills in HTML, like nothing plug-in specific, so, here's, where we're doing the inline fonts you can see it's part of a base64 URL. The, Unicode range there and here's. Where we outputting, the inline, JavaScript there as well yep done in, theory, but. How does it impact the old world performance, right. We've already already, improved, things by Allah but, with, inlining, we've, reduced our interactive, time by half a second on 3G, and the second. On 2g but, we, are not done yet, now. That the javascript is inlined as well we have reached a point where we only have to look at our index.html. File because that contains everything that's needed to get to interactivity, like we've come a long way even over 2g we are now interactive, in under six seconds pretty good but, I think we can do better yeah our index, eats EML the 43. Kilobyte, right now out. Of that 32. Kilobyte, is that, is j/s, but, that's the code for everything. Right all the fancy animations. The WebGL the end screen but, the user doesn't really need, anything, yet, yes. Yes what we've done here is we've done the the, Photoshop, thing I'm, sure the experiences, before where, you end up staring at this screen for. Sometimes, minutes while it loads a hundred, plugins 200, plugins loads of plugins and the. Weird thing about this is the only thing you can do in Photoshop once, it loads is open, an image or create. A new one you don't need all of these plugins yet yeah, so, this, is my favorite frog in oh.
Hello. Did that bottlenecks, I can't even pronounce it yeah when you showed me this image i thought you´d I, thought you just made this up lately this is the real literally, in the Photoshop okay excellent, I don't, know how to pronounce er Iver I think it's a highlighter, bottlenecks, which sounds like a Swedish folk singer but I don't, know what it does so. Let's. Not load, everything before, the user need to use them let's prioritize a code so, to, do this, right, the first interaction, in this code that this game is to pick the level, of the game you want to play and that's all like, we need to be able to react to that user hitting the start button but, not necessarily, starting, the other game like if user manages, to hit the start button before, JavaScript. Downloaded, to do the produce, the game then, we just show the loading screen everything, else can load somewhat. Lazy it doesn't matter if it's guns later okay. So we. Eat a code split right at this point Co, split control app works very similar to how it works in web pack and parcel, like imports like this will cause whatever jeaious to become part of the main bundle if you want it to be code split you, need to turn it into a dynamic, import, instead now this gives you a promise, so if you want to actually use the module you. Will need to await it this. Means now that whatever dot J's it won't be bundled it will be put into another, chunk yeah so it makes it a sync which can create its own problems. For example component, frameworks, expect Len during to be synchronous, right beyond suspense, allows, allows. Who though the component, leads, but please remember we are using pre-act, doesn't. Support, the suspense yet so of course we. Wrote Prague. In its like 20 line seriously, it, doesn't, do, half, of what the expense does but, it does exactly, what we need for this project in 29. It. Wraps a promise of a component and gives us an actual, component. You, can then use that component to vendor a placeholder, so. Provided, by the function, pass to this learning attribute. Sorry. Under. The nebula, component, laws we just lender the placeholder, of a dead, but once the nebula, component, is ready to use the, other function, will, be rendered which, gets passed look freshly loaded, components, yeah and that was everything we needed with that we've moved all of our components to a lazy model except the ones that we needed for the first render and this cut off over.
20k, Of, the HTML, the JavaScript is now down to 11 K and I, mean when you think about it the start of our game is just like a forum really sorry 11 K is quite a lot but we were we were pretty happy with that we thought that that was enough but how do we ensure that this doesn't creep up over, time yeah, so it's. Surprisingly. Hard like, you write a new component you do everything. Right you lot of stuff lazily, none, of your colleague is looking, and you're having a weak moment and then you, do it you use vs call order complete and boom. You have that static import if the component, is used in the critical rendering path you, might have just added a whole bunch of like inline code into this bundle this. Is how Microsoft, minesweeper. Happens and we want to prevent that yeah. So, we you. Know we tried. A couple of ways to do this we had a comment like this warning, this is part of the main bone will please like don't touch it because. Everyone reads a documentation, right. Yeah. There's a reasonable effort but you know tools. Not rules so, we wrote a little thing that we could hook up to Travis CI and what it does is when it builds something it logs now all of the files of everything, in the build directory, but that means that on the next PR it, can go into the logs of Travis. And it can see what the sizes of the previous build were and it means it can it can but the Delta so that means that per PR we can go and look at this and we can see if, the index dot HTML file, is suddenly grown more than we expect, and if this file is getting, suddenly bigger that suggests that something has gone wrong with the bundling and in a way we didn't expect and we can go and investigate that before shipping it yep it was quite handy so. What, did we win what does that gain us right since, this was our last optimisation, let's start, from the top yes. We started five seconds, until ready on 3G 11 seconds on 2g what, we did now as we move the fonts onto our own server and preloaded, the fonts and the scripts and that improved the time to interactive, yeah and then we added a static vendor, influenced. Eve the performance, by getting the pixel on screen early, yes and then we inline the scripts and subsided the fonts bringing down the time to interactive again yeah. And then we split the code right so we prioritize. What we needed for the initial, interactivity. And then. Slash. Is that time to interact it by over second, on 3G, and two, seconds, on 2g so from our starting point here we've half, the time to interactive, let's, actually feel the difference that we've made so on the left here is our original alpha. Version without the optimizations, and on the right our latest version loading, over a 2g connection and off it goes so, you can see this is the initial connection phase nothing we can do about that and then BAM on 2g it's interactive, now the user can use it still, white screen here this is useless, no text and then sometime later it's finally interactive. Yeah that feels like yeah, so, remember when, you're on the festival, or train or using conference, Wi-Fi like today or just on vacation you, will be experiencing. Speed closer to 3G, and or even like 2g yes, absolutely. I'm, also playing the game you know I'm not allowed to ship anything without using a serviceworker so I did a serviceworker it. Works offline and that also means that the second load is instant. So. Where, do we end up with our plugin, counter Jake that's, fine as well to be honest we wrote way more, plugin, for this project than what we talked about today here all the parkings, that's currently in our law lab config, and I think it's faster. To show which one we didn't, write so. In total that brings us to. Sixteen plugins. Yay. Now. Is that a bad thing I'm, not sure I mean I prefer wrangling, code than I do wrangling, Contech of the, people's code I think it's really empowering to be able to go in and fix stuff without spending days learning, a new DSL or anything like that and I, want to make it clear we're not saying, that you should go and use our plugins because they're kind of dependent to procs and they're all sort of interdependent, as well what we're saying is write, your own sometimes, it is a lot quicker to write code to do the thing you want to do rather, than take something off the shelf and try and bend it into the shape that you need it yeah and remember like we care about user, space, so if your, current dole tools are stopping.
You From making like simple, changes like editing HTML to. Help that users, um get, a better, build tools yep. Thank. You very much.
2019-12-07