浅析 innerHTML 性能优化的原理
昨天看了 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树里的节点, 也省去了其中复杂的一步
- 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 性能优化的原理的更多相关文章
- LeakCanary 内存泄漏 监测 性能优化 简介 原理 MD
Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...
- Tree-Shaking性能优化实践 - 原理篇
Tree-Shaking性能优化实践 - 原理篇 一. 什么是Tree-shaking 先来看一下Tree-shaking原始的本意 上图形象的解释了Tree-shaking 的本意,本文所说的前 ...
- react第八单元(什么是纯函数-组件的性能优化-pureComponent-组件性能优化的原理)
课程目标 理解纯函数 熟练掌握组件性能优化的几种技巧 pureComponent和Component的区别 #知识点 一个函数的返回结果只依赖于它的参数,并且在执行过程里面没有副作用,我们就把这个函数 ...
- 浅析Entity FrameWork性能优化
浅析EF性能优化 1. 数据Load 延迟加载:当实体第一次读取时,相关数据没有加载:当第一次试图访问导航属性时,所需的导航数据自动加载,EF默认使用这种方式加载数据,尽量使用预先加载和显 ...
- Android性能优化之数据库优化
本文为性能优化的第一篇——数据库性能优化,原理适用于大部分数据库包括Sqlite.Mysql.Oracle.Sql server,详细介绍了索引(优缺点.分类.场景.规则)和事务,最后介绍了部分单独针 ...
- Angular 的性能优化
目录 序言 变更检查机制 性能优化原理 性能优化方案 小结 参考 序言 本文将谈一谈 Angular 的性能优化,并且主要介绍与运行时相关的优化.在谈如何优化之前,首先我们需要明确什么样的页面是存在性 ...
- H5 缓存机制浅析 移动端 Web 加载性能优化
腾讯Bugly特约作者:贺辉超 1 H5 缓存机制介绍 H5,即 HTML5,是新一代的 HTML 标准,加入很多新的特性.离线存储(也可称为缓存机制)是其中一个非常重要的特性.H5 引入的离线存储, ...
- MySQL性能优化之max_connections配置参数浅析
这篇文章主要介绍了MySQL性能优化之max_connections配置参数浅析,本文着重讲解了3种配置max_connections参数的方法,需要的朋友可以参考下 MySQL的max_connec ...
- Tomcat性能优化及JVM内存工作原理
Java性能优化原则:代码运算性能.内存回收.应用配置(影响Java程序主要原因是垃圾回收,下面会重点介绍这方面) 代码层优化:避免过多循环嵌套.调用和复杂逻辑. Tomcat调优主要内容如下: 1. ...
随机推荐
- Vue安装及插件Vue Devtools
vue安装: # 最新稳定版 $ npm install vue # 全局安装 vue-cli $ npm install --global vue-cli # 创建一个基于 webpack 模板的新 ...
- HDU5890:Eighty seven(Bitset优化背包)
Mr. Fib is a mathematics teacher of a primary school. In the next lesson, he is planning to teach ch ...
- 【Codeforces 762A】 k-th divisor
[题目链接] 点击打开链接 [算法] 我们知道,一个数的因子是成对出现的,一半小于等于sqrt(N),一半大于sqrt(N),因此,我们可以从 2..sqrt(N)枚举因子 [代码] #include ...
- 【旧文章搬运】获取并修改PEB中的映像路径,命令行和当前目录
原文发表于百度空间,2008-7-24 当时对UNICODE_STRING的使用还有点问题,导致最终效果图中字符串被截断了======================================= ...
- linux中用管道实现父子进程通信
1 用户要实现父进程到子进程的数据通道,可以在父进程关闭管道读出一端, 然后相应的子进程关闭管道的输入端. 2 先用pipe()建立管道 然后fork函数创建子进程.父进程向子进程发消息,子进程读消息 ...
- Codeforces702A - Maximum Increase【尺取】
题意: 求一个连续的最长子序列长度: 思路: 没看仔细还wa1了-以为LIS- 然后写了尺取吧...= =太不仔细了.不过收获是LIS特么写挫了然后看了学长的blog<-点我- 题目的挫code ...
- hdoj1078【DP·记忆化搜索】
还是满水的一道题目吧...这个一看肯定要搜索了..然后又是这么DP,那就是记忆化搜索了...走K步,下一步要比他多...很好写啊/// #include<iostream> #includ ...
- Robotframework自动化系列:筛选结果数量统计
Robotframework自动化系统:筛选结果数量统计 上一个节点已经可以随机选中某一个下拉框的值,我们在使用evaluate随机数的时候需要计算下拉选项总数,这时候我们是手工计算输入的:这时候如果 ...
- CF126B Password【KMP】By cellur925
题目传送门 其实$Chemist$在之前写了非常棒的题解! 我长话短说,补充两句. “那么当$next[n]$>$max$时显然不能将$next[n]$作为最长子串的长度”这句话其实在说,因为一 ...
- TensorFlow多线程输入数据处理框架(四)——输入数据处理框架
参考书 <TensorFlow:实战Google深度学习框架>(第2版) 输入数据处理的整个流程. #!/usr/bin/env python # -*- coding: UTF-8 -* ...