What is faster JavaScript or jQuery

Optimize Javascript - loading time and response time

Readability vs size

It takes a while to figure out that the legibility of scripts is more important than brevity and speed. Saving with variable names and using abbreviations quickly strike back when changes need to be made or small errors need to be corrected. After a few days, the twisted paths of logic are forgotten and time flies by comprehending the trains of thought.

Minifiers such as Uglify and compression with gzip reduce the size of the Javascript code and accelerate scripts more effectively than shorthands.

jQuery is a brake

With the departure of the old browser, jQuery no longer has to be used for every operation, even if jQuery is already loaded in the project anyway. Javascript has achieved a high level of consistency when manipulating the DOM in modern browsers. Native Javascript (Vanilla Javascript) offers just as comfortable selectors as jQuery, even if querySelector and querySelectorAll mean more typing. In any case, native Javascript is significantly faster for DOM operations.

It doesn't always have to be $ (), even if the paperwork is more complex.

$ ('input'). keyup (function () {if ($ (this) .val () == 'tata') {…}});

gets twice as fast with the native this

document.querySelector ('input'). onkeyup = function () {if (this.val () == 'tata') {…}};

And that also applies here:

jQuery
$ (el) .find (selector) .length;
Native Javascript (without jQuery)
el.querySelector (selector)! == null

Of course, we have to be aware that there is more to jQuery than simply accessing and manipulating elements of the DOM. Above all, jQuery protects against browser inconsistencies and errors.

CDN - Content Delivery Network

A CDN is not a panacea for short loading times. Local projects, which are mainly aimed at a country and for which there is no local server, increase the loading time. A CDN shortens the loading time for an international website, with a local website a CDN can have exactly the opposite effect: delivery time instead of loading time.

A large part of all websites today is served by HTTP2. Now HTTP2 is not that much faster than HTTP1.1, but HTTP2 multiplexes connections, where new connections have to be established for files from the CDN.

CDNs from which we get open source projects must also always be kept an eye on (advertising popup: Twitter Share Count).

CSS instead of Javascript as much as possible

CSS3 replaces many effects that were previously set into the website using Javascript. For an animated hamburger icon that is animated with CSS, neither an icon font nor Javascript is required.

Just a few lines of CSS are enough for a simple slideshow, and the images fly in, without any jQuery or Javascript.

Even more complex slideshows run without Javascript: CSS slideshow with timeline

Keep Javascript variables consistent

Javascript is dynamically typed - I can use a variable for integer values ​​and then for a string. The variables are kept consistent for fast Javascript.

Arrays

An array can be built up as follows:

let days; days [0] = "Monday"; days [1] = "Tuesday"; days [2] = "Wednesday"; ...

It's faster like this:

let days = ["Monday", "Tuesday", "Wednesday", ... "Sunday"];

Fast loops

Loops or loops are the be-all and end-all of any application and they can be designed faster with optimized conditions.

for (let i = 0; i Better and easier to read

let rows = document.getElementsByTagName ('tr'); for (let i = 0; i Selectors for loops are always saved in a variable (let rows = document.getElementsByTagName ('tr')) instead of extracting them from the DOM again in each pass.

However, neither of these two variants is really efficient. getElementsByTagName does not return a static array, but a dynamic object. Every time the condition is checked, the browser needs to access the object and calculate the number of objects referenced to use the property length return.

It looks similar with the index used. The object must be calculated three times for each run through the for loop. These codes are better, although the first variant is usually the better:

let rows = document.getElementsByTagName ('tr'); for (let i = 0, row; row = rows [i]; i ++) {row.className = 'newclass'; row.style.color = 'red'; ...} let rows = document.getElementsByTagName ('tr'); for (let i = rows.length-1; i> -1; i--) {let row = rows [i]; row.className = 'newclass'; row.style.color = 'red'; ...}

Javascript Abbreviations (&&)

The short circuit operator (&&) helps optimize conditional statements and allows expensive operations to be carried out after less expensive conditions have already been successfully checked: the second condition is only evaluated when the first condition is met. So you put the more complex exam back.

The || operator works similarly and evaluates the second condition only if the first condition is not met. If two conditions are present, but only one condition has to be fulfilled so that the script can be continued, the less complex condition is set to the front so that the second condition only has to be checked if the first condition does not apply.

Access to elements

The DOM provides many methods for accessing elements and you can quickly get used to extensive use of childNodes, siblings, parentNodes and tagNames. This technique is both unreliable and slow, especially when adding and removing elements in the document. In addition, one should always keep in mind that white space between the elements becomes a childNode. getElementById is convenient access to an individual element, however querySelector and querySelectorAll are the equivalent of jQuery $ (), offer a consistent notation and reach all elements via CSS selectors.

Access to several elements is required again and again, e.g. to all h-headings in a document. We can access the h elements with getElementsByTagName ('*'), but that would access far too many elements and make the loops significantly slower. This route should only be taken if the headers are required in the correct order.

let headers = document.getElementsByTagName ('*'); for (let i = 0, oElement; oElement = headers [i]; i ++) {if (oElement.tagName.match (/ ^ h [1-6] $ / i) {...}}

This technique is better:

for (let i = 1; i <7; i ++) {let headers = document.getElementsByTagName ('h' + i); for (let j = 0, oElement; oElement = headers [j]; j ++) {...}}

Minimize rebuilding one side

Every time an element is inserted into a document, the browser has to rebuild the flow of elements on the page, repositioning elements, and rendering. The more that is inserted, the more that has to be rebuilt. So you reduce the number of items that are added so that the browser doesn't have to reorganize as often.

If an element with several children is added, the children are first inserted into the element and only then the element is inserted into the document, so that the browser can manage with a single restructuring. If several sibling elements are not inserted as children of a new element, you can use a document fragment, place the elements there, and then insert the document fragment into the document. The elements are then housed as siblings in a single restructuring.

let foo = document.createDocumentFragment (); foo.appendChild (document.createElement ('p')); foo.firstChild.appendChild (document.createTextNode ('Test')); foo.lastChild.appendChild (document.createTextNode ('Me')); foo.firstChild.style.color = 'green'; document.body.appendChild (foo);

The same applies to the text and styles of an element: First the content and styles are inserted and only then the element is placed in the document.

Add multiple styles via Javascript

This is what pasting multiple styles looks like over and over again:

elem.style.position = 'absolute'; elem.style.top = '0px'; elem.style.left = '0px'; ... Etc ...

This is awesome because it uses the outdated DHTML approach and is really slow. We could take the DOM and put in regular CSS in a single restructuring:

oElement.setAttribute ('style', 'position: absolute; top: 0px; left: 0px; ... ...');

However, it is more efficient to use a CSS class straight away and define the class in the CSS.

oElement.setAttribute ('class', 'myClass');

classList.add, classList.remove and classList.toggle are convenient alternatives for all modern browsers. Internet Explorer supports classList version 10 and higher, but there is a Polyfil for classList for IE9 at github.

Anonymous functions

We want to change the background color of a table row on mouseover and reset it on mouseout. Let's write the classic like this:

if (document.getElementsByTagName) {let rows = document.getElementsByTagName ('tr'); for (let i = 0, row; row = rows [i]; i ++) {row.mouseover = over; row.mouseout = out; }} function over () {this.setAttribute ('style', 'background: silver'); } function out () {this.setAttribute ('style', 'background: blue'); }

Since the over () and out () functions are so simple, we can register them as anonymous functions:

for (let i = 0, row; row = rows [i]; i ++) {row.mouseover = function (event) {this.setAttribute ('style', 'background: silver'); } row.mouseout = function (event) {this.setAttribute ('style', 'background: blue'); }}

(The parameter event is optional)
This works just as well, but keeps the code together better. This construct is also OK:

obj.onclick = function (event) {functionOne (); functionTwo (); }

Search strings - String Matching

There are two basic techniques that can search a string for a string and either get the position of the hit or -1 (not found). The first uses 'indexOf' to find out the position of the substring in the string. The second technique is 'search' or an equivalent method to find a search pattern with a regular expression. string.search () is faster than string.indexOf. Only if the search pattern is very simple should indexOf can be used in place of the regular expression. match() or search () should also be avoided if the string is very long (10KB and more).

If regular expressions with many wildcards are used, the search for a character string is also significantly slower. Repeatedly replacing substrings is also costly.

Sensible recycling

If the search pattern of a regular expression is used repeatedly, it should be generated once and saved as a variable so that the browser can optimize the search. In the example, the two regular expressions are treated separately and waste resources:

if (a == 1 && oNode.nodeValue.match (/ ^ \ s * extra. * free / g)) {// creates the first copy} else if (a == 2 && oNode.nextSibling.nodeValue.match ( /^\s*extra.*free/g)) {// creates the second copy}

The following instructions work identically, but more efficiently, as the browser only needs to make a copy of the regular expression:

let oExpr = /^\s*extra.*free/g; if (a == 1 && oNode.nodeValue.match (oExpr)) {// uses the existing variable} else if (a == 2 && oNode.nextSibling.nodeValue.match (oExpr)) {// also uses the existing one Variable}

In principle, the saved expression does not have to be deleted or set to zero when the search is finished. The script engine performs the garbage collection and the deletion is an unnecessary additional operation.

If it was defined inline in a loop, each instance of a regular expression is only generated once and is automatically cached for the next access in the loop. But if we create multiple instances of the same expression inside the loop, each will be created and cached separately, as we can see above.

for (let i = 0, oNode; oNode = oElement.childNodes [i]; i ++) {if (oNode.nodeValue.match (/ ^ \ s * extra. * free / g)) {// generates the expression // is cached and reused the next time it is run through the loop}}

This does not apply to the syntax, which always creates a new copy of the expression and is generally slower than the creation of a static expression. So it should be avoided as much as possible in loops.

Inline scripts

Javascript inline scripts like <body onload="javascript: start()"> and <input onclick="" ... /> slow down the construction of a page because the browser has to assume that an inline script changes the structure of the page. But today hardly anyone does ...

eval is sneaky

Both the method eval as well as related constructs like new function are wasters.

When a page is loaded, a new instance of the Javascript interpreter is started and a scripting environment is created (also known as a "thread"). The call of eval starts another interpreter with a new environment and imports the variables of the first environment into the new environment. When the eval call is completed, it exports the variables back to their original environment and collects the junk. On top of that, the code cannot be cached for optimization.

Eval () is no longer allowed with useStrict.

Just listen to what is needed

Every time a new event handler is registered, the scripting engine begins listening in and firing on the event. Each additional event handler puts an additional load on the engine.

Avoid unnecessary code

If a script should only run under certain conditions, the conditions are formulated as clearly as possible and the script is stopped immediately if the conditions are not met. If the script is inside a function - which will be the case with most of the JavaScript code - the function can use return be left immediately.

Around for- or while- Leaving instructions will break called, continue skips large blocks in for and while statements. For example, if a script searches all a-tags of a document to find an href attribute with a link to a CSS file, the for- Statement to be exited immediately when the CSS file is found. When a return is not possible because a function after the forStatement should be executed further, a variable could be defined and used as an additional condition in the for- Instruction to be accommodated. It is, however, easier that for-Easy to cancel instruction:

document.addEventListener ('load', function () {let elem = document.querySelectorAll ('. link'); for (i = 0, elem; elem = elem [i]; x ++) {if (elem.getAttribute (' href '). match (/ \ / old.css $ /)) {elem.setAttribute (' href ',' styles / new.css'); break;}}});

Timers cost precious time

setInterval and setTimeout are used for animation effects. Each of these methods creates an additional thread for each timeout created and if the browser executes several timeouts simultaneously, the performance goes downhill. It's not a problem with one or two timers, but as soon as it turns five or ten, the loss of speed becomes apparent. In addition, timers belong to the eval family of methods, so that they are inefficient in several ways.

requestAnimationFrame is more efficient and is called up 60 times per second by default - more is rarely necessary.

let iterationCount = 0; let repeater; function runlock () {easing = easeInQuad (iterationCount, 0, width, 300); lok.setAttribute ('style', 'left:' + easing + 'px'); iterationCount ++; if (iterationCount> 250) {cancelAnimationFrame (repeater); } else {repeater = requestAnimationFrame (runlock); }} runlock ();

Animation with a mixture of Javascript and CSS animation or transformations are even more efficient.

External sources