参考 高性能javascript

文档对象模型(DOM)是独立于语言的,用于操作XML和HTML文档的程序接口API,在浏览器中主要通过DOM提供的API与HTML进行交互,浏览器通常会把DOM和javascript独立实现,这意味着当我们通过javascript操作DOM的时候势必的产生性能上的开销,因此提升页面性能的的思路是尽可能的减少DOM操作或者优化DOM操作

DOM的访问与修改

(1)减少频繁的读取DOM元素

(1)for(var i = 0;i < 10;i++) {
document.getElementById("test") += "a";
}
//上面的代码每次循环都进行了读取
(2)var content = "";
for(var i = 0;i < 10;i++) {
content += "a";
}
document.getElementById("test").innerHTML = content; //只有在最后一次通过innerHTML进行了读取 当我们更新一段html是使用innerHTML代替原始的dom操作

(2)节点克隆

当需要创建大量相似的节点的时候,通过element.clonenode()复制相应的节点,来代替重复的创建相应的节点来提升一部分的性能

(3)处理HTML集合

当我们通过document.getElementsByTagName()   document.getElementsByClassName() document.getElementsByName()  返回的是nodelist  它是一种类数组的集合,我们能通过下标的方式查找到集合中的元素

同样的通过下面的属性得到的也是html集合

document.images document.links document.forms document.forms[0].elements

操作html集合会出现性能的问题是html集合是维持实时的状态,也就是当你在文档中添加一个元素的时候,这个时候你在通过特定的方式获取html集合的长度的时候它的长度是实时变化的,html集合与文档处于连接的状态,获取html的信息的时候需要进行查询操作。

处理html集合元素有大致两种方式:

3.1将html集合转换成数组,因为遍历数组相对于遍历集合更快

  function toArray(coll) {
for(var i = 0,a = [],length = coll.length;i < len;i++) {
a[i] = coll[i];
}
return a;
}

3.2减少集合的查询操作,缓存局部变量

function test(coll) {
var length = coll.length;
var id = "";
for(var i = 0;i <length;i+=1) {
var el = coll[i];
id = el.getAttribute("id");
console.log(id);
}
}

(4)选取dom元素

4.1 使用能区分元素节点的选择API

属性名 被替代的属性
children childNodes
childElementCount childNodes.length
firstElementChild firstChild
lastElementChild  lastChild
nextElementSibling nextSibling
previousElementSibling previousSibling

上面的第一列属性只会返回相应的元素节点(两个节点之间的空格也会被识别成文本节点)  当我们通过第二列属性进行操作的时候,就需要在进行一步过滤的操作,增加了开销

4.2 使用选择器API

当需要进行大量的组合操作的时候,通过document.querySelectorAll()来进行元素的选择,通过这种方式获取的是一个nodelist,但它不与文档进行实时的更新,是一种静态的列表

(5)重绘与重排

当下载完页面的组件后,就会生成两个页面结构 DOM树  表示页面的结构  渲染树 表示DOM节点如何被显示   每一个在DOM树中需要被显示的元素在渲染树中至少存在一个对应的节点(在渲染树中的节点称为帧或者盒),当DOM的变化影响了元素的几何属性(宽高)的时候,这样浏览器就会重新计算元素的几何尺寸,其他元素的几何尺寸也会受到相应的影响,浏览器会使渲染树中受到影响的部分失效并重新构造渲染树,这个过程叫做重排,完成重排后浏览器重新绘制受到影响的部分,这个过程就叫做重绘

重绘和重排都是代价昂贵的操作,所以优化的方案是最小化重绘和重排

重排发生的时机

  • 添加或删除可见的DOM元素
  • 元素位置的改变
  • 元素尺寸的变化
  • 内容的改变(例如文本的改变或者图片内容的改变影响了元素的几何属性)
  • 页面渲染器的初始化
  • 浏览器窗口尺寸的改变

浏览器会优化重排的过程,通过队列的方式修改并批量的执行重拍的过程,但是当我们使用一些属性或者方法的时候,会强制的刷新渲染队列触发重排,当我们频繁的进行这些操作的时候,就会造成性能的开销

优化的思路:

(1)集中操作  将设置样式和获取样式进行分离(不要在布局信息改变的时候去进行查询操作),并且尽可能的合并操作

var el = document.getElementById("test");
el.style.cssText = "border-left:1px;border-right:2px;border-bottom:3px;";

(2)批量的修改DOM的时候,可以通过下面的方式减少重绘与重排

  1. 使元素脱离文档流
  2. 对齐应用修改
  3. 将元素带回文档流

脱离文档流的方案

  1. 隐藏元素 应用修改 显示元素
  2. 使用文档碎片(使用document.createDocumentFragment()创建的文档碎片添加到文档的时候,就将文档碎片的子节点进行添加而不是文档碎片本身)
  3. 将原始元素拷贝进行修改,然后替换元素元素

(3)缓存布局信息 这个思路有点像处理集合元素的时候的方案,通过缓存局部的布局信息,能减少强制刷新渲染队列的次数,也就减少了重排

(4)动画元素的处理 其实思路是一样的 动画有可能会造成大量其他元素位置改变,当动画开始的时候,让它脱离文档流,进行动画的展示,动画完结后让它回到文档流

高性能javascript学习笔记系列(3) -DOM编程的更多相关文章

  1. 高性能javascript学习笔记系列(5) -快速响应的用户界面和编程实践

    参考高性能javascript 理解浏览器UI线程  用于执行javascript和更新用户界面的进程通常被称为浏览器UI线程  UI线程的工作机制可以理解为一个简单的队列系统,队列中的任务按顺序执行 ...

  2. 高性能javascript学习笔记系列(1) -js的加载和执行

    这篇笔记的内容主要涉及js的脚本位置,如何加载js脚本和脚本文件执行的问题,按照自己的理解结合高性能JavaScript整理出来的 javascript是解释性代码,解释性代码需要经历转化成计算机指令 ...

  3. 高性能javascript学习笔记系列(2)-数据存取

    参考 高性能javascript Tom大叔深入理解javascript系列 相关概念 1.执行上下文   当控制器转到ecmascript可执行代码的时候,就会进入一个执行上下文,执行上下文是以堆栈 ...

  4. 高性能javascript学习笔记系列(6) -ajax

    参考 高性能javascript javascript高级程序设计 ajax基础  ajax技术的核心是XMLHttpRequest对象(XHR),通过XHR我们就可以实现无需刷新页面就能从服务器端读 ...

  5. 高性能javascript学习笔记系列(4) -算法和流程控制

    参考高性能javascript for in 循环  使用它可以遍历对象的属性名,但是每次的操作都会搜索实例或者原型的属性 导致使用for in 进行遍历会产生更多的开销 书中提到不要使用for in ...

  6. JavaScript学习笔记系列2:Dom操作(一)

    一.什么是Dom? DOM------>Document Object Model 直接翻译就是文档对象模型. DOM------>定义了表示和修改文档所需的对象.这些对象的行为和属性以及 ...

  7. 《高性能javascript》 领悟随笔之-------DOM编程篇(二)

    <高性能javascript> 领悟随笔之-------DOM编程篇二 序:在javaSctipt中,ECMASCRIPT规定了它的语法,BOM实现了页面与浏览器的交互,而DOM则承载着整 ...

  8. 《高性能javascript》 领悟随笔之-------DOM编程篇

    <高性能javascript> 领悟随笔之-------DOM编程篇一 序:在javaSctipt中,ECMASCRIPT规定了它的语法,BOM实现了页面与浏览器的交互,而DOM则承载着整 ...

  9. Javascript学习笔记三——操作DOM(二)

    Javascript学习笔记 在我的上一个博客讲了对于DOM的基本操作内容,这篇继续巩固一下对于DOM的更新,插入和删除的操作. 对于HTML解析的DOM树来说,我们肯定会时不时对其进行一些更改,在原 ...

随机推荐

  1. Android_文件存储

    因为项目的需求,想实现一个指导使用的欢迎页效果,通过在网上的询问,给的一种解决办法是通过SharedPreferences文件存储方式来实现,具体的实现类似于通过第一次取得SharedPreferen ...

  2. Unity3D 常用插件

    1.FX Maker FX Maker是一款制作特效的工具,它专为移动操作系统做了优化.FX Maker包括300种Prefab特效,300种纹理结构.100种网格.100种曲线效果.支持英文和韩文, ...

  3. LeetCode:Find the Difference_389

    LeetCode:Find the Difference [问题再现] Given two strings s and t which consist of only lowercase letter ...

  4. 苹果官方发布,iPhone 6 & Plus 设计素材

    苹果发布 iPhone 6 和 iPhone 6 Plus 有一段时间了,据说首日预定量达到了创纪录的1600万部,真是不可思议.苹果已经创建了一些指引,让开发者可以受益.他们已经发布了一组苹果官方的 ...

  5. radialLine 径向线生成器

    radialLine 径向线生成器 使用默认的角度,半径访问器,和插值器函数构造一个 径向线生成器,返回的函数用以生成开放分段线性曲线.折线.它和line生成器很相似,只是将line的x,y访问其换位 ...

  6. Java Lambda表达式初探

    Java Lambda表达式初探 前言 本文受启发于Trisha Gee在JavaOne 2016的主题演讲Refactoring to Java 8. Java 8已经发行两年多,但很多人仍然在使用 ...

  7. 移动端中pagehide、pageshow的应用

    闲话少叙,来进入场景:订单提交页面,各种积分礼品卡规则都算好了,用户提交表单开始支付,支付完成进入成功提示页面,这是绝大部分网站的付款体验吧,那么问题来了,web移动端中进入成功提示页后,用户点击浏览 ...

  8. Visual Studio开发Cordova应用示例

    作者:Grey 原文地址:http://www.cnblogs.com/greyzeng/p/5455728.html 本文的GIF动画均使用ScreenToGif进行录制. Cordova是什么? ...

  9. [转载]MongoDB开发学习 经典入门

    如果你从来没有接触MongoDB或对MongoDB有一点了解,如果你是C#开发人员,那么你不妨花几分钟看看本文.本文将一步一步带您轻松入门. 阅读目录 一:简介 二:特点 三:下载安装和开启服务器 四 ...

  10. 解读 C 语言中的指针

    我想对很多学习C语言的新手来说,指针无疑是一个难点.但是,我觉得指针也是C语言特别重要的一个特性.也许,你在除了C和C++以外的编程语言中,很少看到指针.而C++中,也多用引用,而非指针.指针,作为一 ...