Home  >  Article  >  Web Front-end  >  JavaScript optimized DOM

JavaScript optimized DOM

php中世界最好的语言
php中世界最好的语言Original
2018-03-19 16:27:091868browse

This time I will bring you JavaScript to optimize the DOM, and what are the precautions for optimizing the DOM in JavaScript. The following is a practical case, let’s take a look.

Optimizing DOM must start with redrawing and rearrangement, long long ago...

1. Redrawing and rearrangement

1.1 What are redrawing and rearranging

Redrawing refers to some style modifications, and the position and size of the elements have not changed;

Rearrangement means that the position or size of an element has changed, and the browser needs to recalculate the rendering tree. After the new rendering tree is established, the browser will redraw the affected elements.

1.2 Browser rendering page

When you go to an interview, you will always be asked a question, that is, "Enter a line of url into the browser." What happened?", the answer to this question involves not only network knowledge but also the issue of browser rendering of the page. When our browser receives the page responded from the server, it starts rendering line by line. When it encounters css, it will asynchronously calculate the attribute value, and then continue to parse the dom downwards. After the parsing is completed, a DOM tree will be formed, which will be asynchronousThe calculated style (style box) is combined with the DOM tree to form a Render tree, which is then drawn on the page by the browser. The difference between the DOM tree and the Render tree is that nodes with the style display:none; will be in the DOM tree but not in the render tree. After the browser draws it, it starts to parse the js file, and determines whether to redraw and reflow based on the js.

1.3 Reasons for redrawing and rearrangement

Factors that cause redrawing:

Factors causing rearrangement:

In short, you must know that js is single-threaded , redrawing and reflowing will block user operations and affect the performance of the web page. When a page is redrawn and reflowed multiple times, such as writing a timer to change the width and height of page elements every 500ms, the page may become It’s getting more and more laggy, so we need to reduce redrawing and reflowing as much as possible. Then our optimization of DOM is also based on this starting point.

2. Optimization

2.1 Reduce access

Reducing the number of accesses naturally means caching elements, but you must pay attention

var ele = document.getElementById('ele');

This does not cache ele. Each time ele is called, it is equivalent to visiting the node with the ID ele.

2.1.1 Cache NodeList

var foods = document.getElementsByClassName('food');

We can use foods[i] to access the i-th element with class food, but the foods here are not an array , but a NodeList. NodeList is an array-like array that stores some ordered nodes and can access these nodes by position. NodeList objects are dynamic and a document-based query is run on each access. Therefore, we need to minimize the number of visits to NodeList, and we can consider caching the value of NodeList.

// 优化前var lis = document.getElementsByTagName('li');for(var i = 0; i < lis.length; i++) {     // do something...  }// 优化后,将length的值缓存起来就不会每次都去查询length的值var lis = document.getElementsByTagName('li');for(var i = 0, len = lis.length; i < len; i++) {     // do something...  }

And because NodeList changes dynamically, if it is not cached, it may cause an infinite loop, such as adding elements while getting the length of NodeList.

2.1.2 Change the selector

There are two most common ways to get elements, getElementsByXXX() and queryselectorAll(). The difference between these two selectors is very big. The former is to get Dynamic collection, the latter is to obtain a static collection, for example.

// 假设一开始有2个livar lis = document.getElementsByTagName('li');  // 动态集合var ul = document.getElementsByTagName('ul')[0]; 
for(var i = 0; i < 3; i++) {
    console.log(lis.length);    var newLi = document.createElement('li'); 
    ul.appendChild(newLi);
}// 输出结果:2, 3, 4var lis = document.querySelector('li');  // 静态集合 var ul = document.getElementsByTagName('ul')[0]; 
for(var i = 0; i < 3; i++) {
    console.log(lis.length);    var newLi = document.createElement('li'); 
    ul.appendChild(newLi);
}// 输出结果:2, 2, 2

Operations on static collections will not cause re-querying of documents, which is more optimized than dynamic collections.

2.1.3 Avoid unnecessary loops

// 优化前
for(var i = 0; i < 10; i++) {
    document.getElementById('ele').innerHTML += 'a';
} 
// 优化后 
var str = ''; 
for(var i = 0; i < 10; i++) {
    str += 'a'; 
}
document.getElementById('ele').innerHTML = str;

The pre-optimized code accesses the ele element 10 times, while the optimized code only accesses it once, which greatly improves efficiency.

2.1.4 Event Delegate

The event functions in js are all objects. If there are too many event functions, they will occupy a lot of memory, and the more DOM elements that are bound to the event, the more time it will take to access the dom. times, there will also be a delay in the interactive readiness time of the page. Therefore, event delegation was born. Event delegation uses event bubbling. Only one event processing program can manage all events of a certain type.

// 事件委托前var lis = document.getElementsByTagName('li');for(var i = 0; i < lis.length; i++) {
   lis[i].onclick = function() {
      console.log(this.innerHTML);
   };  
}    
// 事件委托后var ul = document.getElementsByTagName('ul')[0];
ul.onclick = function(event) {
   console.log(event.target.innerHTML);
};

Before event delegation, we visited lis.length times li, but after using event delegation, we only visited ul once.

2.2 Reduce redrawing and rearrangement

2.2.1 Change multiple styles of a DOM node

We want to change the width and height of a p element. The usual approach can be like this

 p = document.getElementById('p1'

The above operation changed two attributes of the element, accessed the dom three times, and triggered two rearrangements and two rearrangements. painted. We have said that optimization is to reduce the number of visits and the number of redraws and rearrangements. From this starting point, can we only access the element once and reduce the number of rearrangements to 1? Obviously it is possible, we can write a class in css

/* css
.change {
    width: 220px;
    height: 300px;
}*/document.getElementById('p').className = 'change';

This way we can operate multiple styles at one time

2.2.2 Modify the dom node styles in batches

Above The code is for a DOM node. What if we want to change the style of a DOM collection?

The first method that comes to mind is to traverse the collection and add a className to each node. Think about it again, doesn't this mean that you have visited the DOM node multiple times? Think about the difference between the DOM tree and the rendering tree mentioned at the beginning of the article. If the display attribute of a node is none, then this node will not exist in the render tree, which means that the operation of this node will not affect the render tree and will not cause Redrawing and rearranging, based on this idea we can achieve optimization:

  • Display the parent element of the collection to be modified: none;

  • 之后遍历修改集合节点

  • 将集合父元素display: block;

// 假设增加的class为.changevar lis = document.getElementsByTagName('li');  
var ul = document.getElementsByTagName('ul')[0];
ul.style.display = 'none';for(var i = 0; i < lis.length; i++) {
    lis[i].className = 'change';  
}
ul.style.display = 'block';

3、总结

  • 减少访问dom的次数

    • 缓存节点属性值

    • 选择器的使用

    • 避免不必要的循环

    • 事件委托

  • 减少重绘与重排

    • 使用className改变多个样式

    • 使父元素脱离文档流再恢复

相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!

推荐阅读:

Vue的计算属性

Webpack模块的使用

The above is the detailed content of JavaScript optimized DOM. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn