昨天看了 lveyo老兄的"innerHTML的性能问题" 一文 http://lveyo.iteye.com/blog/182891

该文介绍了一篇老外的关于提高innerHTML性能的文章.

老外的方法非常的怪异且神奇.

很多朋友在惊叹之余 对于背后的原理非常感兴趣.
受hax的提醒, 我看了一下webkit的代码.在这里我将分析的结果分享出来

说的不一定对 还请大家多多拍砖.

浏览器在 el.innerHTML = newHTML 时所做的工作:

====================================
原始方法

1) 创建一个fragment(document碎片)
2) 将 newHTML 设置到 fragment 内部 (这里怎么设置的不必关心,反正不是用的innerHTML 呵呵)
3) 清除el下的所有子节点 ,  类似 el.removeChildren()
4) 将fragment加入到 el内, 类似 el.appendChild(fragment)

====================================
文章里的新方法

1)克隆el节点(不包含子节点),相当于
newEl=document.createElement(el.tagName);
然或将el的所有属性赋值给 newEl  (通过 el.getAttribute  newEl.setAttribute)

2) 创建一个fragment(document碎片)
3) 将 newHTML 设置到 fragment 内部 (这里怎么设置的不必关心,反正不是用的innerHTML 呵呵)
4) 清除 newEl 下的所有子节点 ,  类似 newEl.removeChildren()
5) 将 fragment 加入到 newEl 内, 类似 newEl.appendChild(fragment)
6) 用 fragment 替换 el. 相当于 el.parentNode.replaceChild(newEl, el);

新方法看起来比原始方法更麻烦, 但是为什么速度会更快呢?

关键点就是在 新方法的步骤 4 5 6 .
首先看4:
newEl 是clone的el,但是没有子结点,所以removeChildren很快就返回.相当于没有执行.
而且就算newEL有子结点,由于newEl不是一个在dom树里的节点, 也省去了其中复杂的一步

  1. if (n->inDocument())  n->removedFromDocument();
        if (n->inDocument())  n->removedFromDocument();
	

而 el.removeChildren 这个操作 相比之下自然要耗时很多.原因有三:removeChild操作比较复杂;el有子节点;el和el的子结点都在dom树内.

再来看5
newEl 和 fragment 本身都是脱离dom树独立存在的,这个操作速度也要比el.appendChild(fragment)快.

再来看6. 
6的操作就是 在el.parentNode中移除el,然后再在原始位置加入newEl. 这个步骤并没有速度优势.
但是 4 5 6这3个操作加起来,当el和newHTML足够复杂时,还是要比原始方法的 3 4 步更快

以上就是我的分析 有不对的地方 欢迎大家抛砖.
同时欢迎大家来贴一下 IE 和 ff的实现方式

浅析 innerHTML 性能优化的原理的更多相关文章

  1. LeakCanary 内存泄漏 监测 性能优化 简介 原理 MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  2. Tree-Shaking性能优化实践 - 原理篇

    Tree-Shaking性能优化实践 - 原理篇   一. 什么是Tree-shaking 先来看一下Tree-shaking原始的本意 上图形象的解释了Tree-shaking 的本意,本文所说的前 ...

  3. react第八单元(什么是纯函数-组件的性能优化-pureComponent-组件性能优化的原理)

    课程目标 理解纯函数 熟练掌握组件性能优化的几种技巧 pureComponent和Component的区别 #知识点 一个函数的返回结果只依赖于它的参数,并且在执行过程里面没有副作用,我们就把这个函数 ...

  4. 浅析Entity FrameWork性能优化

    浅析EF性能优化 1.       数据Load 延迟加载:当实体第一次读取时,相关数据没有加载:当第一次试图访问导航属性时,所需的导航数据自动加载,EF默认使用这种方式加载数据,尽量使用预先加载和显 ...

  5. Android性能优化之数据库优化

    本文为性能优化的第一篇——数据库性能优化,原理适用于大部分数据库包括Sqlite.Mysql.Oracle.Sql server,详细介绍了索引(优缺点.分类.场景.规则)和事务,最后介绍了部分单独针 ...

  6. Angular 的性能优化

    目录 序言 变更检查机制 性能优化原理 性能优化方案 小结 参考 序言 本文将谈一谈 Angular 的性能优化,并且主要介绍与运行时相关的优化.在谈如何优化之前,首先我们需要明确什么样的页面是存在性 ...

  7. H5 缓存机制浅析 移动端 Web 加载性能优化

    腾讯Bugly特约作者:贺辉超 1 H5 缓存机制介绍 H5,即 HTML5,是新一代的 HTML 标准,加入很多新的特性.离线存储(也可称为缓存机制)是其中一个非常重要的特性.H5 引入的离线存储, ...

  8. MySQL性能优化之max_connections配置参数浅析

    这篇文章主要介绍了MySQL性能优化之max_connections配置参数浅析,本文着重讲解了3种配置max_connections参数的方法,需要的朋友可以参考下 MySQL的max_connec ...

  9. Tomcat性能优化及JVM内存工作原理

    Java性能优化原则:代码运算性能.内存回收.应用配置(影响Java程序主要原因是垃圾回收,下面会重点介绍这方面) 代码层优化:避免过多循环嵌套.调用和复杂逻辑. Tomcat调优主要内容如下: 1. ...

随机推荐

  1. Vue安装及插件Vue Devtools

    vue安装: # 最新稳定版 $ npm install vue # 全局安装 vue-cli $ npm install --global vue-cli # 创建一个基于 webpack 模板的新 ...

  2. HDU5890:Eighty seven(Bitset优化背包)

    Mr. Fib is a mathematics teacher of a primary school. In the next lesson, he is planning to teach ch ...

  3. 【Codeforces 762A】 k-th divisor

    [题目链接] 点击打开链接 [算法] 我们知道,一个数的因子是成对出现的,一半小于等于sqrt(N),一半大于sqrt(N),因此,我们可以从 2..sqrt(N)枚举因子 [代码] #include ...

  4. 【旧文章搬运】获取并修改PEB中的映像路径,命令行和当前目录

    原文发表于百度空间,2008-7-24 当时对UNICODE_STRING的使用还有点问题,导致最终效果图中字符串被截断了======================================= ...

  5. linux中用管道实现父子进程通信

    1 用户要实现父进程到子进程的数据通道,可以在父进程关闭管道读出一端, 然后相应的子进程关闭管道的输入端. 2 先用pipe()建立管道 然后fork函数创建子进程.父进程向子进程发消息,子进程读消息 ...

  6. Codeforces702A - Maximum Increase【尺取】

    题意: 求一个连续的最长子序列长度: 思路: 没看仔细还wa1了-以为LIS- 然后写了尺取吧...= =太不仔细了.不过收获是LIS特么写挫了然后看了学长的blog<-点我- 题目的挫code ...

  7. hdoj1078【DP·记忆化搜索】

    还是满水的一道题目吧...这个一看肯定要搜索了..然后又是这么DP,那就是记忆化搜索了...走K步,下一步要比他多...很好写啊/// #include<iostream> #includ ...

  8. Robotframework自动化系列:筛选结果数量统计

    Robotframework自动化系统:筛选结果数量统计 上一个节点已经可以随机选中某一个下拉框的值,我们在使用evaluate随机数的时候需要计算下拉选项总数,这时候我们是手工计算输入的:这时候如果 ...

  9. CF126B Password【KMP】By cellur925

    题目传送门 其实$Chemist$在之前写了非常棒的题解! 我长话短说,补充两句. “那么当$next[n]$>$max$时显然不能将$next[n]$作为最长子串的长度”这句话其实在说,因为一 ...

  10. TensorFlow多线程输入数据处理框架(四)——输入数据处理框架

    参考书 <TensorFlow:实战Google深度学习框架>(第2版) 输入数据处理的整个流程. #!/usr/bin/env python # -*- coding: UTF-8 -* ...