首页 > web前端 > js教程 > 正文

深入了解JavaScript的内存与性能问题

WBOY
发布: 2022-03-31 11:44:47
转载
2372人浏览过

本篇文章给大家带来了关于javascript的相关知识,其中主要介绍了javascript的内存与性能问题,包括了如何解决类似按钮过多的问题、删除事件处理程序等等,希望对大家有帮助。

深入了解JavaScript的内存与性能问题

相关推荐:javascript教程

一、何为JavaScript内存与性能

因为事件处理程序在现代web应用中可以实现交互,所以很多开发者都会错误地在页面中大量使用它们,在JavaScript中,页面中事件处理程序的数量与页面整体性能直接相关。原因有很多,比如①每个函数都是对象,都要占用内存空间,对象越多,性能越差;②为指定事件处理程序所需访问DOM的次数会先造成整个页面交互的延迟。

二、谈谈关于innerHTML的性能问题?

1、使用innerHTML的反面教材

for(let value of values){
	ul.innerHTML += '<li>${value}</li>';}
登录后复制

这段代码效率低,因为每次迭代都要设置一次innerHTML,不仅如此,每次循环都要先读取innerHTML,也就是说一次循环要访问两次innerHTML。

立即学习Java免费学习笔记(深入)”;

2、如何解

let itemsHtml = "";for(let value of values){
	itemsHtml  += '<li>${value}</li>';}ul.innerHTML = itemsHtml;
登录后复制

这样修改之后,效率就高多了,只会对innerHTML进行一次赋值,下面代码也可以搞定:
ul.innerHTML = values.map(value => '

  • ${value}
  • ').join(' ');

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

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

    <ul id="myGirls">
    	<li id="girl1">比比东</li>
    	<li id="girl2">云韵</li>
    	<li id="girl3">美杜莎</li></ul>
    登录后复制

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

    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;//删除事件处理程序,事件委托也有助于解决这个问题,如果得知某个元素要被innerHTML替代的时候,就不要给该元素添加事件处理程序了,将其添加到更高层级的节点上即可。

    2、页面卸载也会导致内存中残留引用的问题

    如果在页面卸载后事件处理程序没有被清理,则它们仍然会残留在内存中。之后,浏览器每次加载和卸载页面(比如通过前进、后退或刷新),内存中残留对象的数量都会增加,这是因为事件处理程序不会被回收。
    一般来说,最好在onunload事件处理程序中趁页面尚未卸载先删除所有事件处理程序。这时候也能体现出事件委托的优势,因为事件处理程序少,所以容易记住删除哪些。

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

    表达式

    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);}
    登录后复制

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

    元素的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的内存与性能问题的详细内容,更多请关注php中文网其它相关文章!

    数码产品性能查询
    数码产品性能查询

    该软件包括了市面上所有手机CPU,手机跑分情况,电脑CPU,电脑产品信息等等,方便需要大家查阅数码产品最新情况,了解产品特性,能够进行对比选择最具性价比的商品。

    下载
    来源:CSDN网
    本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
    最新问题
    开源免费商场系统广告
    热门教程
    更多>
    最新下载
    更多>
    网站特效
    网站源码
    网站素材
    前端模板
    关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
    php中文网:公益在线php培训,帮助PHP学习者快速成长!
    关注服务号 技术交流群
    PHP中文网订阅号
    每天精选资源文章推送
    PHP中文网APP
    随时随地碎片化学习
    PHP中文网抖音号
    发现有趣的

    Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号