The numbers tell us that the
growth in the volume of JavaScript-code is bad for the performance of web projects. If this continues in the future, then very soon, when loading the average page, at least 400 KB of JS code will be transmitted. And this is just the amount of data transferred. Like other textual resources, JavaScript is almost always compressed. Perhaps compression is the only thing that is usually done correctly when transferring code from the server to the client.

Unfortunately, while reducing the transmission time of some resources makes a serious contribution to what we call "performance", compression does not affect how long the browser takes to parse and process the script after it is fully loaded .
If the server sends the client 400 KB of compressed JS code, then the actual amount of code that the browser needs to process after decompression of the received data will be around a megabyte. How well various devices cope with such work depends on the devices themselves.
Much has been written about this, but one can only say with certainty that the time it takes even to parse the amount of code that is quite usual for its time varies greatly between different devices.
')
Take a look, for example, on
this my simple project. During the page load, about 23 KB of uncompressed JS code is transmitted to the client. Chrome, running on a MacBook Pro, which was released in mid-2017, this rather small amount of code processes in about 25 ms. On the Android-smartphone
Nokia 2 , however, a similar figure grows to 190 ms. This is not to say that this is very small, but in any case, the page becomes interactive fairly quickly.
Now - an important question. How do you think a simple Nokia 2 smartphone handles average modern pages? In fact - just awful. Browsing the web, even on a fast internet connection, forces the user to exercise patience, since working with the pages loaded with JavaScript code becomes possible only after a hefty waiting period.
Nokia 2 performance review when viewing a page that contains a large amount of JS code, processing of which blocks the main streamAlthough the devices with which they view web pages and the networks over which data is transmitted have greatly improved in recent years, studies show that all these improvements are “eaten up” by large amounts of JS code included in the pages. We need to use JavaScript responsibly. Responsibility begins with an understanding of what we create and how we do it.
Comparison of the ideology of "sites" and "applications"
Strange things happen to inaccurate terms that we use to call something, although their meaning, on an intuitive level, is clear to everyone. Sometimes we overload the meaning of the word "bee", calling it "bees" and wasps, even though the difference between bees and wasps is very significant. Taking into account such differences can lead to the fact that with the "bees" and "wasps" will act differently. For example, we are going to destroy the wasp nest, but if we are talking about bees, insects are much more useful and vulnerable, their nest, located in an unfortunate place, will probably be decided not to destroy, but to move somewhere.
Similar freedom can be observed in the way we use the terms “website” and “web application”. The differences between these concepts are much less obvious than the differences between real wasps and honeybees, but if these concepts are combined, this can lead to very unpleasant consequences. Trouble begins when we allow ourselves to do something, depending on whether a certain project is “just a website” or a “full-scale web application.” If you create an informational site for a certain company, then most likely you will not rely on a powerful framework for managing DOM changes or for implementing routing on the client. At a minimum, I hope so. Using tools that are poorly suited for solving certain problems will not only harm those who will use the site, but will probably have a bad impact on the development process.
When developing a web application, everything looks different. We install packages, which is accompanied by adding hundreds, if not thousands, of dependencies to the project. However, we are not even sure about the
safety of some of them. We write complex configurations for bandlers. When working in such an ubiquitous mad development environment, knowledge and attention are needed to make sure that what was collected was fast, that the project would work where it should work. If you are in doubt, run the
npm ls --prod command in the root directory of your project and see if you can state the purpose of using
everything that this command displays. Even if you can do this, it does not apply to third-party scripts. I am sure that several such scripts are used in your project.
We forget that both websites and web applications occupy the same “ecological niche”. Both those and others are under the same influence of the environment, which consists of various networks and devices. Such restrictions will not disappear if we decide to call what we are developing “application”, and the devices of our users will not magically become much faster if we call the “website” “application”.
It is our responsibility to find out who uses what we create, we must take into account that the conditions in which different users connect to the Internet may differ from those we rely on. When creating something, we must know the goal for the sake of which we create it, and after that we are engaged in the development of what helps to achieve this goal - even if the development turns out to be
not such a delightful occupation .
This means that we need to re-evaluate our dependence on JavaScript, and how its use, in particular at the expense of HTML and CSS, can lead us to use irrational patterns that are harmful to the performance and accessibility of web projects.
Don't let frameworks impose irrational patterns on you
I witnessed the discovery of strange things in code bases when I worked with teams dependent on frameworks in order to help them be more productive. Many similar finds have one thing in common, which is that the way they are written often leads to problems with the availability and performance of sites. For example, consider the following React component:
import React, { Component } from "react"; import { validateEmail } from "helpers/validation"; class SignupForm extends Component { constructor (props) { this.handleSubmit = this.handleSubmit.bind(this); this.updateEmail = this.updateEmail.bind(this); this.state.email = ""; } updateEmail (event) { this.setState({ email: event.target.value }); } handleSubmit () {
Here you can find several notable problems regarding the availability of the project:
- A form that does not use the
<form>
element is no longer a form. In fact, you can fix this by simply specifying the role = "form" of the parent <div>
element, but if you create a form, and what we see definitely looks like a form, use the <form>
element, adjusting it accordingly attributes action
and method
. The action
attribute plays an important role here, as it allows the form to do at least something, even if JavaScript is not available (of course, if the component was rendered on the server). - The
<span>
not a substitute for the <label>
, which provides some options regarding the availability of projects that <span>
does not have. - The
<button>
element without the type="submit"
attribute is simply a button that, when clicked, invokes the event handler attached to it. If we want to do something with the data before the form is onSubmit
, the button needs to assign the type="submit"
attribute, and move the code from the onClick
event handler to the onSubmit
form event handler. - By the way, why use JavaScript to validate your email address, while HTML5 provides us with controls that support validation of entered data in almost all browsers - up to IE10? Here we see the missed opportunity to use the functionality that already exists in the browser and apply the appropriate element type , as well as the required attribute. However, when applying such constructions, keep in mind that adjusting their normal interaction with screen reading programs will require some effort .
Taking into account the above, we will refactor the component code:
import React, { Component } from "react"; class SignupForm extends Component { constructor (props) { this.handleSubmit = this.handleSubmit.bind(this); } handleSubmit (event) {
Now that this component renders is not only more accessible, but also less JS code is used to implement the same functionality as before. In a world that literally drowned in JavaScript, getting rid of a few lines of code should be perceived as something positive. The browser gives us a
lot of opportunities , and we need to strive to use these opportunities as often as possible.
I don’t want to say here that problems with accessibility of pages arise exclusively when using certain frameworks. I mean that, overly relying on JavaScript, the developer will, in the end, simply miss out on a lot of important HTML and CSS features. These gaps in knowledge often lead to mistakes, and, we are not even aware of these mistakes. Frameworks can be useful tools that increase developer productivity, but continually exploring the capabilities of basic web technologies is extremely important in creating user-friendly, usable products, regardless of the supporting tools used in their development.
Rely on the capabilities of the web platform and ensure your projects a bright future.
Since we are talking about frameworks, it should be noted that the web platform, in itself, is also a huge framework. As was shown in the previous section, we find ourselves in a better position if we can rely on the established patterns of work with markup and on the capabilities of the browser. The alternative to these standard features is to reinvent them. Needless to say, such an “invention” is associated with considerable difficulties. But what if such problems, each in its own way, would be solved by the authors of all the JavaScript packages we install?
â–ŤSingle-page applications
One of the weaknesses of the developers, which they easily allow themselves, is to apply the Single Page Application (SPA) model even in those projects for which this model is not suitable. Of course, such projects benefit from the fact that they are perceived by users as more productive due to the routing performed by the client’s means. But what are the disadvantages of using the SPA model? The browser’s built-in browsing capabilities, although built on a synchronous model, give the project a lot of advantages. One of them is that the management of the history of visits is carried out through the implementation of
complex specifications . Users without JavaScript,
whether they have disabled it themselves or not , will not lose the opportunity to work with the project. In order for a one-page application to be available in browsers with disabled JavaScript, it suddenly turns out that you need to pay considerable attention to server rendering.
Comparison of different options for downloading an experimental application on a slow communication channel. The rendering of the application on the left is completely dependent on JavaScript. The application on the right is rendered on the server, but then it uses, on the client, the hydrate () method to connect the components to the markup already created on the server.Here you can see that the application, which is rendered on the client, shows the user a blank screen for a few seconds, and then displays the finished interface.
An application that is rendered on the server and brought to a working state on the client rather quickly displays the main interface elements, but you can use it after about the same time as the application that is rendered entirely on the client.
The availability of the application also suffers if the router located on the client cannot inform the user about what has changed on the page that he views. This can force the user to rely on assistive technologies in order to find out about what exactly has changed on the page, as a result, the user’s work with the site becomes much more complicated.
Further, here you can meet our old enemy - an excessive load on the system. Some client routers are very small. But if you make a project on
React , use a compatible
router , and, perhaps, a
library to manage the state of the application, this means that you have to accept that there will be a certain amount of service code in it, from which you can not escape. Namely, in this case it is about 135 Kb of such code. Carefully analyze the projects you create and whether client routing is worth the additional load on the system. It usually happens that it is better to refuse client routing.
If you are worried about the user's feelings, if you want the site to seem fast to him, then you can rely on the attribute of the links
rel = prefetch , which allows you to organize early loading of documents from the same source. Using this attribute has a tremendous impact on improving the performance of a project perceived by users, since the pages linked to this attribute, when clicked on these links, are instantly loaded from the cache. In addition, since data preloading has a low priority, it is unlikely to compete for bandwidth with important resources.
The HTML code, which is written / written, is preloaded when visiting the main page of the site. When a user clicks on the appropriate link, the HTML code is instantly loaded from the browser's cache.The main problem that may arise with the preloading of pages, and about which you need to know, is that such a load may be a waste of time and resources. To solve it, you can, for example, use a small
Quicklink script from Google, which mitigates this problem. It checks if the current client is using a slow connection, if the
data-saving mode is on , and, by default, avoids preloading materials from sources other than the page source.
In order to make the site look fast in the eyes of users who repeatedly visit it, you can use
service workers . They can be used regardless of whether the client is using a routing system or not, given that you are familiar with
some of the features of service workers. By
caching routes by means of service workers, we get many of the same advantages that are typical for pre-loading materials of some links, but we have much more extensive possibilities for working with requests and responses. Whether you perceive your site as an “application” or not, equipping it with a service worker, perhaps an example of one of the most important options for using JavaScript from existing ones.
AvaJavaScript is not designed to generate layouts
If we install a JS package designed for solving problems related to page layouts, then it’s time for us to exercise extreme caution and ask ourselves what we are trying to accomplish with this package. CSS was created
specifically for building page layouts, in order to use it effectively, no abstractions are needed. Most of the tasks of building layouts that try to solve with JavaScript tools, like
placing elements, aligning them, adjusting their sizes, like
managing text, or even completely
creating layouts with JavaScript, these days can be solved using CSS. Modern tools for creating layouts like Flexbox and Grid are well supported by browsers, so we do not need to develop projects based on frameworks for working with layouts. By the way, CSS is after all a framework too. When we have at our disposal such an opportunity as
property inquiries , the progressive improvement of layouts to support new tools for their formation, as it turns out, is
not such a difficult task .
/* , , , CSS Grid. */ /* @supports , CSS Grid, . */ @supports (display: grid) { /* */ @media (min-width: 40em) { /* CSS Grid */ } }
Using the capabilities of JavaScript to solve the problems of creating page layouts and customizing their appearance is not new. This is what we did in 2009 when we lived in an atmosphere of self-deception, saying that each site should look the same in IE6 as in the more advanced browsers of the time. If today, in 2019, we continue to develop websites so that they look the same in all browsers, this means that we need to revise our goals. There will always be some browsers that need to be supported and that do not have the same capabilities as the most modern browsers. The complete external similarity of projects on all platforms is not only a waste of energy, it is also the principal enemy of the idea of
progressive improvements .
Results: I'm not going to be a JavaScript killer
Do not get me wrong, I do not belong to the enemies of JavaScript. Thanks to this language, I built a career, and, frankly, JavaScript, for more than ten years, brings me a lot of pleasure. As happens in any long-term relationship, the more time I spend working with JavaScript, the better I will know it. This is a mature language with many possibilities, which is getting better every year.
However, sometimes it seems to me that in our relationship with JavaScript something went wrong. I criticize him. Or, more precisely, I criticize the current tendency to consider JavaScript to be the main tool for site building, which is resorted to first of all, not looking at anything else. When I analyzed another bundle that looked like a tangled Christmas garland, it became clear to me that the web was intoxicated with JavaScript. We use this language for almost any reason, even in cases where circumstances do not require it. Sometimes I think about how serious the consequences of such an attitude towards JS can be.
I plan to keep writing about javascript and web development, and keep looking for ways to make better use of web technologies. Hopefully together we will make the modern web better.
Dear readers! Do you think the modern web is really overloaded with JavaScript code?