关于DOM的操作以及性能优化问题
- 格式:doc
- 大小:25.50 KB
- 文档页数:4
前端性能优化使用缓存优化DOM操作在前端开发中,性能优化是一个非常重要的话题。
优化页面加载速度和性能是提升用户体验的关键。
在这篇文章中,我们将探讨如何使用缓存来优化前端的DOM操作,从而提高页面的性能。
缓存是一种存储数据的技术,它可以将之前请求的资源在客户端进行存储,以便在后续的请求中直接使用,而无需再次向服务器请求。
在前端开发中,我们可以使用缓存来优化DOM操作,具体的方法如下:1. 使用本地缓存使用本地缓存是前端开发中常用的优化手段之一。
在浏览器中,可以使用localStorage或sessionStorage来存储数据。
这些缓存对象是以键值对的形式进行存储,可以存储字符串、数值或JSON格式的数据。
通过将DOM元素的内容存储在本地缓存中,在下次需要使用时,可以直接从缓存中获取,而无需再次进行DOM操作。
这样可以显著减少DOM操作带来的开销,提高页面加载速度和性能。
2. 使用缓存策略除了使用本地缓存,我们还可以通过缓存策略来优化DOM操作。
缓存策略是一种判断逻辑,用于确定是否需要执行DOM操作。
在执行DOM操作之前,可先检查缓存中是否已存在需要操作的DOM元素,如果存在,则可以直接使用缓存的元素,而无需再次进行DOM查找和操作。
通过合理的缓存策略,可以减少DOM操作的次数,提高页面的性能。
常见的缓存策略包括使用全局变量、对象属性缓存等。
3. 使用虚拟DOM虚拟DOM是一种用于优化DOM操作的技术,它通过将真实的DOM结构映射到内存中的虚拟DOM树,通过对比虚拟DOM树的变化,最终将变化部分更新到真实的DOM中。
使用虚拟DOM可以减少直接操作真实DOM的次数,从而提高性能。
在修改DOM时,我们可以先将变化应用到虚拟DOM上,然后再一次性将变化更新到真实DOM中。
这样可以减少DOM操作的次数,提高性能。
4. 避免频繁的DOM操作频繁的DOM操作会影响页面的性能,尤其是在涉及大量DOM元素的情况下。
前端开发中的性能监控与调优技巧随着互联网的发展,前端开发在网站和应用程序的开发过程中扮演着越来越重要的角色。
在用户体验至关重要的今天,性能监控和调优成为了前端开发的关键。
本文将探讨前端开发中的性能监控与调优技巧,帮助开发者提高网站和应用程序的性能。
一、加载时间优化网页的加载时间是用户体验的重要指标之一。
优化加载时间可以提高用户的满意度和留存率。
在前端开发中,我们可以采取一些措施来优化加载时间。
1. 压缩和合并文件:将CSS和JavaScript文件进行压缩和合并,减少文件的大小和数量,从而减少加载时间。
2. 图片优化:使用适当的图片格式,如JPEG、PNG和WebP,并对图片进行压缩,以减小文件体积。
3. 延迟加载:对于页面中不是立即可见的内容,可以延迟加载,只在需要时再加载。
这样可以减少页面的初始加载时间。
二、DOM操作优化DOM操作是前端开发中常用的操作之一,但是频繁的DOM操作会影响页面的性能。
在进行DOM操作时,我们可以采取以下措施来优化性能。
1. 批量操作:将多个DOM操作合并为一个批量操作,减少DOM操作的次数。
2. 缓存DOM元素:在进行DOM操作时,尽量缓存DOM元素的引用,避免重复查询DOM元素。
3. 使用事件委托:对于大量的事件绑定,可以使用事件委托的方式,将事件绑定到父元素上,减少事件绑定的数量。
三、网络请求优化网络请求是前端开发中常见的操作之一,优化网络请求可以提高页面的加载速度和响应时间。
1. 减少请求次数:合并多个请求,减少请求的次数,从而减少网络传输的开销。
2. 使用缓存:对于静态资源,可以设置缓存策略,使得浏览器能够缓存这些资源,减少重复的请求。
3. 异步加载:对于一些非关键的资源,可以使用异步加载的方式,使得页面的加载不会被阻塞。
四、内存管理与垃圾回收前端开发中,内存管理和垃圾回收是非常重要的,合理的内存管理可以避免内存泄漏和提高页面的性能。
1. 及时释放资源:在不需要使用的时候,及时释放资源,如解绑事件、清除定时器等。
前端框架的性能优化技巧随着web应用程序的复杂化,前端框架的应用也越来越广泛。
前端框架作为web开发的基础,为我们提供了很多不错的工具和功能。
而在大型应用中,前端框架的性能问题也成了一个需要关注和研究的问题。
本文将介绍一些前端框架的性能优化技巧,帮助web开发人员提升web应用程序的性能和用户体验。
1、DOM操作DOM操作是web开发中最消耗性能的部分之一。
当我们通过前端框架创建和渲染DOM节点时,它可能会频繁地更新DOM元素,这会导致浏览器的重绘和回流,从而降低web应用程序的性能。
因此,我们需要尽量避免不必要的DOM操作,减少重绘和回流的次数。
首先,我们可以将需要更新的元素缓存起来,避免在更新时频繁查询。
其次,我们可以使用虚拟DOM来减少DOM操作的次数。
虚拟DOM是一种轻量级的内存数据结构,用于抽象真实DOM元素。
在更新虚拟DOM时,我们只需要比较新旧虚拟DOM的差异,而不用频繁地操作真实DOM元素。
2、事件绑定事件绑定也是web开发中的一个性能瓶颈。
当我们绑定大量事件时,浏览器需要处理大量的事件回调函数,从而影响用户体验。
因此,在事件绑定上,我们需要避免过度绑定事件,以及使用事件委托的方式来降低事件回调函数的数量。
例如,我们可以使用事件委托的方式来绑定事件,即使用一个父元素来处理所有子元素的事件。
这样可以减少事件回调函数的数量,从而提高web应用程序的性能。
3、数据的处理和传输数据的处理和传输也是web应用程序性能的重要因素。
当我们处理大量数据时,需要考虑使用逻辑分页或者懒加载的方式来优化数据显示效果。
逻辑分页通过在后端对数据进行分页,从而减少需要一次性加载的数据量,提高web应用程序性能。
懒加载则是在数据量庞大的情况下,只加载用户当前可见的部分数据,从而加快数据的传输和处理速度。
同时,我们也需要考虑数据格式的压缩和传输方式的优化。
例如,使用gzip压缩数据,以及使用异步传输的方式来提高数据传输的效率。
高频dom 操作和页面性能优化探索一、DOM操作影响页面性能的核心问题通过js操作DOM的代价很高,影响页面性能的主要问题有如下几点:●访问和修改DOM元素●修改DOM元素的样式,导致重绘或重排●通过对DOM元素的事件处理,完成与用户的交互功能DOM的修改会导致重绘和重排。
●重绘是指一些样式的修改,元素的位置和大小都没有改变;●重排是指元素的位置或尺寸发生了变化,浏览器需要重新计算渲染树,而新的渲染树建立后,浏览器会重新绘制受影响的元素。
页面重绘的速度要比页面重排的速度快,在页面交互中要尽量避免页面的重排操作。
浏览器不会在js执行的时候更新DOM,而是会把这些DOM操作存放在一个队列中,在js执行完之后按顺序一次性执行完毕,因此在js执行过程中用户一直在被阻塞。
1.页面渲染过程一个页面更新时,渲染过程大致如下:●JavaScript: 通过js来制作动画效果或操作DOM实现交互效果●Style: 计算样式,如果元素的样式有改变,在这一步重新计算样式,并匹配到对应的DOM上●Layout: 根据上一步的DOM样式规则,重新进行布局(重排)●Paint: 在多个渲染层上,对新的布局重新绘制(重绘)●Composite: 将绘制好的多个渲染层合并,显示到屏幕上在网页生成的时候,至少会进行一次布局和渲染,在后面用户的操作时,不断的进行重绘或重排,因此如果在js中存在很多DOM操作,就会不断地出发重绘或重排,影响页面性能。
2.DOM操作对页面性能的影响如前面所说,DOM操作影响页面性能的核心问题主要在于DOM操作导致了页面的重绘或重排,为了减少由于重绘和重排对网页性能的影响,我们要知道都有哪些操作会导致页面的重绘或者重排。
2.1 导致页面重排的一些操作:内容改变文本改变或图片尺寸改变DOM元素的几何属性的变化例如改变DOM元素的宽高值时,原渲染树中的相关节点会失效,浏览器会根据变化后的DOM重新排建渲染树中的相关节点。
前端性能优化的DOM操作与渲染优化DOM(文档对象模型)操作和渲染是前端性能优化中至关重要的一部分。
在网页加载和交互过程中,大量的DOM操作和渲染会对性能产生影响。
本文将介绍一些优化DOM操作和渲染的技巧和策略,以提高前端应用的性能和用户体验。
一、避免频繁的DOM查询与操作DOM查询和操作是昂贵的操作,特别是在多次查询和操作同一个DOM元素时。
因此,减少DOM查询和操作的次数可以显著提升性能。
以下是一些减少DOM查询和操作次数的方法:1. 使用变量缓存DOM元素的引用。
在需要频繁使用的DOM元素上,将其引用缓存到变量中,以避免重复查询DOM树。
2. 批量更新DOM。
避免在循环中进行DOM操作,可以先将需要修改的DOM元素保存在一个变量中,在循环结束之后再一次性进行DOM操作。
3. 使用事件委托。
将事件绑定在父元素上,利用事件冒泡机制捕获子元素的事件,这样可以减少事件处理函数的数量,提高性能。
二、优化DOM的插入与删除操作DOM的插入与删除操作是常见的DOM操作,但频繁的插入与删除操作会导致页面重新渲染,影响性能。
下面是一些优化这些操作的方法:1. 使用Fragment进行批量插入。
将需要插入的DOM元素先添加到一个Fragment对象中,然后再将整个Fragment对象添加到文档中,这样可以减少实际插入的次数,提高性能。
2. 避免频繁的DOM删除与重建。
如果需要频繁地对DOM元素进行删除和重建,可以考虑使用隐藏和显示的方式,而不是直接删除和重新创建DOM元素。
三、合理使用样式与布局样式和布局的改变会触发浏览器的重排和重绘,因此在进行DOM操作时,需要注意对样式和布局的影响,以减少重排和重绘的次数。
1. 使用CSS动画替代JavaScript动画。
CSS动画可以利用硬件加速,在性能上有较大的优势。
尽量避免使用JavaScript来实现复杂的动画效果。
2. 避免使用table布局。
table布局在渲染上比较慢,如果可以使用其他方式替代,可以提高页面加载和渲染的速度。
前端性能优化减少DOM元素的数量在Web开发中,性能优化是一个至关重要的问题。
优化网页性能不仅可以提升用户体验,还能够减少服务器负载,降低网站维护成本。
其中,减少DOM元素的数量是一个有效的性能优化策略。
本文将介绍几种减少DOM元素数量的方法,并分析它们的优缺点。
一、合理利用DOM选择器在JavaScript中,通过选择器可以获取到页面上满足特定条件的DOM元素。
然而,使用选择器时应该尽量精确,避免选择过多的元素。
1. 使用ID选择器:ID具有唯一性,使用ID选择器可以快速获取到具体的DOM元素,避免遍历整个文档树。
例如,通过document.getElementById('elementId')可直接获取到特定ID的元素,效率非常高。
2. 使用Class选择器:将具有相似功能或样式的元素添加相同的class属性,在JavaScript中可以通过类选择器快速获取到这些元素。
例如,通过document.getElementsByClassName('className')可以一次性获取到所有class为className的元素。
3. 使用层级选择器:在CSS选择器中,可以通过层级关系选择指定元素。
但是,层级选择器的性能并不是很高,特别是在嵌套层级较多的情况下。
因此,应该尽量减少层级选择器的使用,避免影响页面性能。
二、使用虚拟DOM虚拟DOM是一种将真实DOM映射到JavaScript对象的技术,通过对比虚拟DOM的变化来最小化DOM操作,提升性能。
1. 创建虚拟DOM:通过JavaScript对象来描述DOM的结构,而不是直接操作真实DOM。
这样可以减少真实DOM的数量,并将DOM操作集中在必要的时候进行。
2. 提交虚拟DOM变化:当虚拟DOM发生变化时,通过比较前后两个虚拟DOM的差异,仅更新变化的部分,而不需要重新渲染整个页面。
这样可以减少DOM操作的次数,提升性能。
使用jQuery进行DOM操作和Web应用程序优化在Web开发过程中,我们经常需要通过修改DOM(文档对象模型)来实现页面功能。
而在处理DOM时,jQuery成为了开发者们的首选库之一。
它对DOM的处理和操作,简化了很多代码和逻辑,为Web应用程序优化提供了很多便利性。
本篇文章将从两方面进行讲解。
首先是jQuery对DOM操作的增强和优化。
接着是jQuery在Web应用程序优化中的应用。
一、使用jQuery进行DOM操作1. 查询DOM元素当我们需要选择一个或多个DOM元素时,jQuery提供了一系列选择器来根据元素的标签名称、类、ID、属性、父元素等进行查找。
而检索到的元素可以直接进行各种方法的调用,比如addClass,removeClass,attr,text等等。
此外,querySelectorAll方法和getElementByID方式等传统的DOM查询方式都可以通过jQuery进行简化。
这样可以减少DOM层级嵌套和查询的时间,提高程序的性能和执行效率。
2. 操作DOM元素在jQuery中,修改DOM元素的方法比原生JS简单很多,而且兼容性也更好。
比如,添加、移除类可以使用addClass、removeClass方法,修改样式可以使用css方法,添加、删除或者改变HTML内容也非常容易,.attr、.prop和.val等方法等都可以被用来修改属性或元素值。
3. 事件处理jQuery可以轻松地将事件附加到元素上,例如click、hover、mousemove等等。
这些事件可以通过选择某个DOM元素后轻易地绑定到它上面。
然后,你可以对事件使用任何标准的监听器或处理函数,以及jquery提供的特殊方法(例如on)。
jQuery事件处理的另一个好处是它足够灵活以允许你将事件冒泡禁止到指定层数或者仅在某个页面中完成操作。
事件委托也是一种优化性能的有效方式。
二、Web应用程序优化中的jQuery应用1. 页面优化在进行Web页面优化的时候,我们常常需要对页面渲染时间进行优化,对于DOM操作,jQuery提供了一些技巧。
前端开发中的内存管理与性能优化技巧随着互联网技术的飞速发展,前端开发在现代软件开发中的地位越来越重要。
尤其是当今的Web应用程序越来越复杂,前端内存管理和性能优化成为了不可忽视的问题。
本文将介绍一些前端开发中的内存管理和性能优化技巧,帮助开发者提升网站的响应速度和用户体验。
1. 优化DOM操作DOM操作是前端开发中经常需要进行的一项工作,但不当的DOM操作会导致网页的加载速度明显下降。
其中一个重要的原因是DOM操作会引发网页的重绘和重排,消耗大量的CPU资源。
因此,在编写代码时,应尽量避免频繁的DOM操作,可以将多个操作合并成一次操作,减少重绘和重排的次数。
2. 减少网络请求次数网页的性能优化中,减少网络请求次数是一个重要的方面。
减少JavaScript和CSS文件的数量,可以使用合并和压缩工具将多个文件合并成一个文件,并采用Gzip压缩技术减小文件体积。
此外,使用CSS Sprites技术将多个小图片合并成一个大图,减少网络请求次数,有助于提高网页加载速度。
3. 内存泄漏处理内存泄漏是一个常见的问题,在前端开发中尤为明显。
内存泄漏会导致页面崩溃、卡顿甚至系统崩溃。
为了避免内存泄漏,开发者可以使用JavaScript的垃圾回收机制手动释放不再使用的资源,及时销毁不再需要的对象和事件监听器。
4. 懒加载技术懒加载是一种在用户需要时再加载资源的技术,可以显著提高网页的加载速度。
在开发过程中,可以根据页面内容的不可见性,延迟加载图片和其他资源,减少页面的加载时间。
同时,懒加载技术也有利于节约用户的流量,提升用户体验。
5. 缓存策略合理的缓存策略可以有效地提高网页的加载速度。
在前端开发中,可以使用浏览器缓存和服务器缓存。
通过设置合适的缓存头和过期时间,让浏览器在下次请求同一资源时直接使用缓存而不需要重新下载,从而降低服务器的负载和网络请求的数量。
6. 前端框架和库的选择选择合适的前端框架和库也是提高网页性能的重要因素。
JavaScript DOM的性能优化详解在前端开发中,用Javascript操作DOM比较消耗性能,每次操作DOM都会触发布局的改变、DOM树的修改和渲染。
也就是说操作DOM会引发重排(回流)与重绘,这个过程是非常消耗资源的。
所以我们要对DOM操作进行性能优化。
DOM性能优化的本质:就是减少对DOM查询及减少DOM操作(增、删、改)引起的重排(回流)和重绘的次数DOM性能优化方法:1.合并多次对css样式的修改,改为一次处理2.对DOM查询做缓存3.将频繁DOM操作改为一次性操作4.操作DOM前,先把DOM节点删除或隐藏5.采用事件代理处理事件在讲解5种优化方法之前,我们需要先了解什么是重排(回流)和重绘,要了解重排(回流)和重绘,就需要先了浏览器的渲染机制,所以我们先从浏览器的渲染机制开始讲起。
一、浏览器的渲染机制浏览器的整个渲染过程(下图)•解析HTML,构建DOM 树•解析CSS,生成CSS 规则树•合并DOM 树和CSS 规则树,生成render(渲染)树。
•布局render 树(回流/ 重排),负责各元素尺寸、位置的计算。
•绘制render 树(painting 重绘),绘制页面像素信息•浏览器会将各层的信息发送给GPU,GPU 会将各层合成(composite),显示在屏幕上。
构建渲染树时,浏览器主要完成以下工作•从DOM 树的根节点开始遍历每个可见节点•对每个可见节点,找到CSS 规则树中对应的规则,并应用它们•根据每个可见节点以及其对应的样式,组合生成渲染树不可见节点(也就是不会出现在渲染树中的节点)•一些不会渲染输出的节点(如:script、meta、link 等)•一些通过css 进行隐藏的节点(如:display: none)注意点:•样式为display:none;的节点会在DOM树中而不在渲染树中•visiblity 和opacity 隐藏的节点在DOM和渲染树中同时存在。
性能优化:虚拟列表,如何渲染10万条数据的dom,页⾯同时不卡顿最近做的⼀个需求,当列表⼤概有2万条数据,⼜不让做成分页,如果页⾯直接渲染2万条数据,在⼀些低配电脑上可能会照成页⾯卡死,基于这个需求,我们来⼿写⼀个虚拟列表思路1. 列表中固定只显⽰少量的数据,⽐如60条2. 在列表滚动的时候不断的去插⼊删除dom3. startIndex、endIndex,不断的改变这个值来获取最新的显⽰列表4. paddingTop、paddingBottom撑开容器的滚动区域⾸先看⼀下当直接插⼊2万条列表时,页⾯的性能可以看到⽕焰图中已经有了红⾊的部分了,dom渲染也耗时也有1s多再来看⼀下当使⽤虚拟列表时页⾯的性能从⽕焰图中可以看出,⽕焰图中⼀篇绿油油的,这就证明,通过虚拟列表来进⾏渲染使页⾯性能得到了极⼤的提升简单的虚拟列表demo实现我们假设有⼀个容器,⾼度为600px,列表项每个⾼度为30px,那么根据列表的length我们就可以计算出滚动容器的总⾼度,也可以知道显⽰60条数据的⾼度,我们此时可以给容器加⼀个paddingBottom,来撑开容器,来模拟页⾯应该滚动的⾼度this.paddingBottom = this.allHeight - this.scrollList.length * 30容器同时还需要paddingTop⽤做当容器滚动顶部数据移除后撑起scrollTop最后我们需要监听容器的滚动事件来不断的修改paddingTop、paddingBottom、startIndex、endIndex最终效果最后附上所有代码<!doctype html><html lang="zh"><head><meta charset="UTF-8"><meta name="viewport"content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"><title>Document</title><style>.container {width: 300px;height: 600px;overflow: auto;border: 1px solid;margin: 100px auto;}.item {height: 29px;line-height: 30px;border-bottom: 1px solid #aaa;padding-left: 20px;}</style></head><body><div id="app"><button @click="add">增加</button><div class="container" ref="container"><div class="scroll-wrapper" :style="style"><div v-for="(item, index) in scrollList" :key="index" class="item">{{item}}</div> </div></div></div><script src="./vue.js"></script><script>new Vue({el: '#app',data: {list: ['测试数据'],startIndex: 0,endIndex: 60,paddingTop: 0,paddingBottom: 0,allHeight: 0},computed: {scrollList() {return this.list.slice(this.startIndex, this.endIndex)},style() {return {paddingTop: this.paddingTop + 'px',paddingBottom: this.paddingBottom + 'px'}}},watch: {list(val) {const valLen = val.lengththis.allHeight = valLen * 30this.paddingBottom = this.allHeight - this.scrollList.length * 30}},mounted() {const container = this.$refs.containercontainer.addEventListener('scroll', () => {const top = container.scrollTopthis.startIndex = Math.floor(top / 30)this.endIndex = this.startIndex + 60this.paddingTop = topif (this.endIndex >= this.list.length - 1) {this.paddingBottom = 0return}this.paddingBottom = this.allHeight - 600 - top})},methods: {add() {let arr = new Array(50000).fill(0)arr = arr.map((item, index) => {return index})this.list = [...this.list,...arr]}}})</script></body></html>。
关于DOM的操作以及性能优化问题大家都知道DOM的操作很昂贵。
然后贵在什么地方呢?一、访问DOM元素二、修改DOM引起的重绘重排一、访问DOM像书上的比喻:把DOM和JavaScript(这里指ECMScript)各自想象为一个岛屿,它们之间用收费桥梁连接,ECMAScript每次访问DOM,都要途径这座桥,并交纳“过桥费”,访问DOM的次数越多,费用也就越高。
因此,推荐的做法是尽量减少过桥的次数,努力待在ECMAScript岛上。
我们不可能不用DOM的接口,那么,怎样才能提高程序的效率?既然无法避免,那就减少访问。
(width、offsetTop、left。
能少就少,可以缓存起来的,就缓存)复制代码// code1错误console.time(1);for(var i = 0; i < times; i++) {document.getElementById('div1').innerHTML += 'a';}console.timeEnd(1);// code2正确console.time(2);var str = '';for(var i = 0; i < times; i++) {str += 'a';}document.getElementById('div2').innerHTML = str;console.timeEnd(2);////////////////////////复制代码html集合&遍历DOMhtml集合类似数组,但是跟数组还是不一样的。
如:document.getElementsByTagName('a') 返回的html集合。
这个集合是实时更新的,即后面代码修改了DOM,会反映在这个html 集合里面。
可尝试代码。
复制代码<body><ul id='fruit'><li> apple </li><li> orange </li><li> banana </li></ul></body><script type="text/javascript">var lis = document.getElementsByTagName('li');var peach = document.createElement('li');rHTML = 'peach';document.getElementById('fruit').appendChild(peach);console.log(lis.length); // 4</script>复制代码正因为这个原因:html集合,读取length 属性比数组消耗大多了。
要解决这个问题并不难,在遍历DOM集合的时候,缓存length就好了。
不要每次使用就获取,主要体现在for循环中(你应该知道,for循环中,每一次都会执行判读语句,读取length)复制代码console.time(0);var lis0 = document.getElementsByTagName('li');var str0 = '';for(var i = 0; i < lis0.length; i++) {str0 += lis0[i].innerHTML;}console.timeEnd(0);console.time(1);var lis1 = document.getElementsByTagName('li');var str1 = '';for(var i = 0, len = lis1.length; i < len; i++) {str1 += lis1[i].innerHTML;}console.timeEnd(1);复制代码二、重绘重排1.什么是重绘重排?浏览器下载完页面中的所有组件——HTML标记、JavaScript、CSS、图片之后会解析生成两个内部数据结构——DOM树和渲染树。
在文档初次加载时,浏览器引擎通过解析html文档构建一棵DOM树,之后根据DOM元素的几何属性构建一棵用于展示渲染的渲染树。
渲染树中的节点被称为“帧”或“盒",符合CSS模型的定义,可理解为(包括理解页面元素为一个具有大小,填充,边距,边框和位置的盒子)。
由于隐藏元素不需要显示,渲染树中并不包含DOM树中隐藏的元素(知道这点有用)。
当渲染树构建完成,浏览器把每一个元素放到正确的位置上,然后再根据每一个元素的其他样式,绘制页面。
由于浏览器的流布局,对渲染树的计算通常只需要遍历一次就可以完成。
但table及其内部元素除外,它可能需要多次计算才能确定好其在渲染树中节点的属性,通常要花3倍于同等元素的时间。
这也是为什么我们要避免使用table做布局的一个原因。
重绘:是一个元素外观的改变所触发的浏览器行为,例如改变visibility、outline、背景色等属性(上面说到的其他属性)。
浏览器会根据元素的新属性重新绘制,使元素呈现新的外观。
重绘不会带来重新布局,并不一定伴随重排。
重排:当DOM的变化影响了元素的几何属性(宽或高),浏览器需要重新计算元素的几何属性,同样其他元素的几何属性和位置也会因此受到影响。
浏览器会使渲染树中受到影响的部分失效,并重新构造渲染树。
这个过程称为重排。
重排一定伴随着重绘。
2. 触发重排的操作:2.1 修改DOM元素几何属性:修改元素大小,位置,内容(一般只有重绘,但是内容可能导致元素大小变化)2.2 DOM树结构发生变化当DOM树的结构变化时,例如节点的增减、移动等,也会触发重排。
浏览器引擎布局的过程,类似于树的前序遍历,是一个从上到下从左到右的过程。
通常在这个过程中,当前元素不会再影响其前面已经遍历过的元素。
所以,如果在body最前面插入一个元素,会导致整个文档的重新渲染,而在其后插入一个元素,则不会影响到前面的元素。
2.4 改变浏览器大小3.渲染树变化的排队和刷新思考下面代码:1 var ele = document.getElementById('myDiv');2 ele.style.borderLeft = '1px';3 ele.style.borderRight = '2px';4 // var _top = ele.offsetTop; //刷新队列5 ele.style.padding = '5px';三行代码,三次修改元素的几何属性,浏览器应该发生三次重排重绘。
但是浏览器并不会这么笨,它也是有做优化的。
它会把三次修改“保存”起来(大多数浏览器通过队列化修改并批量执行来优化重排过程,也有设置时间片段的),一次完成!然而,如果你在三行代码中,以下获取DOM布局信息。
(为了返回最新的布局信息,将立即执行渲染树变化队列的更新)如上面被注释的第4行,如果取消注释会导致(2+3)、(5)两次重排;获取关于DOM布局信息的属性:offsetTop, offsetLeft, offsetWidth, offsetHeightscrollTop, scrollLeft, scrollWidth, scrollHeightclientTop, clientLeft, clientWidth, clientHeightgetComputedStyle() (tStyle in IE)4 应对方法:尽量减少重绘次数、减少重排次数、缩小重排的影响范围。
4.1 合并多次操作,如上面的操作ele.style.cssText = 'border-left: 1px; border-right: 2px; padding: 5px;';4.2 将需要多次重排的元素,position属性设为absolute或fixed,这样此元素就脱离了文档流,它的变化不会影响到其他元素。
例如有动画效果的元素就最好设置为绝对定位。
4.3 由于display属性为none的元素不在渲染树中,对隐藏的元素操作不会引发其他元素的重排。
如果要对一个元素进行复杂的操作时,可以先隐藏它,操作完成后再显示。
这样只在隐藏和显示时触发2次重排。
但是这可能导致浏览器的闪烁。
4.4 在内存中多次操作节点,完成后再添加到文档中去(可使用fragment元素)。
例如要异步获取表格数据,渲染到页面。
可以先取得数据后在内存中构建整个表格的html片段,再一次性添加到文档中去,而不是循环添加每一行。
复制代码var fragment = document.createDocumentFragment(); // 未使用的虚拟节点,appendChild(fragment) //append的是里面的子元素var li = document.createElement('li');li.innerHTML = 'apple';fragment.appendChild(li);var li = document.createElement('li');li.innerHTML = 'watermelon';fragment.appendChild(li);document.getElementById('fruit').appendChild(fragment);。