IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> JavaScript知识库 -> 事件之内存与性能 -> 正文阅读

[JavaScript知识库]事件之内存与性能

一? 内存与性能的关系

在 JavaScript 中,页面中事件处理程序的数量与页面整体性能直接相关

  • 每个函数都是对象,都占用内存空间,对象越多,性能越差
  • 为指定事件处理 程序所需访问 DOM 的次数会先期造成整个页面交互的延迟

二 事件委托

定义:事件委托利用事件冒泡,可以只使用一个事件处理程序来管理一种类型的事件

  • 使用事件委托,只要给所有元素共同的祖先节点添加一个事件处理程序, 就可以解决问题
// click 事件冒泡到 document。这意味着可以为整个页面指定一个 onclick 事件处理程序,而不用为每个可点击元素分别指定事件处理程序。比如有以下 HTML:
<ul id="myLinks"> 
 <li id="goSomewhere">Go somewhere</li> 
 <li id="doSomething">Do something</li> 
 <li id="sayHi">Say hi</li> 
</ul> 
let list = document.getElementById("myLinks"); 
list.addEventListener("click", (event) => { 
 let target = event.target; 
 switch(target.id) { 
     case "doSomething": 
         document.title = "I changed the document's title"; 
     break; 
     case "goSomewhere": 
         location.href = "http:// www.wrox.com"; 
     break; 
     case "sayHi": 
         console.log("hi"); 
     break; 
 } 
}); 

// 这里只给<ul id="myLinks">元素添加了一个 onclick 事件处理程序。因为所有列表项都是这个元素的后代,所以它们的事件会向上冒泡,最终都会由这个函数来处理。

// 但事件目标是每个被点击的列表项,只要检查 event 对象的 id 属性就可以确定,然后再执行相应的操作即可。

// 相对于前面不使用事件委托的代码,这里的代码不会导致先期延迟,因为只访问了一个 DOM 元素和添加了一个事件处理程序。结果对用户来说没有区别,但这种方式占用内存更少。所有使用按钮的事件(大多数鼠标事件和键盘事件)都适用于这个解决方案。

// 只要可行,就应该考虑只给 document 添加一个事件处理程序,通过它处理页面中所有某种类型的事件

优点:

  • document 对象随时可用,任何时候都可以给它添加事件处理程序(不用等待DOMContentLoaded 或 load 事件)。这意味着只要页面渲染出可点击的元素,就可以无延迟地起作用
  • 节省花在设置页面事件处理程序上的时间。只指定一个事件处理程序既可以节省 DOM 引用,也可以节省时间
  • 减少整个页面所需的内存,提升整体性能。 最适合使用事件委托的事件包括:click、mousedown、mouseup、keydown 和 keypress。 mouseover 和 mouseout 事件冒泡,但很难适当处理,且经常需要计算元素位置(因为 mouseout 会在光标从一个元素移动到它的一个后代节点以及移出元素之外时触发)

三 删除事件处理程序

背景:很多 Web 应用性能不佳都是由于无用的事件处理程序长驻内存导致的

原因:

  • 删除带有事件处理程序的元素
  • 页面卸载

原因分析:

原因一:删除带有事件处理程序的元素

造成的场景:

  • 通过真正的 DOM 方法 removeChild()或 replaceChild()删除节点
  • 使用innerHTML 整体替换页面的某一部分,被 innerHTML 删除的元素上如果有事件处理程序,就不会被垃圾收集程序正常清理
<div id="myDiv"> 
 <input type="button" value="Click Me" id="myBtn"> 
</div> 
<script type="text/javascript"> 
 let btn = document.getElementById("myBtn"); 
 btn.onclick = function() { 
     // 执行操作
     document.getElementById("myDiv").innerHTML = "Processing..."; 
     // 不好!
 }; 
</script>

处理方式:

知道某个元素会被删除,那么最好在删除它之前手工删除它的事件处理程序

<div id="myDiv"> 
 <input type="button" value="Click Me" id="myBtn"> 
</div> 
<script type="text/javascript"> 
 let btn = document.getElementById("myBtn"); 
 btn.onclick = function() { 
     // 执行操作
     btn.onclick = null; // 删除事件处理程序
     document.getElementById("myDiv").innerHTML = "Processing..."; 
 }; 
</script>

原因二:页面卸载

原因分析:如果在页面卸载后事件处理程序没有被清理,则它们仍然会残留在内存中。之后,浏览器每次加载和卸载页面(比如通过前进、后退或刷新),内存中残留对象的数量都会增加,这是因为事件处理程序不会被回收

处理方式:

最好在 onunload 事件处理程序中趁页面尚未卸载先删除所有事件处理程序。这时候也能体现使用事件委托的优势,因为事件处理程序很少,所以很容易记住要删除哪些。关于卸载页面时的清理,可以记住一点:onload 事件处理程序中做了什么,最好在 onunload 事件处理程序中恢复

  JavaScript知识库 最新文章
ES6的相关知识点
react 函数式组件 & react其他一些总结
Vue基础超详细
前端JS也可以连点成线(Vue中运用 AntVG6)
Vue事件处理的基本使用
Vue后台项目的记录 (一)
前后端分离vue跨域,devServer配置proxy代理
TypeScript
初识vuex
vue项目安装包指令收集
上一篇文章      下一篇文章      查看所有文章
加:2021-12-28 22:49:56  更:2021-12-28 22:52:26 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 11:04:26-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码