⬆️ ⬇️

How to improve the performance of frontend web applications: five tips





In many of my front-end projects, at some point I came across a decrease in performance — this usually happens when the complexity of the application increases, and this is normal. Nevertheless, developers are still responsible for performance, so in my article I will give five tips for optimizing applications that I use myself: some may seem obvious, some affect the basic principles of programming - but, I think, it's not enough to refresh memory will be. Each tip is backed by tests: you can run them yourself and check the performance.



Transferred to Alconost



Foreword



Remember: if code optimization is not needed, do not meddle in it. Of course, the code you write should work quickly, and you can always come up with a faster algorithm - but what you write should remain clear to other developers. In the lecture “Programming as an art” Donald Knut made a very important thought about code optimization:

')

The real problem was that programmers spent too much time worrying about efficiency in inappropriate places and in inappropriate time. Premature optimization is the root of all programming errors (or at least most).



1. Search: instead of ordinary arrays - objects and associative arrays



When working with data, there are often situations when you need to, for example, find an object, do something with it, then find another object, and so on. The most common data structure in JS is an array, so storing data in it is a normal practice. However, whenever you need to find something in the array, you have to use such methods as “find”, “indexOf”, “filter”, or iterate with cycles — that is, you need to iterate through the elements from beginning to end. Thus, we perform a linear search, the complexity of which is 0 (n) (in the worst case, we will need to perform as many comparisons as there are elements in the array). If you do this operation a couple of times on small arrays, the performance impact will be small. However, if we have a lot of elements, and the operation is performed many times, the performance will surely squeeze.



In this case, a good solution would be to convert an ordinary array into an object or an associative array and perform a search by keys: in these structures, access to the elements can be obtained with complexity O (1) - we will have one memory call, regardless of size. Increasing the speed of work is achieved through the use of a data structure called a hash table .



You can test performance here: https://jsperf.com/finding-element-object-vs-map-vs-array/1 . Below are my results:







The difference is very significant: for the associative array and the object, I got millions of operations per second, whereas for the array the best result is just over a hundred operations. Of course, data conversion is not taken into account here, but even taking into account its operation, it will be performed much faster.



2. Instead of exceptions - the conditional operator "if"



Sometimes it seems that it is easier to skip checking for “null” and just catch the relevant exceptions. This, of course, is a bad habit - you don’t need to do that, and if you have it in your code, just rewrite the relevant sections. But in order to finally convince you, I will back up this recommendation with tests. I decided to test three ways to do the checks: a try-catch statement, an if condition, and a “short circuit” calculation.



Test: https://jsperf.com/try-catch-vs-conditions/1 . Below are my results:







I think it is obvious from here that it is necessary to check for “null”. In addition, as you can see, there is almost no difference between the “if” condition and the “short circuit” calculation - to which the soul lies, then apply.



3. The fewer cycles, the better.



Another obvious, but perhaps not indisputable consideration. There are many convenient functions for arrays: “map”, “filter”, “reduce” - that is why their use looks tempting, and the code with them looks neater and is easier to read. But when it comes to improving performance, you can try to reduce the number of called functions. I decided to parse two cases: 1) “filter”, then “map”, and 2) “filter”, then “reduce” - and compare them with the functional chain, “forEach” and the traditional “for” cycle. Why these two cases? From the tests it will be seen that the benefits obtained may not be very significant. In addition, in the second case, I also tried using “filter” when calling “reduce”.



Performance test for “filter” and “map”: https://jsperf.com/array-function-chains-vs-single-loop-filter-map/1 . My results:







It can be seen that one cycle is faster, but the difference is small. The reason for such a small margin is the “push” operation, which is not required when using the “map”. Therefore, in this case, you can think about whether it is really necessary to go to one cycle.



Now let's check “filter” + “reduce”: https://jsperf.com/array-function-chains-vs-single-loop-filter-reduce/1 . My results:







Here the difference is already significant: the unification of two functions into one accelerated the implementation of almost doubled. However, the transition to the traditional “for” cycle gives a much more significant increase in speed.



4. Use regular “for” loops



This advice may also seem controversial, because developers love functional cycles: they are well read and can simplify work. However, they are less effective than traditional cycles. I think you may have noticed the difference in the use of “for” cycles, but let's take a look at it in a separate test: https://jsperf.com/for-loops-in-few-different-ways/ . As you can see, besides the built-in mechanisms, I also checked “forEach” from the “Lodash” library and “each” from “jQuery”. Results:







And again we see that the simplest “for” loop works much faster than the others. True, these cycles are good only for arrays - in the case of other iterated objects, use "forEach", "for ... of" or directly the iterator. But “for ... in" should be used only if there are no other ways at all. In addition, remember that “for ... in" accepts all the properties of an object (and in the array properties are indices), which can lead to unpredictable results. Surprisingly, the methods from Lodash and jQuery were not so bad in terms of performance, so in some cases you can safely use them instead of the built-in “forEach” (interestingly, the test from Lodash worked faster than the built-in).



5. Use built-in functions for working with DOM.



Sometimes you look at someone else's code and see that the developer imported jQuery only for DOM manipulations - I am sure that you also encountered this, because this is one of the most popular JavaScript libraries. It is clear that there is nothing wrong with using libraries to control the DOM: today we use React and Angular, and they do the same. However, it sometimes seems to some that jQuery needs to be used even for simple operations to extract an element from the DOM and make minor changes to it.



Here is a comparison of the built-in functions for DOM and similar jQuery operations in three different cases: https://jsperf.com/native-dom-functions-vs-jquery/1 . My results:







Again, the most basic functions — getElementById and getElementsByClassName — turned out to be the fastest when viewing the DOM. In the case of identifiers and extended selectors, “querySelector” is also faster than jQuery. And only in one case “querySelectorAll” is slower than jQuery (getting items by class name). Learn more about how and how to replace jQuery, see here: http://youmightnotneedjquery.com .



It is clear that if you already use the library to manage the DOM, it is strongly recommended that you stick to it - however, for simple cases, the built-in tools are sufficient.



Additional materials



These five tips will help write more “fast” code in JavaScript. But if you're interested in reading more about performance optimization, here are a few recommendations:



1. Optimization of JavaScript bundles using the Webpack: this is a very broad topic, but if everything is done correctly, the download of applications can be greatly accelerated.



2. Data structures, basic algorithms and their complexity: many believe that this is “just a theory”, but in the very first paragraph we saw how this theory works in practice.



3. Tests on the jsPerf page: here you can familiarize yourself with comparing different ways of performing the same task in JavaScript and at the same time see an important indicator in practice - the difference in speed.



About the translator



Translation of the article is made in Alconost.



Alconost is engaged in the localization of games , applications and websites in 70 languages. Language translators, linguistic testing, cloud platform with API, continuous localization, 24/7 project managers, any string resource formats.



We also make advertising and training videos - for sites selling, image, advertising, training, teasers, expliners, trailers for Google Play and the App Store.



Read more

Source: https://habr.com/ru/post/456808/



All Articles