How to quickly get started with VUE3.0: Enter Learning
Related Recommendations: JavaScript Tutorial
event handlers can interact in modern web applications, many developers will mistakenly use a large number of them in the page. In JavaScript, the number of event handlers on a page is directly related to the overall performance of the page. There are many reasons, such as ① each function is an object and takes up memory space. The more objects there are, the worse the performance; ② The number of DOM visits required for a specified event handler will first cause a delay in the entire page interaction.
for (let value of values) { ul.innerHTML += '<li>${value}</li>';}
This code is inefficient because innerHTML must be set once for each iteration. Not only that, innerHTML must be read first for each loop, and That is to say, innerHTML needs to be accessed twice in one loop.
let itemsHtml = "";for(let value of values){ itemsHtml += '<li>${value}</li>';}ul.innerHTML = itemsHtml;
After this modification, the efficiency will be much higher. Only innerHTML will be assigned a value. The following code can also be done:
ul.innerHTML = values.map(value => '<li>${value}</li>').join(' ');
The solution to too many event handlers is to use event delegation. Event delegation leverages event bubbling, allowing you to use only one event handler to manage one type of event. For example, the click event bubbles up to the document. This means that you can specify an onclick event handler for the entire page, rather than specifying separate event handlers for each clickable element.
<ul id="myGirls"> <li id="girl1">Bibi Dong</li> <li id="girl2">Yun Yun</li> <li id="girl3">Medusa</li></ul>
This contains three list items that should perform a certain action when clicked. The usual way is to specify three event handlers:
let item1 = document.getElementById("girl1");let item2 = document.getElementById("girl2");let item3 = document.getElementById("girl3");item1.addEventListener("click",(event) => { console.log("I am Bibi Dong!");})item2.addEventListener("click",(event) => { console.log("I am Yunyun!");})item3.addEventListener("click",(event) => { console.log("I am Medusa!");})
There are too many identical codes and the code is too ugly.
Using event delegation, just add an event handler to the common ancestor node of multiple elements and you can solve the ugliness!
let list = document.getElementById("myGirls");list.addEventListener("click",(event) => { let target = event.target; switch(target.id){ case "girl1": console.log("I am Bibi Dong!"); break; case "girl2": console.log("I am Yunyun!"); break; case "girl3": console.log("I am Medusa!"); break; }})
The document object is available at any time, and you can add an event handler to it at any time (without waiting for DOMContentLoaded or load events), and use it to handle all events of some type in the page. This means that as long as the page renders clickable elements, it will work without delay.
Save time spent setting up page event routines.
Reduce the memory required for the entire page and improve overall performance.
By assigning event handlers to elements, a connection is established between the browser code and the JavaScript code responsible for page interaction. The more such contact resumes, the worse the page performance will be. In addition to limiting such connections through event delegation, unused event handlers should be promptly removed. The poor performance of many web applications is caused by useless event handlers remaining in memory.
There are two reasons for this problem:
such as deleting nodes through the DOM method removeChild() or replaceChild(). The most common one is to use innerHTML to replace a certain part of the page as a whole. At this time, if there is an event handler on the element deleted by innerHTML, it will not be cleaned up normally by the garbage collection program.
Therefore, if you know that an element will be deleted, you should manually delete its event handler, such as btn.onclick = null;//删除事件处理程序
. Event delegation can also help solve this problem. When an element is to be replaced by innerHTML, do not add an event handler to the element, just add it to a higher-level node.
If the event handlers are not cleaned up after the page is unloaded, they will still remain in the memory. After that, every time the browser loads and unloads the page (such as by going forward, back, or refreshing), the number of residual objects in memory increases because the event handlers are not recycled.
Generally speaking, it is best to delete all event handlers in the onunload event handler before the page is unloaded. The advantage of event delegation can also be seen at this time. Because there are few event handlers, it is easy to remember which ones to delete.
let ps = document.getElementsByTagName("p");for(let i = 0;i<ps.length;++i){ let p = document.createElement("p"); document.body.appendChild(p);}
let ps = document.getElementsByTagName("p");for(let i = 0,len=ps.length;i<len;++i){ let p = document.createElement("p"); document.body.appendChild(p);}
The first line in expression ① obtains an HTMLCollection containing all <p>
elements in the document. Because this collection is real-time, any time you add a new <p>
element to the page, and then query this collection, there will be one more item. Because the browser does not want to save the collection each time it is created, it will update the collection on each visit. Each loop will evaluate i < ps.length
, which means a query to get all <p>
elements. Because a new <p>
element is created and added to the document within the body of the loop, the value of ps.length will also be incremented each time through the loop. Because both values will be incremented, i will never equal ps.length
, so expression ① will cause an infinite loop.
In expression ②, a variable len that holds the length of the set is initialized, because len holds the length of the set at the beginning of the loop, and this value will not grow dynamically as the set increases ( for循环中初始化变量处只会初始化一次
) , so the infinite loop problem that appears in expression ① can be avoided.
If you do not want to initialize a variable, you can also use reverse iteration:
let ps = document.getElementsByTagName("p");for(let i = ps.length-1;i>=0;--i){ let p = document.createElement("p"); document.body.appendChild(p);}
Related recommendations: JavaScript Tutorial
The above is an in-depth understanding of the memory and performance issues of JavaScript. For more information, please pay attention to other related articles on the PHP Chinese website!