이 글은 javascript에 대한 관련 지식을 제공합니다. 버튼이 너무 많거나 이벤트 핸들러를 삭제하는 등의 문제를 해결하는 방법을 포함하여 JavaScript의 메모리 및 성능 문제를 주로 소개합니다. 모든 사람에게 도움이 되기를 바랍니다.
관련 권장 사항: javascript 튜토리얼
이벤트 핸들러는 최신 웹 애플리케이션에서 대화형일 수 있기 때문에 많은 개발자가 페이지에서 많은 수의 이벤트 핸들러를 실수로 사용하게 됩니다. 페이지의 이벤트 핸들러 수인 JavaScript는 페이지의 전반적인 성능과 직접적인 관련이 있습니다. 이유는 다양합니다. ① 각 함수는 객체이며 메모리 공간을 차지합니다. 객체가 많을수록 성능이 저하됩니다. ② 특정 이벤트 핸들러에 필요한 DOM 방문 횟수로 인해 전체 지연이 발생합니다. 페이지 상호 작용.
for(let value of values){ ul.innerHTML += '
innerHTML은 각 반복마다 한 번 설정해야 하기 때문에 비효율적입니다. 뿐만 아니라 각 루프마다 innerHTML을 먼저 읽어야 합니다. 하나의 루프 innerHTML에서 두 번 액세스됩니다.
let itemsHtml = "";for(let value of values){ itemsHtml += '
이 수정 후에는 innerHTML에만 값이 할당됩니다. ul.innerHTML = value.map (value => '<li>${value}</li>').join(' ');
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应用性能不佳都是由于无用的事件处理程序长驻内存导致的。
导致这个问题的原因有两个:
比如通过的DOM方法removeChild()或replaceChild()删除节点。最常见的还是使用innerHTML整体替换页面的某一部分。这时候,被innerHTML删除的元素上如果有事件处理程序,也不会被垃圾收集程序正常清理。
所以,如果在得知某个元素会被删除之前,应手动删除它的事件处理程序,比如btn.onclick = null;//删除事件处理程序
let ps = document.getElementsByTagName("p");for(let i = 0;i<ps.length let document.body.appendchild></ps.length>
let ps = document.getElementsByTagName("p");for(let i = 0,len=ps.length;i<len let document.body.appendchild><br>동일한 코드가 너무 많고 코드가 너무 보기 흉합니다. 이벤트 위임을 사용하면 여러 요소의 공통 조상 노드에 이벤트 핸들러를 추가하기만 하면 문제를 해결할 수 있습니다! 🎜<pre class="brush:php;toolbar:false">let ps = document.getElementsByTagName("p");for(let i = ps.length-1;i>=0;--i){ let p = document.createElement("p"); document.body.appendChild(p);}
btn.onclick = null;//Delete event handler
와 같은 해당 이벤트 핸들러를 수동으로 삭제해야 합니다. 이벤트 위임도 이 문제를 해결하는 데 도움이 됩니다. , 요소가 innerHTML로 대체된다는 것을 알고 있는 경우 요소에 이벤트 핸들러를 추가하지 말고 상위 수준 노드에 추가하기만 하면 됩니다. 🎜🎜🎜2. 페이지 언로드로 인해 메모리에 잔여 참조 문제가 발생할 수도 있습니다. 🎜🎜🎜페이지가 언로드된 후 이벤트 핸들러가 정리되지 않으면 여전히 메모리에 남아 있습니다. 그 후에는 브라우저가 페이지를 로드 및 언로드할 때마다(예: 앞으로 이동, 뒤로 이동, 새로 고침 등) 이벤트 핸들러가 재활용되지 않으므로 메모리에 남아 있는 개체 수가 늘어납니다. 🎜 일반적으로 페이지가 언로드되기 전에 onunload 이벤트 핸들러에서 모든 이벤트 핸들러를 삭제하는 것이 가장 좋습니다. 이벤트 위임의 장점도 이때 확인할 수 있습니다. 이벤트 핸들러가 적기 때문에 어떤 핸들러를 삭제할지 기억하기 쉽습니다. 🎜let ps = document.getElementsByTagName("p");for(let i = 0;i<ps.length let document.body.appendchild><h3><strong>表达式</strong></h3><pre class="brush:php;toolbar:false">let ps = document.getElementsByTagName("p");for(let i = 0,len=ps.length;i<len let document.body.appendchild><p>表达式①中第一行取得了包含文档中所有<code><p></p></code>元素的HTMLCollection。因为这个集合是实时的,所以任何时候只要向页面中添加一个新的<code><p></p></code>元素,再查询这个集合就会多一项。因为浏览器不希望保存每次创建的集合,所以就会在每次访问时更新集合。每次循环都会求值<code>i ,这意味着要获取所有<code><p></p></code>元素的查询。因为循环体中创建并向文档中添加一个新的<code><p></p></code>元素,所以每次循环ps.length的值也会递增。因为两个值都会递增,所以i永远不会等于<code>ps.length</code>,因此表达式①会造成死循环。<br> 而表达式②中,又初始化了一个保存集合长度的变量len,因为len保存着循环开始集合的长度,而这个值不会随集合增大动态增长(<code>for循环中初始化变量处只会初始化一次</code>),所以就可以避免表达式①中出现的无穷循环问题。<br> 如果不想初始化一个变量,也可以使用反向迭代:</code></p> <h3><strong>表达式</strong></h3> <pre class="brush:php;toolbar:false">let ps = document.getElementsByTagName("p");for(let i = ps.length-1;i>=0;--i){ let p = document.createElement("p"); document.body.appendChild(p);}
相关推荐:javascript教程
위 내용은 JavaScript 메모리 및 성능 문제에 대한 깊은 이해의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!