JavaScript Surprises

Hey everyone.

Thanks for having me.

Glad to be presenting at Web Directions.

Really love the effort that the team has put in to make this conference what it is today.

So I'm gonna be talking about a lot of JavaScript findings today, and this is really close to my heart because you know, when you get to analyze millions of websites and see how other developers are building their websites, building and contributing towards the Web, and approaching other JavaScript features, you really get a broader view of things.

And it becomes meaningless to talk about trivial things like, for example, you know, which framework to get into as a beginner-right.

So I'm referring to the Web Almanac report here, which is an annual state of the Web report that's based on the HTTP archive data.

This data spans through millions of websites and gives you the correct understanding of the state of the Web.

Now we are gonna be using that data and referring and going back to that data a lot.

Now the speed and consistency with which JavaScript has evolved is tremendous.

Primarily JavaScript was only used for the client side applications, but now, you know, you would see that this is going well in the world of building services and Server side tools.

JavaScript is not only used to create faster Web applications, but it is also allowing you to now run servers within your browsers.

What do I mean there?

Have you heard of Web containers?

So Web containers are basically allowing you to run servers within your browsers.

For example, the StackBlitz IDE right, where you can build your applications, but you can also compile your applications using the nodeJS, integrated IDE, integrated terminal there.

And just run your applications, similar to your local setup with any of the IDEs that you use.

So StackBlitz is the first one to do it with the help of Web containers.

So you can do that with JavaScript now.

Now, when I was looking into the Web Almanac data, back in 2021, to see the usage of JavaScript, it was found that a median mobile page was loading 427KB of JavaScript, which is quite a number.

And this was an increase of 18% up compared to the last year.

Now with such an upward trend, you can imagine that the application and the rendering of different applications can get very slow with the additional CPU effort and the work that the browser has to do.

Right?

In fact, it was found in the markup chapter of the Web Almanac that script is one of the most used elements in the list of elements.

Now, this doesn't feel as surprising, but it will, when you go back and compare it to the data found in the year, for example, 2005.

Script element was not even present on the list of these used elements back in 2005.

So now you can imagine the journey from the year 2005 to now from the year 2021.

Crazy isn't it?

Now with that amount of JavaScript, that's loaded in the browser there's one question that you would want to ask yourself, which is how much JavaScript is actually being used?

Are we using all of that JavaScript that we are shipping?

Maybe not.

So when I went back to the data to look, look into and understand how much JavaScript we were actually using, I found that a median mobile page again, was loading 155 kilobytes of JavaScript that was unused.

Now, if we go into the long tail, we find that it goes until 598 kilobytes of JavaScript, which goes unused at the, for example, 90th percentile.

If we begin to find a percentage of this you know, unused JavaScript, it comes down to 36% of JavaScript that goes wasted.

And now imagine the Core Web Vitals being affected by this kind of, you know, unused code.

You could think about multiple reasons here, it could be a large you know, it could be the large frameworks and libraries that we use that contribute to, you know, this unused code.

It could be a lot of boiler plate code that comes with these, you know, frameworks, or it could simply be, you know, this extra non-required code in your, you know, code base, which is simply shipped, but maybe not intended.

Right?

Now, a defensive check for, you know, the presence of JavaScript, with each implementation or a bundle import is a must in this case.

Here's some of the things that I do to see, you know, the, the presence of JavaScript in my applications and how I could work towards those.

So let's look at that now.

So one thing that you could do when you are checking for the unused JavaScript in your application is to go to your developer tools and look for the Lighthouse results.

Lighthouse basically gives you the amount of unused JavaScript and a better way of doing this.

It is to actually check for the opportunities to improve the usage of, or, or the unused JavaScript.

For that I usually go to Web dot dev and I would in the measure section, I would put in the, the website that I want to check for.

And it gives you the amount of reduced you know, the amount of unused JavaScript in your application.

With that it also gives you the opportunities in the areas of improvement, where there could be some potential saving.

It as, as you can see here, it doesn't just give you the transfer size of the JavaScript, but also gives you the potential savings that there could be with certain improvements in the unused JavaScript code that there is, it could be just some extra bundles that you're importing.

Or maybe some bundles that are not being used fully.

And maybe there's just one part of it that's being used.

Right?

So such things can be improved using these opportunities that Web.Dev page speed insights give you, gives you here.

And another thing that I like to do is use the Webpack bundle analyzer, which basically gives you a graph-like representation of the amount and the sizes that your bundles are using and tells you to be able to compare that, you know, which bundle is using more size, if it's really worth using that, you know, amount of size or not.

So it gives you a representation like this that you see, it tells you that for example, react-beautiful-dnd is taking this much space, but then there's other bundles, which is really taking a smaller space, and maybe that's good, right?

Or maybe you are repeating different imports in multiple places if you're using micro front ends for, for example, right?

And you could have the opportunity of just loading that once in the browser and not repetitively with different micro front ends.

Right?

So such opportunities are come your way when, you know, you're looking at these different tools.

The other thing that I've started using recently is the import cost extension for your IDEs.

And it basically whenever you're importing any of the bundles in your application, it basically gives you the size that each bundle is taking.

So, you know, you become conscious while developing your application and not just at the end when you're, you've decided to improve the perform.

While you are building and you're importing something, it gives you the exact measure of how much space that bundle is gonna take.

And you become conscious if this is really the space that you're okay with.

Uh, Or maybe you wanna go for a lighter version, maybe you import React and it tells you that this is for example, 35 KBs of, you know, data that this takes or size that it takes.

And you decide to just go with preact for example, in that case.

So such opportunities come your way when you have these different tools with you, surrounding you all the time, helping you to build a better and performant application.

Now, the other aspect of looking at it is that these different script tags block the render of your application when they come in the rendering of your, you know, when, when the browser renders your application.

So when a browser finds a script element present on the, on the different elements the first thing it has to do is to download that script.

The second thing it has to do is to execute that script.

And all of that happens while the HTML parsing is still blocked.

It's waiting for that script element and the results of it to arrive so that the rendering of the application can proceed.

Right?

Now this causes all that delay in the load of your page, right?

The rendering of your application.

And it looks something like this, where you can see that there's all of that weight of parsing different elements on the page.

It could be the style sheets.

It could be the other script elements or, you know, multiple other scripts that are running or downloading or just executing.

And that's when it parses that HTML that you need on that page.

Which is in this case, a crazy Delay of 22.06 milliseconds, right?

And it could be even more or less.

Now all of that weight is not justified and a better way of doing it is to use an async attribute on that script element.

Now, what this async attribute allows you you to do is that it downloads that script in the background.

However for the execution part, it still blocks the render of your application.

So the browser still has to wait for the execution and has to either wait for the rendering of your application.

And in that case, it'll become a blocking request still.

However, if the script has already arrived you know before the initial paint was done and it has to wait for the execution, in that case, it is a blocking one.

However, if the script arrives after the initial paint of your, you know, the first load of your application was done, it's no more a blocking request, right?

Because the script arrived after that initial paint and you don't have to wait for the first render for your script to be executed.

Now there's still a delay cost because of the execution bit, which makes the request, the, the script, a blocking script.

The other better way of doing this is to use a defer attribute.

The way defer attribute works is that the downloading happens in the background.

However, the execution part is deferred until the point the page has rendered, the rendering of your application is done.

So there's no execution bit until the page has rendered.

This is much better in the case of performance because you don't have this waiting time for where the browser is waiting for the execution of multiple script tags, or the downloading of them, right?

Both downloading and execution are taken care of and only happen after-the execution only happens-after the parsing of your page.

Now, sadly, we saw that this is not very much the case where they're, you know, a lot of other pages.

We found that it was only 48% of pages, median mobile pages, which were, you know, actually using the defer attribute.

And actually, interestingly, we also found that there was this anti pattern where some pages and many pages actually were using both async and defer attributes on the same script element.

Now you would ask me why this is an anti-pattern, right?

Why first of all, many browsers were using it on the same, same script element.

And it would be something like this.

You would have the async as well as the defer attribute on the same script.

Now, first of all, it was for the cases where, you know, you wanted to support both the modern browsers and the older browsers.

However, For most of the supported browsers, it always used to fall back to async, right?

The async attribute.

And the presence of the defer attribute causes a problem in the parsing until the page has loaded.

So this was an anti pattern that we found with both of these you know, attributes present on the same script.

And sadly, it was found that 35.6% of mobile pages were actually using this antipattern.

We, we digged into the problem and saw why this was happening.

It was found that it was mostly the analytics kind of website that were dynamically injecting these script elements with, you know, the async attribute as well as the defer attribute set to be true.

And that's why, you know, most of these in, in most of these cases, we were finding that both the elements, both, the attributes were set on this script element.

So this was one of the things that we found.

Now, since we are talking about, you know, JavaScript, we should also look at the usage of, you know, different frameworks and libraries.

What are the most used libraries?

And I think this is the most interesting part for all of us to look at.

Right?

Isn't it?

So we actually found that more than 80% of websites still rely on jQuery.

Now, this was very surprising because you would wonder where are the other frameworks where's React?

Where's Angular.

Are those in the 20% category?

Now, while this was surprising, it actually made a lot of sense and is totally justified.

To check that we went to the, we went to check the CMS chapter of the Web Almanac 2021.

And it was found that more than one third of the websites were actually relying on WordPress.

They were built using WordPress.

Now, when there's a reference to the WordPress websites, it also is a kind subtle reference to the jQuery being used.

Right.

So that kind of justifies this crazy adoption of jQuery from all of these WordPress websites.

However, this is just one reason, what is the other reason?

So we use all of these JavaScript libraries as dependencies in our applications and these JavaScript libraries could be using jQuery for their internal functioning.

And that's where this internal adoption, you know, kind of this indirect adoption of jQuery comes in which again, contributes to that 80% of jQuery adoption in our applications, in the different websites that we analyzed.

So all of this comes from, you know, WordPress and the different libraries which indirectly, you know, give us the usage of jQuery.

However, we also wanted to dig deeper and see how WordPress is actually you know, aligning with the usage of jQuery and to check that we looked at the versioning of jQuery.

So the most popular version of jQuery is 3.5.1, which is actually used by around 21% of median mobile pages.

And the second most popular version, was 1.12.4, which is used by around 14.4% of median mobile pages.

Now to understand this difference in the versions and their, you know, the percentage that we found we went in to check the history of when was WordPress upgraded the last time.

And it was in the year 2020 when you know, there was a change in the WordPress core and there was this announcement where, you know, WordPress took a leap to version three.

Which also meant a default upgrade for, of jQuery from version, you know, 1.12.4 to the, this latest version, which is, you know, 3.5.1.

And that's where, you know, you could connect the dots and understand that, okay, this is the reason for the adoption.

And this is the reason for that percentage change that you see there.

So that's about the different frameworks and which is mostly about jQuery.

So that's about, you know, the different JavaScript frameworks.

And in the end, I think I would just want to just like Alex Russell says I would want to say that, you know I would ask you to not allow me to have to, you know, give this talk again.

I would ask you to, you know, not allow me to talk about improving performance from a developer experience again.

It should be an instant Web.

It should be the Web for developers where they're built upon the Web for their needs.

They should not have to do lazy loading for all their components.

They should not have to care about hydration techniques.

They should not have to care about caching certain stuff so that their applications are faster.

Our developer should simply be building upon the Web, the framework that they have for the easy building of their applications.

And that should be it.

Isn't it?

That's what an instant Web is all about.

And in the long run, I think that's what we should be talking about.

Not about how many websites are lazy loading their, you know, components or bundles, not about how many websites are actually using Web components or they're caching their, you know, resources, how many websites are using a sync or defer attributes.

Right?

We should not be talking about that.

We should be talking about what are the different features that developers are building upon this you know, faster Web that we have given to them.

And one of the frameworks is actually doing it and working fully focused towards an instant Web.

The Qwik framework is actually already doing it.

The developer doesn't need to care about, you know, lazy loading techniques.

They don't need to care about hydration.

It's all edge cachable and fun for the developer.

That's what a Web in the long run looks like.

So thank you.

Screenshot of the Web Almanac page. Text reads "Web Almanac. HTTP Archive's annual state of the web report"

Screenshot of the StackBlitz website. Text reads as below

Run servers. In your browser.

You want it to be a mini-operating system.

Alan Kay on his vision for web browsers

Top elements

2005 2019 2020 2021
title div div div
a a a a
img span span span
meta li li li
br img img img
table script script script
td p p p
tr option link link
i meta
option i
ul
option

Screenshot of warning to reduce unused JavaScript

screenshot of graph from Webpack Bundle Analyzer.

Screenshot of import cost extension results

import { TableCell as MuiTableCell, Chip } from '@epilot/base-elements'
import { useTranslation } from '@epilot360/i18n' 8.3M (gzipped: 1.1M)
import from 'lodash/fp' 81.9k (gzipped: 28.7k)
import React, { useMemo } from ' react' 7.4k (gzipped: 3k)
import { useLocation } from "react-router' 15.9k (gzipped: 6.2k)
import styled from 'styled-components' 32.9k (zipped: 12.8k)

Screenshot of timeline in devtools showing delay in parsing HTML.

<script src="almanac.js" async > ... </script>
<script src="almanac.js" defer > ... </script>
<script src="almanac.js" async defer > ... </script>

Screenshot of code showing `async` set on script tag injected into the document.

Graph of adoption of top libraries and frameworks from Web almanac 2021. Shows jQuery at 84%, jQuery migrate at 33%. jQuery UI at 22%

Pie chart of CMS adoption share from Web Almanac. Shows Wordpress at 75.4%, Joomla 4.4%.

Screenshot of part of a web page on jQuery and Wordpress. Text reads as below

Major Query Changes on the Way for WordPress 5.5 and Beyond

For some, this may feel like a journey back to the mid-2000s, a time when JavaScript very much felt like the Wild West. Query solved many issues for a programming language that had not kept up with what developers needed to accomplish.

A ticket created by Aaron Jorbin four years ago to move WordPress to the latest 3x branch of Query is finally coming to fruition. However, the WordPress development team will need to make this transition in stages, particularly after waiting for so long.

Qwik

No hydration, auto lazy-loading, edge cacheable, and fun 🎉!