Heim  >  Artikel  >  Web-Frontend  >  Tiefes Verständnis für JavaScript-Speicher- und Leistungsprobleme

Tiefes Verständnis für JavaScript-Speicher- und Leistungsprobleme

WBOY
WBOYnach vorne
2022-03-31 11:44:472118Durchsuche

Dieser Artikel vermittelt Ihnen relevantes Wissen über Javascript. Er stellt hauptsächlich die Speicher- und Leistungsprobleme von JavaScript vor, einschließlich der Lösung von Problemen wie zu vielen Schaltflächen, dem Löschen von Ereignishandlern usw. Ich hoffe, dass er für alle nützlich sein wird.

Tiefes Verständnis für JavaScript-Speicher- und Leistungsprobleme

Verwandte Empfehlungen: Javascript-Tutorial

1. Was ist JavaScript-Speicher und -Leistung? Da Ereignishandler in modernen Webanwendungen interaktiv sein können, verwenden viele Entwickler fälschlicherweise eine große Anzahl davon auf der Seite Bei JavaScript steht die Anzahl der Event-Handler auf einer Seite in direktem Zusammenhang mit der Gesamtleistung der Seite. Es gibt viele Gründe, wie zum Beispiel: ① Jede Funktion ist ein Objekt und belegt Speicherplatz. Je mehr Objekte vorhanden sind, desto schlechter ist die Leistung. ② Die Anzahl der DOM-Besuche, die für einen bestimmten Ereignishandler erforderlich sind, führt zunächst zu einer Verzögerung im gesamten Seiteninteraktion.

2. Sprechen Sie über die Leistungsprobleme von innerHTML?

1. Das negative Lehrmaterial der Verwendung von innerHTML

for(let value of values){
	ul.innerHTML += '
  • ${value}
  • ';}
    Dieser Code ist ineffizient, da innerHTML für jede Iteration einmal festgelegt werden muss, was bedeutet, dass innerHTML zuerst für jede Schleife gelesen werden muss Auf innerHTML wird zweimal in einer Schleife zugegriffen.

    <p></p>2. So lösen Sie

    let itemsHtml = "";for(let value of values){
    	itemsHtml  += '
  • ${value}
  • ';}ul.innerHTML = itemsHtml;
    Nach dieser Änderung wird nur innerHTML ein Wert zugewiesen. Der folgende Code kann dies auch tun:

    ul.innerHTML = Werte. map(value =&gt ; '<li>${value}</li>').join(' ');


    3. Wie löst man das Problem zu vieler Schaltflächen? ul.innerHTML = values.map(value => '<li>${value}</li>').join(' ');

    三、如何解决类似按钮过多问题?

    过多事件处理程序的解决方案是使用事件委托。事件委托利用事件冒泡,可以只使用一个事件处理程序来管理一种类型的事件。例如,click事件冒泡到document。这意味着可以为整个页面指定一个onclick事件处理程序,而不是为每个可点击元素分别指定事件处理程序。

    
    
    • 比比东
    • 云韵
    • 美杜莎

    这里包含三个列表项,在被点击时应该执行某个操作,通常的方式是指定三个事件处理程序:

    let item1 = document.getElementById("girl1");let item2 = document.getElementById("girl2");let item3 = document.getElementById("girl3");item1.addEventListener("click",(event) => {
    	console.log("我是比比东!");})item2.addEventListener("click",(event) => {
    	console.log("我是云韵!");})item3.addEventListener("click",(event) => {
    	console.log("我是美杜莎!");})

    相同代码太多,代码过于丑陋了。
    使用事件委托,只要给多有元素的共同的祖先节点添加一个事件处理程序,就可以解决丑陋!

    let list = document.getElementById("myGirls");list.addEventListener("click",(event) => {
    	let target = event.target;
    	switch(target.id){
    		case "girl1":
    			console.log("我是比比东!");
    			break;
    		case "girl2":
    			console.log("我是云韵!");
    			break;
    		case "girl3":
    			console.log("我是美杜莎!");
    			break;
    	}})

    四、事件委托的优点有哪些?

    • document对象随时可用,任何时候都可以为它添加一个事件处理程序(不用等待DOMContentLoaded或load事件),通过它处理页面中所有某种类型的事件。这意味着只要页面渲染出可点击的元素,就可以无延迟的起作用。

    • 节省花在设置页面事件程序上的事件。

    • 减少整个页面所需的内存,提升整体性能。

    五、删除事件处理程序

    把事件处理程序指定给元素后,在浏览器代码和负责页面交互的JavaScript代码之间就建立了联系。这种联系简历越多,页面性能就越差。除了通过事件委托来限制这种连接之外,还应该及时删除不用的事件处理程序。很多web应用性能不佳都是由于无用的事件处理程序长驻内存导致的。
    导致这个问题的原因有两个:

    1、删除带有事件处理程序的元素

    比如通过的DOM方法removeChild()或replaceChild()删除节点。最常见的还是使用innerHTML整体替换页面的某一部分。这时候,被innerHTML删除的元素上如果有事件处理程序,也不会被垃圾收集程序正常清理。
    所以,如果在得知某个元素会被删除之前,应手动删除它的事件处理程序,比如btn.onclick = null;//删除事件处理程序

    Die Lösung für zu viele Event-Handler ist die Verwendung der Event-Delegation. Die Ereignisdelegation nutzt das Event-Bubbling, sodass Sie nur einen Event-Handler zum Verwalten eines Ereignistyps verwenden können. Beispielsweise sprudelt das Klickereignis zum Dokument. Dies bedeutet, dass Sie einen Onclick-Ereignishandler für die gesamte Seite angeben können, anstatt für jedes anklickbare Element einen separaten Ereignishandler anzugeben.

    let ps = document.getElementsByTagName("p");for(let i = 0;i<ps.length let document.body.appendchild><strong>Dies enthält drei Listenelemente, die beim Klicken eine bestimmte Aktion ausführen sollen. Der übliche Weg besteht darin, drei Ereignishandler anzugeben: </strong><pre class="brush:php;toolbar:false">let ps = document.getElementsByTagName("p");for(let i = 0,len=ps.length;i<len let document.body.appendchild></len>

    Es gibt zu viele identische Codes und der Code ist zu hässlich.

    Mithilfe der Ereignisdelegation können Sie die Hässlichkeit lösen, indem Sie einfach einen Ereignishandler zum gemeinsamen Vorfahrenknoten mehrerer Elemente hinzufügen!

    let ps = document.getElementsByTagName("p");for(let i = ps.length-1;i>=0;--i){
    	let p = document.createElement("p");
    	document.body.appendChild(p);}
    4. Was sind die Vorteile der Event-Delegation? 🎜
    • 🎜Das Dokumentobjekt ist jederzeit verfügbar und Sie können ihm jederzeit einen Ereignishandler hinzufügen (ohne auf das DOMContentLoaded- oder Ladeereignis warten zu müssen). ), um die Seite durch alle Ereignisse irgendeiner Art zu verarbeiten. Das bedeutet, dass die Seite ohne Verzögerung funktioniert, solange sie anklickbare Elemente darstellt. 🎜
    • 🎜Sparen Sie Zeit beim Einrichten von Seitenereignisroutinen. 🎜
    • 🎜Reduzieren Sie den für die gesamte Seite erforderlichen Speicher und verbessern Sie die Gesamtleistung. 🎜
    🎜 5. Event-Handler löschen 🎜🎜Nach dem Zuweisen von Event-Handlern zu Elementen wird eine Verbindung zwischen dem Browsercode und dem für die Seiteninteraktion verantwortlichen JavaScript-Code hergestellt. Je öfter solche Kontakte wieder aufgenommen werden, desto schlechter wird die Seitenleistung. Zusätzlich zur Einschränkung solcher Verbindungen durch Ereignisdelegierung sollten nicht verwendete Ereignishandler umgehend entfernt werden. Die schlechte Leistung vieler Webanwendungen wird dadurch verursacht, dass nutzlose Event-Handler im Speicher verbleiben. 🎜 Es gibt zwei Gründe für dieses Problem: 🎜🎜🎜1. Elemente mit Event-Handlern löschen 🎜🎜🎜Zum Beispiel das Löschen von Knoten über die DOM-Methode „removeChild()“ oder „replaceChild()“. Am häufigsten wird innerHTML verwendet, um einen bestimmten Teil der Seite als Ganzes zu ersetzen. Wenn zu diesem Zeitpunkt ein Ereignishandler für das von innerHTML gelöschte Element vorhanden ist, wird es vom Garbage Collection-Programm nicht normal bereinigt. 🎜Wenn Sie also wissen, dass ein Element gelöscht wird, sollten Sie seinen Ereignishandler manuell löschen, z. B. btn.onclick = null;//Ereignishandler löschen. Die Ereignisdelegation hilft auch, dieses Problem zu lösen Wenn Sie wissen, dass ein Element durch innerHTML ersetzt werden soll, fügen Sie dem Element keinen Ereignishandler hinzu, sondern fügen Sie ihn einfach einem Knoten einer höheren Ebene hinzu. 🎜🎜🎜2. Das Entladen einer Seite kann auch das Problem verbleibender Referenzen im Speicher verursachen. 🎜🎜🎜Wenn die Ereignishandler nach dem Entladen der Seite nicht bereinigt werden, verbleiben sie weiterhin im Speicher. Danach erhöht sich jedes Mal, wenn der Browser die Seite lädt und entlädt (z. B. durch Vor- oder Zurückblättern oder Aktualisieren), die Anzahl der verbleibenden Objekte im Speicher, da die Ereignishandler nicht wiederverwendet werden. 🎜 Im Allgemeinen ist es am besten, alle Event-Handler im Onunload-Event-Handler zu löschen, bevor die Seite entladen wird. Auch hier zeigt sich der Vorteil der Event-Delegation. Da es nur wenige Event-Handler gibt, kann man sich leicht merken, welche man löschen muss. 🎜

    六、如何解决循环中动态添加p,造成的死循环问题?

    表达式

    let ps = document.getElementsByTagName("p");for(let i = 0;i

    表达式

    let ps = document.getElementsByTagName("p");for(let i = 0,len=ps.length;i

    表达式①中第一行取得了包含文档中所有<p></p>元素的HTMLCollection。因为这个集合是实时的,所以任何时候只要向页面中添加一个新的<p></p>元素,再查询这个集合就会多一项。因为浏览器不希望保存每次创建的集合,所以就会在每次访问时更新集合。每次循环都会求值i ,这意味着要获取所有<p></p>元素的查询。因为循环体中创建并向文档中添加一个新的<p></p>元素,所以每次循环ps.length的值也会递增。因为两个值都会递增,所以i永远不会等于ps.length,因此表达式①会造成死循环。
    而表达式②中,又初始化了一个保存集合长度的变量len,因为len保存着循环开始集合的长度,而这个值不会随集合增大动态增长(for循环中初始化变量处只会初始化一次),所以就可以避免表达式①中出现的无穷循环问题。
    如果不想初始化一个变量,也可以使用反向迭代:

    表达式

    let ps = document.getElementsByTagName("p");for(let i = ps.length-1;i>=0;--i){
    	let p = document.createElement("p");
    	document.body.appendChild(p);}

    七、JavaScript思维导图

    Tiefes Verständnis für JavaScript-Speicher- und Leistungsprobleme

    相关推荐:javascript教程

    Das obige ist der detaillierte Inhalt vonTiefes Verständnis für JavaScript-Speicher- und Leistungsprobleme. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

    Stellungnahme:
    Dieser Artikel ist reproduziert unter:csdn.net. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen