 Thank you. Thank you. It's a very nice introduction. Hello everyone. I'm super excited to be here in Bangkok. This is my first word camp outside of Pakistan. I've attended many over there. That's where I'm from by the way if you haven't noticed by now. So like we mentioned, the focus of my talk today is not just to come in and share the things that you can do. I will be sharing that. That's no doubt it's going to be there. But it's actually to change the perspective that maybe we're too focused on SEO and we're not too focused, not enough focused on giving great user experiences when building our websites. So let's see. I'm going to dive in and we can explore a little bit of what we have to share here. So already, B has given a pretty detailed introduction already. So I'm just going to skip through here. I just wanted to mention part of my role is also I'm a Google Developer Expert for Web and Angular, which means I also get to sync in with the Chrome team from now, time, time again. And some of the things I'll be sharing was data shared with us by the Chrome team. So that has been pretty cool, interesting tidbits that we've found from there. Now also on a podcast in case anybody finds this interesting, you can obviously see more of where that came from. A quick show of hands. How many people have been frustrated while using their computer over the last few days, few weeks? How many people have, they want to just get angry when they're using it? Like what happens when things don't go the way they plan? Show of hands. How many people have been frustrated? Yeah, see, many, many people and the reason and the whole point of starting off with this is we want to start taking that frustration apart and try to see why people are getting frustrated. So let's say I'm trying to access a website and now I'm waiting two seconds, I'm seeing a blank screen. Nothing's happening. Four seconds, I'm getting impatient, I'm getting frustrated. At six seconds, I'm checking my internet connection and maybe my internet is down, I don't know what's happening. At 10 seconds, there's likely chance that I will close the tab, right? So one part of that problem is that I need feedback. I need visual completion. And if I'm not getting that visual completion, I'm not, I'm going to be frustrated and I'm going to move away. The second part is interactivity because when I'm on a website, I'm there to interact with it, right? I'm going to scroll, I'm going to click, I'm going to visit some links, I want to see some animations. But if my browser is too busy loading stuff or maybe doing some background processing, then that feedback is not going to be there. I'm going to be trying to click something and nothing's going to happen. And that's going to lead to frustration as well. So I went around asking people, it's like, how do you guys, how does the WordPress community solve the performance problem today? And a lot of you shared with me that you guys use plugins. And I use plugins as well. I think the amazing plugins over here. But I feel that we're still lacking something. Here's a slide that you guys have probably seen in the boots outside. It's in the Google booth when we're talking about performance there. You'll see the WordPress line two years ago was about 15%. It's gotten a little bit better. We're still at 25%. And this is, by the way, the score percentage of websites that are scoring good on Corbett vitals, so automatically you can see that there's a lot of work that needs to be done. And a lot of work just because 40% of the web still runs on WordPress. If we, the community, don't uplift this, it's not going to do it by itself. So this is the graph that scares me a lot. And that's why I went down this journey of trying to figure out if we're all using plugins and we all have figured out these performance problems, then why are we scoring so poorly across the board? Show of hands. How many people here know and use Corbett vitals already? Most people use them. That's great. They came out a few years ago. One of the reasons why I personally love Corbett vitals is because the whole concept of Corbett vitals was centered around the user. It was all about user experience. Take LCP, for example. This is the metric for performance. And before LCP came into being, there was always this confusion. What does a fast website mean? Is it time to first bite? Is it DOM content loaded? And nothing really was centered around the user itself. It was all about shipping bytes from a server. But LCP came in and changed that paradigm. And now we actually have a metric that we can refer to back and back again that defines that when your largest contentful paint, when the largest part of the frame comes, is displayed, is rendered, that's when the user gets the value. That is the point that we measure in time for our performance. Similarly, stuff like FID and CLS were not something we talked about at all. But they have a large impact on the customer experience. I regularly face issues with CLS on some really big websites, even as of today. Because you'll be trying to get to something, you'll be trying to click something or read a blog, and suddenly content will get pushed down because it got rendered later and it wasn't configured properly. So these are the things, these are the three core metrics that have been built around user experience. And if we're able to focus on these and get high scores in them, then eventually we're essentially looking at how do you create good user experiences? But I feel sometimes we get too locked in numbers and we don't really, we stop thinking about what is the actual problem behind the scenes, right? So I want to take you down that journey a little bit. What is the actual problem we're trying to solve? So if you're looking at optimization or performance, you actually are, what's the basic problem? You have a bunch of code that's hosted somewhere in the server and the client's trying to access that and now you have to download all of that content onto that device. It could be a mobile device, desktop device, whatever, right? So the problem is broken down into two stages. The first part is downloading it, and then the second part is it has to be executed and then rendered. Now, when we're building software, unfortunately for developers, most of us, we're not, we're usually thinking about the best case scenario and not the worst case scenario. So I will be testing this on a high-end phone or maybe even my own MacBook and on a broadband connection. And on that, yeah, it's completely fine. There's no issues over there. But for your average user who's using a probably a low-powered Android device and is on a 3G connection, that's where things start breaking down pretty bad. So if you start looking at resources, the theme I want to focus on today, because performance is such a large and complex topic, I want to focus on just one thing today. How do you reduce the number of bytes that are coming from the server to the client? And if we are able to do that, automatically, we're improving our LCP. Automatically, there is less stuff that needs to be processed. So if our FID will go up, and if we're able to load everything fast enough, then there shouldn't be any CSS issues as well. If you look at resources, what is the largest resource that is downloaded over the internet on any website? Any guesses? Images, right? We heavily use images. And if you look at the numbers, this is the data from HTTP Archive. And if you look at the 90th percentile, we're downloading almost five MB worth of images on load. That's a lot of content when you're trying to just load a website, right? Do we need to see all these images? Maybe not. On average, it's about, I think, 450KB or something. Still quite a lot. So how do we reduce this? Let's look at a few things and let's discuss and see what techniques can we use to, one, reduce the amount of content we're getting in and optimize the content that we want to show, show it first. That's very important. Lazy loading. Anybody here who hasn't heard of lazy loading yet? Please raise your hand. Thank God. All right. Everybody knows lazy loading. We've been doing this since 2004. The way we've been doing this, we'll discuss on that. Maybe we want to optimize that a little bit. But the one reason I want to talk about, so all the plugins that we use, I shared a bunch of them before, all of them are involved in lazy loading. But what are some of the cases where lazy loading doesn't have an impact? So the plugin will not be able to lazy load your images. Are we thinking about that? It doesn't look like that. Right? So a lot of WordPress websites are now moving over to React. And all of the React code is usually rendered on the client side. So are your images lazy loaded then? Not really. You have to lazy load images yourself. So how do you do that? Well, it's not hard. It's part of the image tag. All you have to do is configure the lazy property and those images that are not in the viewport onload should be loaded lazily. The browser behind is for you. You don't have to install any libraries. You don't even have to install any plugins technically if you're configuring this on all the images yourself. But there is a problem because 70% of mobile pages have an LCP that has an image. That means when your website loads first, there is an image over there. And what happens when I lazy load that image? My LCP goes down because when I'm lazy loading that image, it's going to be rendered later. I've told the browser that this is not important. This needs to be rendered later. And this is a place I've been talking to some of the teams over here on the plugin side as well. This is a tricky problem to solve even for the plugins. So you have exclusion lists in the plugins themselves that will leave these out. But you have to go there and change them. So you need to be aware of these things that when you're talking about performance, it's not just clicking a button and, oh, you know what, that's it. My problem is solved. Rather, you have to understand what each plugin is doing. What are the areas where it is optimizing and what are some of the areas it's not optimizing? So what do we do over here? So one of the things that I want to also introduce to you guys is priority hints. This is, again, something that's been shipped in Chrome also available on Microsoft Edge. And what this tells the browser is that there are certain resources that need to be brought up in priority. So if you have an image that's front and center, you might want to mark that as high priority so that it goes first. And it gets downloaded even before the CSS and JavaScript resources that might be needed later on. So little things like this, and it's not too much effort. It's just a single attribute, right? But the impact it has on your website could be quite large. And generally, if you look at the lazy loading ecosystem, if you're not already using a plugin, there is massive savings to be made from a byte perspective. And depending on how big your clients are or your own website is, you could potentially be having monetary savings as well by not serving all of those image files to your users. So that's something to think about. Another area that I feel we can always optimize more is on the responsive front. So we all build websites and teams, and we build them responsive so that they work on desktop and they work on mobile as well. But most of the time, when it comes to images, we're not really thinking about are we optimizing that image for the kind of device it's being rendered for at that time or not. Well, I mean, it's a solved problem. Again, something a lot of the plugins are already doing for us. So an image CDN will basically optimize your image for that particular device. How does it do that? It's pretty straightforward. It will look at the browser information that's coming in, the browser agent in the headers. It will also sometimes look at the device information. So it's a little thing, right? You have this quality over here. Do I really need the highest quality image on a low-end Android phone? I don't. I don't have that high-resolution screen. So I can knock this down. I can shave off a few bytes, and I can serve that customer faster, give them a better experience, and save bytes on the server side. So it's a win-win for everyone. And here's another example. Travago is another OTA in this space, and these guys saw a drop of 80% when they started to use an image CDN. So again, the savings can be substantial by doing something as small as sharing dedicated websites on your server. But there's another way to do this, and I also wanted to share that quickly. There is something called responsive images. I'm not sure how many people are here are aware of this, but basically you can create the multiple different sizes of images on your server, and then when you configure them in your code, you simply define them. And this is, again, something that's supported across all browsers, and the browser will then decide which is the right image to download, and will pick the most optimized image possible. This is obviously backward compatible in the sense that you still share the source image, so nothing breaks for your users in case this is not supported, but I think this is supported across the board anyway. So these were all the things that we could do from a plug-in site, but what else? How can we further optimize our images? And one of the things that I've come across which was very interesting was what if we move away from the image itself? What we started looking at SVGs, which are technically images, but they're actually code, so they're much, much, much smaller, or just think of CSS. This image here, I've just picked it up from a playground, and this is rendered in CSS, so you can do quite complex things in CSS as well. And the size of the code is a fraction of what the actual image would be. Now, this is obviously not applicable for all the cases, but this is definitely an option for some of the cases where you might be rendering maybe your logo or something else. How many people here are using GIFs on their website? Show of hands if anybody is, all right? There are a few folks. Interesting thing I learned about GIFs is that we no longer need to use GIFs on websites because they're not that efficient. So an 8MB GIF can be converted into a 400KB MP4 video, and then you just need to configure a place in line loop, and it will just look like it's a GIF on the website. So straightforward. Little things that will chip away and slowly you're shipping fewer bytes to the client, and you're getting improved results for your customers, and potentially even saving money on the server side. But the big one, which we all worry about, I guess, is JavaScript. So JavaScript has been growing steadily, especially again I mentioned before as well, as we move a lot more code into the React world and make everything dynamic, we're shipping more and more JavaScript. The important thing to know about JavaScript is that majority of the code that you ship is not the code that you've written. It's somebody else's code. It's libraries, it's Google Analytics, it's those AdWords scripts, whatever, but it's third-party code. So the objective for us usually is how do you reduce that? This is a web analyzer output, so there's a tool called Webpack Bundle Analyzer, and if you run that on your source code, on your bundle, it will show you what's inside that bundle. And this is a project that I was working on, and this is a few weeks ago when we started off, and this is a huge bundle, it's a 3.5 MB bundle. And you can see there's this huge thing over here, that's an external library for charts. There is some big boxes over here, including another library for charts, I don't know why, there's Moment.js. And we started looking into each of these and tried to see how can we kind of clean this all up. And a few weeks later, this is still not fully optimized, but you can automatically see from the image that we have shrunk it down quite a bit. And I think at this point, this is at 1.2 MB, which is still too big, but we're cutting it down even more. There's some pretty obvious candidates to remove that we can see if we need them or not. So, one way to reduce the amount of content that you're sending to the server is by doing housekeeping, is by looking at what consists of the bundle, of the code that you have, and removing stuff that you no longer need. One of the things that's changed over the last few years is the introduction of ES modules. And ES modules brought with them this ability to something called tree shaking. And tree shaking basically is that instead of including everything in the library that you are using, you only pick up the functions or the code that you have used and bundle that instead. Very simple idea, but it's still not fully adopted across the ecosystem. So, Lowdash is one of the popular libraries that we use for utility functions in JavaScript. Now there's Lowdash ES. So, when I use one function from Lowdash, I make sure that I just import that one function instead of importing everything. So, this is just two things that you have to be careful about. If you do import all, it will import the whole file, even if you're using one function. And then you have to use the right syntax over here. So, if you use something like this, Lowdash, it will import the whole library, but if you call in that specific function from the ES library, it will just import that one function. And again, the code that you were shipping was never being used anyway. So, you're not changing functionality over here, you're just configuring it so that you're sending less bytes to the client. And the coverage tool is not just, I mean, on Webpack, for most WordPress websites, actually, the coverage tool is right built into DevTools. So, all you've got to do is open your DevTools and see what is not being used. One of the spaces where I've consistently see there's being a huge gap is the CSS side of things. So, normally for most teams, there is this one large file for CSS that bundles all the CSS in it, and then we're serving that on all pages. So, one of the ways to improve this is by refactoring your CSS into more modular functions so that you're only shipping the CSS in a way that is relevant to that page. And we'll talk about this a little bit more, but you can go really, really hard on and make sure that you want to focus your CSS for the first render, right? Whatever is in the first viewport, you want to make sure that that CSS gets loaded first so that you can render the content and then the rest of the CSS gets loaded in later on. Here's another metric. Just like our app before, Walmart did a whole house cleaning as well, and they were able to reduce their JavaScript bundle by 70%. So, I'm pretty sure for each one of us, there is opportunity to improve our bundle sizes over there. Adaptive serving is this idea we've all experienced whenever we're watching a video, and the bandwidth decreases, the connection is no longer that good. It will move us from a 1080p video to maybe a 720 or a 240p video, right? Can we do that with JavaScript as well? So, here's an interesting idea. eBay did this. They limited the amount of functionality depending on the stuff the user, the connection the user was on. So, if the user is on a 3G connection, do you really want to download that whole slider and all of the related images with it? Maybe not. Maybe you can just do it with one image. All of this code, all of this stuff is things that are very hard to do for a plugin automatically, right? This is something that we as developers have to think about and optimize for and discuss with our clients to see, hey, look, I can see an opportunity here. I'm testing this on my low-end device with a 3G connection, and this slider is taking too long to download. It's not great. So, how can we improve the experience for the lowest denominator, and then automatically, when we move upwards, the experience remains great for all the other users as well. Another one is Twitter's data saver mode. This is something I've really enjoyed using, especially when I'm on 3G, because all they do is they download a 64x64 pixel image and spread it across, and then when you tap on it, it will load the full image, right? So, there's always that assumption that the user wants to see all of the images, but does the user really want that? In this particular case, maybe not, because this is a popular feature, and the savings you get, again, are pretty substantial, right? Because the user is going to save 80% bandwidth by using this mode, and maybe this is relevant for your website as well. And just to wrap up this section, I think we can go a lot more deeper into this, and if you want to be really, really aggressive, there is this whole idea called a purple pattern, and there is a love documentation on this as well, including this idea of critical CSS. So, you take this down to the most smallest possible bundle, and you only get 14KB. You have to bundle everything in 14KB and ship that as fast as possible so that you can get the fastest render on your website. And when you go down this road, you'll find many other interesting things other people have also done just to get that first render viewport rendered quickly, and I think this is going to be very useful for everyone here to learn from, basically. So, all of us will hopefully go on Monday and start working on our websites, and we'll start improving, start optimizing, and we'll all be happy. Yes, we made our website faster, but unfortunately, after six months, we'll find out that where's exactly where we started from. So, what happened? The problem is that our websites are not static in nature, most of them, right? They're dynamic, they're changing, people are adding more requirements, people are adding more scripts, there's new analytics tool coming in, there's that chat tool coming in, there's that support tool coming in, there's that reviews tool coming in, and it goes on and on and on and on and on, right? So, just us, just as a developer, it becomes very hard to hold back. You can only optimize so much before the bundle will keep growing, the resources will keep growing. So, how do you slow this down? How do you improve this on an organizational level? That's where you, we have to start thinking about building a performance culture inside the organization. So, there's this whole new concept of, well, it's not a new concept, but it's a concept of performance budgets. So, for once, so we've all been there where we've gone to our business counterpart and said, hey, look, there's this awesome tool for security or XYZ and we want to get this and we've been told that there's not enough budget for it. In this particular case, when a new script or new requirement comes in that needs to be added and it's not part of the budget, we can share that same concern with our users as well, right? Because if we don't have these budgets set and we're not learning about these budgets, then things will get worse over time automatically. So, they will keep us in check as we make changes to the system. So, how do you go around defining a budget? There's a nice tool that helps you kind of configure each resource that will kind of give you an idea of, okay, roughly this should be my budget and I'll share the links at the end so that you guys can take them all in one bunch. But there are several ways to configure your limits themselves. It could be a time-based thing, it could be a resource limit-based thing, it could be a lighthouse performance-based thing. But basically the idea is that as you're building and adding more code and changing stuff, you want to make sure that you're not going over the limits, right? Because sometimes these limits, you just add a library and you don't know. I'll give you a quick example here. I think I have just enough time. So, recently in our project, somebody added moment.js because they wanted to format a date function. All right, makes sense. But turns out that we were adding 400 kilobytes of source code for that one formatting function, right? Now, I've already shared a better way to do this would be to use date functions library and use the right syntax so that we only import maybe a few bytes of code rather than 400 kilobytes bundle, right? So, with budgets, it alerts you immediately when you've done something like that and you can investigate and see, oh, did we do something wrong? And then you can make corrections likewise. So, how do you do this? There's a tool within Lighthouse called the light wallet and you can configure this as part of your continuous integration. I would recommend configuring this on your GitHub with GitHub actions. And as soon as you push new code into your repository, it will tell you if you've started breaking any budgets or not. So, it's super useful and you can also put it as part of your CI pipeline so it won't let you merge if your budgets are off. So, that's also always useful especially because if there are other people who are just merging stuff in, the things, the alerts get triggered but they don't get acted upon. And there's so much more, right? I could probably go on for a few hours talking about performance but I'm going to wrap it up today for today and I'm going to leave you with these few resources which I hope are visible enough. So, there's a lot of content especially on web.dev where you can learn about web performance and yeah, I think if you go, especially there's been this new article that I just recently learned about as well that really focuses down on things, a lot of the things that I've shared over here but a lot more as well that's present on this thing as well. Yeah, cool. I think that was it from my side. Thank you.