JavaScript 메모리 및 성능 문제에 대한 깊은 이해

WBOY
풀어 주다: 2022-03-31 11:44:47
앞으로
2031명이 탐색했습니다.

이 글은javascript에 대한 관련 지식을 제공합니다. 버튼이 너무 많거나 이벤트 핸들러를 삭제하는 등의 문제를 해결하는 방법을 포함하여 JavaScript의 메모리 및 성능 문제를 주로 소개합니다. 모든 사람에게 도움이 되기를 바랍니다.

JavaScript 메모리 및 성능 문제에 대한 깊은 이해

관련 권장 사항:javascript 튜토리얼

1. JavaScript 메모리 및 성능이란 무엇입니까

이벤트 핸들러는 최신 웹 애플리케이션에서 대화형일 수 있기 때문에 많은 개발자가 페이지에서 많은 수의 이벤트 핸들러를 실수로 사용하게 됩니다. 페이지의 이벤트 핸들러 수인 JavaScript는 페이지의 전반적인 성능과 직접적인 관련이 있습니다. 이유는 다양합니다. ① 각 함수는 객체이며 메모리 공간을 차지합니다. 객체가 많을수록 성능이 저하됩니다. ② 특정 이벤트 핸들러에 필요한 DOM 방문 횟수로 인해 전체 지연이 발생합니다. 페이지 상호 작용.

2. innerHTML의 성능 문제에 대해 이야기하시나요?

1. innerHTML 사용의 부정적인 교육 자료

for(let value of values){ ul.innerHTML += '
로그인 후 복사
  • ${value}
  • ';}

    innerHTML은 각 반복마다 한 번 설정해야 하기 때문에 비효율적입니다. 뿐만 아니라 각 루프마다 innerHTML을 먼저 읽어야 합니다. 하나의 루프 innerHTML에서 두 번 액세스됩니다.

    2. 해결 방법

    let itemsHtml = "";for(let value of values){ itemsHtml += '
    로그인 후 복사
  • ${value}
  • ';}ul.innerHTML = itemsHtml;

    이 수정 후에는 innerHTML에만 값이 할당됩니다.
    ul.innerHTML = value.map (value => '

  • ${value}
  • ').join(' ');ul.innerHTML = values.map(value => '
  • ${value}
  • ').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;//删除事件处理程序

    3. 버튼이 너무 많은 문제를 해결하는 방법은 무엇인가요?

    너무 많은 이벤트 핸들러에 대한 해결책은 이벤트 위임을 사용하는 것입니다. 이벤트 위임은 이벤트 버블링을 활용하므로 하나의 이벤트 핸들러만 사용하여 한 가지 유형의 이벤트를 관리할 수 있습니다. 예를 들어 클릭 이벤트가 문서까지 버블링됩니다. 이는 클릭 가능한 각 요소에 대해 별도의 이벤트 핸들러를 지정하는 대신 전체 페이지에 대해 onclick 이벤트 핸들러를 지정할 수 있음을 의미합니다.
    let ps = document.getElementsByTagName("p");for(let i = 0;i
    로그인 후 복사

    여기에는 클릭 시 특정 작업을 수행해야 하는 세 가지 목록 항목이 포함되어 있습니다. 일반적인 방법은 세 가지 이벤트 핸들러를 지정하는 것입니다.

    let ps = document.getElementsByTagName("p");for(let i = 0,len=ps.length;i
    동일한 코드가 너무 많고 코드가 너무 보기 흉합니다. 이벤트 위임을 사용하면 여러 요소의 공통 조상 노드에 이벤트 핸들러를 추가하기만 하면 문제를 해결할 수 있습니다!
    let ps = document.getElementsByTagName("p");for(let i = ps.length-1;i>=0;--i){ let p = document.createElement("p"); document.body.appendChild(p);}
    로그인 후 복사
    4. 이벤트 위임의 장점은 무엇인가요?
    • 문서 객체는 언제든지 사용할 수 있으며 DOMContentLoaded 또는 load 이벤트를 기다리지 않고 언제든지 이벤트 핸들러를 추가할 수 있습니다. ) 이를 통해 페이지를 처리합니다. 어떤 유형의 모든 이벤트입니다. 이는 페이지가 클릭 가능한 요소를 렌더링하는 한 지연 없이 작동한다는 것을 의미합니다.
    • 페이지 이벤트 루틴을 설정하는 데 소요되는 시간을 절약하세요.
    • 전체 페이지에 필요한 메모리를 줄이고 전반적인 성능을 향상시킵니다.
    5. 이벤트 핸들러 삭제 요소에 이벤트 핸들러를 할당한 후 브라우저 코드와 페이지 상호 작용을 담당하는 JavaScript 코드 사이에 연결이 설정됩니다. 이러한 접촉이 재개될수록 페이지 성능은 더욱 저하됩니다. 이벤트 위임을 통해 이러한 연결을 제한하는 것 외에도 사용되지 않는 이벤트 핸들러는 즉시 제거해야 합니다. 많은 웹 애플리케이션의 성능 저하는 메모리에 남아 있는 쓸모 없는 이벤트 핸들러로 인해 발생합니다. 이 문제에는 두 가지 이유가 있습니다: 1. 이벤트 핸들러를 사용하여 요소 삭제 예를 들어 DOM 메서드 RemoveChild() 또는 replacementChild()를 통해 노드를 삭제합니다. 가장 일반적인 방법은 innerHTML을 사용하여 페이지의 특정 부분을 전체적으로 바꾸는 것입니다. 이때, innerHTML에 의해 삭제된 요소에 이벤트 핸들러가 있는 경우에는 가비지 컬렉션 프로그램에 의해 정상적으로 정리되지 않습니다. 따라서 요소가 삭제된다는 것을 알고 있는 경우 btn.onclick = null;//Delete event handler와 같은 해당 이벤트 핸들러를 수동으로 삭제해야 합니다. 이벤트 위임도 이 문제를 해결하는 데 도움이 됩니다. , 요소가 innerHTML로 대체된다는 것을 알고 있는 경우 요소에 이벤트 핸들러를 추가하지 말고 상위 수준 노드에 추가하기만 하면 됩니다. 2. 페이지 언로드로 인해 메모리에 잔여 참조 문제가 발생할 수도 있습니다. 페이지가 언로드된 후 이벤트 핸들러가 정리되지 않으면 여전히 메모리에 남아 있습니다. 그 후에는 브라우저가 페이지를 로드 및 언로드할 때마다(예: 앞으로 이동, 뒤로 이동, 새로 고침 등) 이벤트 핸들러가 재활용되지 않으므로 메모리에 남아 있는 개체 수가 늘어납니다. 일반적으로 페이지가 언로드되기 전에 onunload 이벤트 핸들러에서 모든 이벤트 핸들러를 삭제하는 것이 가장 좋습니다. 이벤트 위임의 장점도 이때 확인할 수 있습니다. 이벤트 핸들러가 적기 때문에 어떤 핸들러를 삭제할지 기억하기 쉽습니다.

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

    表达式

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

    表达式

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

    表达式①中第一行取得了包含文档中所有

    元素的HTMLCollection。因为这个集合是实时的,所以任何时候只要向页面中添加一个新的

    元素,再查询这个集合就会多一项。因为浏览器不希望保存每次创建的集合,所以就会在每次访问时更新集合。每次循环都会求值i ,这意味着要获取所有

    元素的查询。因为循环体中创建并向文档中添加一个新的

    元素,所以每次循环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思维导图

    JavaScript 메모리 및 성능 문제에 대한 깊은 이해

    相关推荐:javascript教程

    위 내용은 JavaScript 메모리 및 성능 문제에 대한 깊은 이해의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    관련 라벨:
    원천:csdn.net
    본 웹사이트의 성명
    본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
    최신 다운로드
    더>
    웹 효과
    웹사이트 소스 코드
    웹사이트 자료
    프론트엔드 템플릿
    회사 소개 부인 성명 Sitemap
    PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!