前端入门到弃坑:Dom操作是否会带来性能问题

简介: 前端入门到弃坑:Dom操作是否会带来性能问题

image.png

1.页面的渲染过程

(1)Javascript:通过JS实现动画效果或者操作DOM实现交互

(2)Style:计算样式,如果样式有改变将重新计算,并返回给DOM

(3)Layout:根据DOM的样式,重新布局(重排)

(4)Paint:在多个渲染层上,对新的布局重新渲染(重绘)

(5)Composite:将绘制好的多个渲染层合并,显示到页面上

在页面生成时,至少进行一次布局和渲染,在后面用户不断地操作过程中会进行多次的重排和重绘,以至于影响页面的性能。

2.通过JS操作DOM影响页面性能的问题有

(1)访问和修改DOM

(2)修改DOM元素的样式,导致重绘或者重排

(3)通过对DOM元素的事件处理,完成与用户的交互功能

3.DOM操作对页面性能的影响

(1)DOM的修改会导致重排和重绘

重排是指元素的位置或者大小发生了改变,浏览器需要重新去计算渲染树,新的渲染树建立之后,浏览器会重新绘制所影响的元素

重绘是指元素的样式发生了变化,而大小和尺寸没有发生改变

(2)导致页面重排的一些操作

   内容改变:文本改变或者图片的尺寸改变

   DOM元素的几何属性改变:元素的宽高改变时,原来渲染树中的DOM节点会失效,浏览器会根据DOM的变化重新构建渲染树中的相关节点。如果父元素的几何属性发生变化时,会导致子元素以及兄弟元素的位置发生变化,从而引起重排。

   DOM树结构发生变化:添加DOM节点,修改DOM节点的位置以及删除某个节点都会对渲染树进行修改,从而导致重排。浏览器的布局是自上而下的,修改当前元素不会都之前的元素造成影响,但是会对之后的元素造成影响,导致重排。

   获取某些属性时:当获取一些属性值时,浏览器为了保证获取到正确的值也会引起重排。如元素的offsetTop,offsetLeft,offsetHeight,offsetWidth,scrollTop,scrollWidth,scrollLeft,scrollHeight、

   浏览器窗口尺寸发生改变时:浏览器窗口的尺寸发生改变时,会导致所有元素的尺寸发生变化,从而导致重排。

(3)导致页面重绘的一些操作

只修改元素的样式,而未修改元素的大小和位置,引起重绘

重排一定引起重绘,而重绘不一定引起重排

4.性能优化

(1)浏览器本身的优化策略

浏览器会维护一个队列,将所有引起重排和重绘的操作都放在这个队列里,当操作达到一定的数量或者时间间隔时,浏览器会进行一个批处理。这样可以让多次的重排重绘,变成一次。但是有时候一些特殊的style属性会使这种优化失效,例如offsetTop,scrollTop,clientTop等属性,这些属性都是要实时返回给用户的几何属性或者布局属性,因此浏览器需要立即执行,触发重排返回正确的值。

(2)最小化的重排和重绘

减少对渲染树的操作,并减少对一些style信息的请求。

   将多次样式改变属性合并成一次操作(仅适用于单个节点)

//javascript
        var el = document.getElementById("el");
        el.style.color = "red";
        el.style.height = "100px";
        el.style.width = "20px";

可以使用内联样式的cssText实现

var el = document.getElementById("el");
el.style.cssText = 'color: red; height:100px; width:20px'

还可以使用切换类名的方法

//CSS
        .active{   
            color: red;
            width: 20px;
            height: 100px;
        }
        //javascript
        var el = document.getElementById("el");
        el.className = "active";

        批量修改DOM  

   核心思想:

   让元素脱离文本流;对其进行多重改变;将元素带回文档中;

  a.  采用display属性隐藏元素,修改之后再显示元素,这样只在显示和隐藏元素是触发两次重排; 将多次需要重排元素,position属性设置为absolute和fixed这样就脱离文档流,元素的变化将不会影响其他元素。使用动画效果的元素最好设置成绝对定位。

 b.  使用文档片段创建一个子树,然后再拷贝到文档中。例如要一步获取一个列表中的元素,可以在内存中生成一个列表的HTML片段,然后再一次添加到文档中,而不是每循环一次添加一项。这样就只触发了一次重排。

 c.  将原始元素拷贝到一个独立节点中去,然后操作这个独立的节点,覆盖原始元素。

   缓存布局信息

当访问offsetTop这种属性时,会冲破浏览器本身的优化,所以应减少对布局信息的查询。可以将属性值赋值给局部变量来参与运算。

var a = el.offsetWidth;
    a.style.width = 1 + ++a +'px';
相关文章
|
1月前
|
前端开发
【前端web入门第四天】02 CSS三大特性+背景图
本文详细介绍了CSS的三大特性:继承性、层叠性和优先级,并深入讲解了背景图的相关属性,包括背景属性、背景图的平铺方式、位置设定、缩放、固定以及复合属性。其中,继承性指子元素自动继承父元素的文字控制属性;层叠性指相同属性后定义覆盖前定义,不同属性可叠加;优先级涉及选择器权重,包括行内样式、ID选择器等。背景图部分则通过具体示例展示了如何设置背景图像的位置、大小及固定方式等。
240 91
|
1月前
|
前端开发
【前端web入门第四天】01 复合选择器与伪类选择器
本文档详细介绍了CSS中的复合选择器与伪类选择器。复合选择器包括后代选择器、子代选择器、并集选择器和交集选择器,能够更精确地定位和样式化元素。后代选择器用于选中某元素的所有后代,子代选择器仅选中直接子元素。并集选择器可为多个标签设置相同样式,而交集选择器则选中同时满足多个条件的元素。此外,还介绍了伪类选择器,如鼠标悬停效果和超链接的不同状态。
57 32
【前端web入门第四天】01 复合选择器与伪类选择器
|
15天前
|
JavaScript 前端开发 小程序
一小时入门Vue.js前端开发
本文是作者关于Vue.js前端开发的快速入门教程,包括结果展示、参考链接、注意事项以及常见问题的解决方法。文章提供了Vue.js的基础使用介绍,如何安装和使用cnpm,以及如何解决命令行中遇到的一些常见问题。
一小时入门Vue.js前端开发
|
1天前
|
JavaScript 前端开发 编译器
吐血整理:纯前端如何实现批量dom转图片,并下载成压缩包
【10月更文挑战第2天】吐血整理:纯前端如何实现批量dom转图片,并下载成压缩包
11 2
|
18天前
|
前端开发 JavaScript
前端基础(七)_DOM元素获取(getElementById、getElementsByTagName、getElementsByClassName、querySelector等)
本文介绍了如何在前端通过不同的方法获取DOM元素,包括getElementById、getElementsByTagName、getElementsByClassName、querySelector和querySelectorAll。
57 3
|
17天前
|
JSON 前端开发 JavaScript
不会webpack的前端可能是捡来的,万字总结webpack的超入门核心知识
该文章提供了Webpack的基础入门指南,涵盖安装配置、基本使用、加载器(Loaders)、插件(Plugins)的应用,以及如何通过Webpack优化前端项目的打包构建流程。
不会webpack的前端可能是捡来的,万字总结webpack的超入门核心知识
|
17天前
|
XML 缓存 JavaScript
提升对前端的认知,不得不了解Web API的DOM和BOM
该文章强调了在前端开发中理解和掌握DOM(文档对象模型)和BOM(浏览器对象模型)的重要性,并介绍了它们的相关操作和应用。
提升对前端的认知,不得不了解Web API的DOM和BOM
|
18天前
|
JavaScript 前端开发
前端基础(十)_Dom自定义属性(带案例)
本文介绍了DOM自定义属性的概念和使用方法,并通过案例展示了如何使用自定义属性来控制多个列表项点击变色的独立状态。
32 0
前端基础(十)_Dom自定义属性(带案例)
|
1月前
|
前端开发
【前端web入门第五天】03 清除默认样式与外边距问题【附综合案例产品卡片与新闻列表】
本文档详细介绍了CSS中清除默认样式的方法,包括清除内外边距、列表项目符号等;探讨了外边距的合并与塌陷问题及其解决策略;讲解了行内元素垂直边距的处理技巧;并介绍了圆角与盒子阴影效果的实现方法。最后通过产品卡片和新闻列表两个综合案例,展示了所学知识的实际应用。
32 11
|
3天前
|
机器学习/深度学习 自然语言处理 前端开发
前端大模型入门:Transformer.js 和 Xenova-引领浏览器端的机器学习变革
除了调用API接口使用Transformer技术,你是否想过在浏览器中运行大模型?Xenova团队推出的Transformer.js,基于JavaScript,让开发者能在浏览器中本地加载和执行预训练模型,无需依赖服务器。该库利用WebAssembly和WebGPU技术,大幅提升性能,尤其适合隐私保护、离线应用和低延迟交互场景。无论是NLP任务还是实时文本生成,Transformer.js都提供了强大支持,成为构建浏览器AI应用的核心工具。
41 0