1. Scope-dependent

01 Avoid global search

Optimization lesson: Whenever a function has a global object referenced more than twice, you should save that object as a local variable.

Reason: If you define a global variable, you will experience scope-chain lookups when looking up the global variable in the local scope, so global variables are more time consuming than local variables.

Code analysis:

The first function refers to the global Document object three times, and if the page picture is very large, the for loop will refer to it hundreds of times, traversing the scope chain each time.

The second function optimizes this. A reference to the Document object is kept locally, so the scope chain is only looked up once, optimizing performance.

/ / before optimization
function updateUI() {
  let imgs = document.getElementsByTagName("img");
  for (let i = 0, len = imgs.length; i < len; i++) {
    imgs[i].title = '${document.title} image ${i}';
  }

  let msg = document.getElementById("msg");
  msg.innerHTML = "Update complete.";
}

/ / after optimization
function updateUI() {
  let doc = document;
  let imgs = doc.getElementsByTagName("img");
  for (let i = 0, len = imgs.length; i < len; i++) {
    imgs[i].title = '${doc.title} image ${i}';
  }

  let msg = doc.getElementById("msg");
  msg.innerHTML = "Update complete.";
}
Copy the code

02 Avoid using the with statement

Lesson learned: Do not use the with statement.

Reason: The with statement creates its own scope, thus lengthening the scope chain of the code, so it takes one more step to check the scope chain than it does without the with statement, so with is slower.

With Example (not recommended) :

function updateBody() {
	with(document.body){
		console.log(tagName); }}Copy the code

2. Js method correlation

01 Avoid unnecessary attribute lookup

Optimization lesson: Whenever you use an object’s deep property more than once, you should store it in local variables

Reason: When accessing the object, it is to find the prototype chain, the algorithm complexity is O(n), the more attributes to find, the longer the execution time.

Code analysis: the first code, there are six attribute searches, there are several points to find several times. Therefore, optimization should avoid using an object deep object multiple times and should be stored in local variables.

In the second code, there are only four attribute lookups after optimization, saving 33%

If you think about it, if the script is very large, this increase can significantly change performance.

/ / before optimization
let query = window.location.href.substring(window.location.href.indexOf("?"));

/ / after optimization
let url = window.location.href;
let query = url.substring(url.indexOf("?"));
Copy the code

02 Optimization cycle

Optimization experience and reasons:

(1) Simplify optimization conditions. It should be faster because the termination condition is computed for each loop.

(2) Simplified circulation body. Be sure to remove methods from the loop that can be evaluated outside the loop.

(3) Test cycle after use. The do-while is a post-test loop that avoids the initial evaluation of termination conditions. The for and while loops are test loops first.

Optimization analysis:

In the first loop condition, values. Length is queried I times, complexity O(n).

In the second loop condition, values. Length is queried once, complexity O(1), so performance is improved.

The third, which belongs to the post-test loop, values. Length is queried once, complexity O(1), and — I and I >=0 merge into one.

/ / before optimization
for (let i = 0; i < values.length; i++) {
  process(values[i]);
}
/ / after optimization
for (let i = values.length - 1; i >= 0; i--) {
  process(values[i]);
}

// After the test loop
let i = values.length-1;
if (i > -1) {
  do {
    process(values[i]);
  }while(--i >= 0);
}
Copy the code

03 Unwinding a loop

Optimization lesson: If the number of loops is finite, calling a function multiple times is faster than calling a function loop.

Reason: This saves on creating loops and calculating the cost of terminating loops, making the code faster.

Others: If the number of cycles is unpredictable, a technique called Duff’s Device can be used. The basic idea of the Duff device is to expand the loop into a series of statements by iterating in multiples of 8.

Code examples:

/ / after optimization
process(values[0]);
process(values[1]);
process(values[2]);
Copy the code

Avoid repeated explanations

Optimization lesson: Avoid writing strings with JS code in them.

Reason: If the code is contained in a string, the JS runtime must start a parser instance to parse the string code, and the instance parser is time-consuming.

Code examples:

// Evaluate code: do not
eval("console.log('Hello world! ')");

// Create a new function: do not
let sayHi = new Function("console.log('Hello world! ')");

// Set the timeout function: do not
setTimeout("console.log('Hello world! ')".500);
Copy the code

05 Other Performance Optimization precautions

1. Native methods are fast. Native methods are methods written in C++ or C, not JS, such as Math.

2. Switch statements are very fast. If you have complex if-else statements in your code, convert them to switch, putting the most likely ones first and the least likely ones last.

3. Bitwise operations are fast. Bitwise operations are faster than any Boolean or numerical calculation when performing mathematical operations. For complex calculation, it can improve efficiency.

3. Minimum optimization of statements

Optimization lesson: When declaring multiple variables, you can declare them using a let statement.

Reason: Declaring variables once is faster than declaring variables multiple times.

01 Multivariable declaration

/ / before optimization
// Four statements are wasted
let count = 5;
let color = "blue";
let values = [1.2.3];
let now = new Date(a);/ / after optimization
// A statement is better
let count = 5,
  color = "blue",
values = [1.2.3],
now = new Date(a);Copy the code

02 Insert iterative values

Optimization lesson: When encountering increasing or decreasing values, combine statements whenever possible.

Cause: Two executed statements can be combined into one statement

/ / before optimization
let name = values[i];
i++;
/ / after optimization
let name = values[i++]
Copy the code

03 Using array and object literals

Optimization lesson: Reduce statements when creating an array or object

/ / before optimization
// Create and initialize an array with four statements: waste
let values = new Array(a); values[0] = 123;
values[1] = 456;
values[2] = 789;

// Create and initialize objects with four statements: waste
let person = new Object(a); person.name ="Nicholas";
person.age = 29;
person.sayName = function() {
  console.log(this.name);
};

/ / after optimization
// a statement creates and initializes an array
let values = [123.456.789];

// a statement creates and initializes objects
let person = {
  name: "Nicholas".age: 29.sayName() {
    console.log(this.name); }};Copy the code

4. Optimize the Dom

First, why is it slow to manipulate the DOM?

Cause 1: The DOM contains thousands of pieces of information. Each time the DOM is accessed, the browser recalculates thousands of metrics before the update can be performed.

Cause 2: DOM belongs to V8 engine, js belongs to JS engine. Every time JS operates DOM, it means v8 engine and JS engine communicate once. Frequent DOM update means frequent communication between engines, which costs a lot and costs a lot for performance.

01 use createDocumentFragement

The DOM structure is built from document fragments, and when the DOM is modified, only the created document fragments are modified, eventually being added to the DOM at once.

After this modification, all you need to do is trigger a live update.

let list = document.getElementById("myList"),
  fragment = document.createDocumentFragment(),
  item;

for (let i = 0; i < 10; i++) {
  item = document.createElement("li");
  fragment.appendChild(item);
  item.appendChild(document.createTextNode("Item " + i));
}

list.appendChild(fragment);
Copy the code

02 use innerHTML

Optimization lesson: There are two ways to create A DOM node on a page, using createElement and innerHTML.

Reason: For a small number of updates, there’s not much difference, but for a large number of DOM updates, using innerHTML is much faster.

With one call to innerHTML, you’re actually creating a native DOM in the background, which is much faster than creating a NATIVE DOM in JS, which is interpreted code.

let list = document.getElementById("myList"),
  html = "";

for (let i = 0; i < 10; i++) {
  html += '<li>Item ${i}</li>';
}

list.innerHTML = html;
Copy the code

03 Using event delegate

The idea is to register events to the parent rather than to each individual child element to reduce trigger event listening.

04 note HTMlCollection

The most common way to do this is to access the length of an array, for example, in a for loop, every time the loop executes, it looks at the length of the array, and then it looks at the document, and that’s a very time-consuming query, so let’s look at the optimized example. Here we assign length to len, so we only query once.

Optimization idea: The goal is to reduce the number of queries and store these time-consuming things in temporary variables.

let images = document.getElementsByTagName("img");

for (let i = 0, len = images.length; i < len; i++) {
  / / processing
}
Copy the code

conclusion

The above is about some of the JS performance optimization needs to pay attention to matters, there are so many syntax in ES6, there are many optimization schemes, but the most critical is the idea of optimization, the subsequent development of each line of code to attach importance to the optimization, is an important part of becoming an excellent developer.