`
byf157
  • 浏览: 207760 次
  • 性别: Icon_minigender_1
  • 来自: 石家庄
社区版块
存档分类
最新评论

js性能优化调试

    博客分类:
  • java
阅读更多

客户端动态输出table数据并展示表格,是web应用中较为常见的工作。对于循环打印输出tr,td本身是一件非常僵硬和暴力的编程办法,再加上最后绑定元素innerHTML字符流输出,
系统所消耗的性能代价是非常高昂的,如果我们需要展现的数据非常庞大时,那么代价也是成倍的。然而这种动态输出表格的方法是大多数客户端程序员最常用的方法。那么基于最常用的方法,
如何才能降低性能成本,改善用户体验,快速安全的显示我们所需要的数据呢?
我认为从根本上调优需要从两个方面去考虑。
1:server的数据吐出和client的数据解析。这里涉及的知识点较多,今后再做详细的说明。但是对于较为复杂的xml的数据格式来说,client的解析应该用xpath寻址和dom内置对象相结合的方法,高速定位。
2:DHTML的优化。包括dom,css,js的优化,也就是MVC(model, view, control)的优化。
这里我们用js动态生成一个table, 构建一个3000行,8列的表格,代码分多个版本,便于清晰的比较每个版本不同的性能消耗。
vision 0.1 【耗时14694ms】
貌似以下的写法是没有任何错误,但是确是最暴力,效率最低,性能消耗最大的写法。对于大量的数据行和列,用for循环拼接元素字符串,最后innerHTML输出是不可取的。
3000记录页面加载耗时14694毫秒,近15秒。这样的页面数据加载是近乎灾难的,应该竭力避免。
<html>
 <body>
  <div id="tableDiv"></div>
  <script>
   var maxRow =3000;
   var maxCol = 8;
   var strTbl = "<table border='1'><tbody>";
   var strTbody = '';
  
   for(var i = 0; i < maxRow; i++){
    strTbody +="<tr>";
     for(var j = 0; j < maxCol; j++){
      strTbody += "<td>test</td>";
     }
    strTbody += "</tr>";
   }
   strTbl = strTbody + "</tbody></table>";
  
   var obj = document.getElementById("tableDiv");
   obj.innerHTML = strTbl;
  
  </script>
 </body>
</html>

vision 0.2 【耗时3623ms】
这个版本的代码有非常大的改进,采用DOM技术动态添加元素,说明在需要处理展现大量数据的情况下,运用DOM快速定位并添加绑定元素的方法,效率远比拼接html元素字符串的方法要高许多。
整个页面加载完成所耗的时间为3623毫秒。3000行的记录耗时不到4秒,这个版本的代码结构和编程思路也无可挑剔, 那么这样的加载速度是否可以再快些呢?
<html>
<body>
<script>
  var _table, _tbody, tr, td, text, maxRow, maxCol;
  maxRow = 3000;
  maxCol = 8;
 
  _table = document.createElement("table");
  _table.border = "1";
  _tbody = document.createElement("tbody");
  _table.insertBefore(_tbody, null);
 
  document.body.insertBefore(_table, null);
  for (var i=0; i<maxRow; i++) {
  tr = document.createElement("tr");
  for(var j = 0; j<maxCol; j++){
   td = document.createElement("td");
   text = document.createTextNode("Text");
   td.insertBefore(text, null);
   tr.insertBefore(td, null);
  }
     _tbody.insertBefore(tr, null);
  }
</script>
</body>
</html>

vision 0.3 【耗时3320ms】
基于vision 0.2中的代码,我们可以看到,整个代码段有多处用到了"body","window","document"这样的对象,在js中类似这样的对象都为全局对象,对他们的引用操作势必会消耗性能
对这些全局变量引用要比简单通过局部变量引用的代价要昂贵的多。
这里我们可以将"document.body"的引用缓存到局部变量中,这样就完成了一个将全局对象转换成局部变量的过程。
在代码中添加:var docBody = document.body;并且将行:document.body.insertBefore(_table, null);替换为:docBody.insertBefore(_table, null);
在代码中对"document"单个全局对象的引用就达到8×3000=24000次之多,获取一个document变量比局部变量大约多花费4ms时间, 所以我们下一步把document对象也缓存起来。
在代码中添加:var _doc = document;
这样,我们重新加载页面,所耗时间为3320毫秒。只比上个版本所耗的时间减少了10%,似乎性能相差不大,但是在我们日常的开发习惯中,将全局的对象缓存到局部变量中是一个好的开始。
<html>
<body>
<script>
  var _table, _tbody, tr, td, text, maxRow, maxCol;
  var docBody = document.body;
  var _doc = document;
  maxRow = 3000;
  maxCol = 8;
 
  _table = _doc.createElement("table");
  _table.border = "1";
  _tbody = _doc.createElement("tbody");
  _table.insertBefore(_tbody, null);
 
  docBody.insertBefore(_table, null);
  for (var i=0; i<maxRow; i++) {
  tr = _doc.createElement("tr");
  for(var j = 0; j<maxCol; j++){
   td = _doc.createElement("td");
   text = _doc.createTextNode("Text");
   td.insertBefore(text, null);
   tr.insertBefore(td, null);
  }
     _tbody.insertBefore(tr, null);
  }
</script>
</body>
</html>
vision 0.4 【耗时2779ms】
一个document对象加载速度的优化就是在<script>标签指定defer属性。首先在这里简单介绍一下defer属性。defer作用是文档加载完毕了再执行脚本,这样回避免找不到对象的问题,
加上defer等于在页面完全在入后再执行,相当于window.onload,但应用上比window.onload 更灵活。设置这个属性仅适合不需要立即运行<SCRIPT>中代码的情况。
(立即运行的代码指不在函数体内的--这些代码将会在脚本块加载后立即执行)当defer属性设置后,IE不会等待加载和转换这段脚本。这就也为着页面加载会快很多。
通常这意味着立即运行的脚本应该封装放在一个函数内,并通过document或者body的onload的事件处理。如果你的脚本是依赖于页面加载后的用户动作,如点击按钮,或者移动鼠标到某个区域,会更加有用!
最后请注意两点:
1、不要在defer型的脚本程序段中调用document.write命令,因为document.write将产生直接输出效果。
2、不要在defer型脚本程序段中包括任何立即执行脚本要使用的全局变量或者函数。
<html>
<body onload="init()">
<script defer>
function init() {
  var _table, _tbody, tr, td, text, maxRow, maxCol;
  var docBody = document.body;
  var _doc = document;
  maxRow = 3000;
  maxCol = 8;
 
  _table = _doc.createElement("table");
  _table.border = "1";
  _tbody = _doc.createElement("tbody");
  _table.insertBefore(_tbody, null);
 
  docBody.insertBefore(_table, null);
  for (var i=0; i<maxRow; i++) {
  tr = _doc.createElement("tr");
  for(var j = 0; j<maxCol; j++){
   td = _doc.createElement("td");
   text = _doc.createTextNode("Text");
   td.insertBefore(text, null);
   tr.insertBefore(td, null);
  }
     _tbody.insertBefore(tr, null);
  }
}
</script>
</body>
</html>
 
 vision 0.5 【耗时2650ms】
 上一个版本中的页面加载速度已经缩短到了2779ms。下面我们对代码进行进一步的优化。
 我们看到代码中dom操作,绑定子元素的方法是由下至上包裹,这样的元素绑定方式会相对较慢。
  create <TR>
  create <TD>
  create TextNode
第一步 insert TextNode into <TD>
第二步 insert <TD> into <TR>
第三步 insert <TR> into TBODY
 
 现在我们将元素的绑定顺序颠倒过来,由上至下的包裹绑定元素
  create <TR>
  create <TD>
  create TextNode
第一步 insert <TR> into TBODY
第二步 insert <TD> into <TR>
第三步 insert TextNode into <TD>
<html>
<body onload="init()">
<script defer>
function init() {
  var _table, _tbody, tr, td, text, maxRow, maxCol;
  var docBody = document.body;
  var _doc = document;
  maxRow = 3000;
  maxCol = 8;
 
  _table = _doc.createElement("table");
  _table.border = "1";
  _tbody = _doc.createElement("tbody");
  _table.insertBefore(_tbody, null);
  docBody.insertBefore(_table, null);
 
  for (var i=0; i<maxRow; i++) {
  tr = _doc.createElement("tr");
   _tbody.insertBefore(tr, null);
  for(var j = 0; j<maxCol; j++){
   td = _doc.createElement("td");
   text = _doc.createTextNode("Text");
   td.insertBefore(text, null);
   tr.insertBefore(td, null);
  }
  }
}
</script>
</body>
</html>

vision 0.6 【耗时2580ms】
这个版本中我们要调优的是修改table的css属性,使用fixed-table布局(layout)。指定了fixed-table布局后的表格的列宽使用<col>标签设置。
fixed-table布局样式将改善table的性能,因为每个单元格的内容的尺寸不需要进行计算了。这是一个非常实用的性能改善方法,特别是那些有很多列的大型表格。
这个操作也可以通过简单增加css样式实现:
<html>
<body onload="init()">
<script defer>
function init() {
  var _table, _tbody, tr, td, text, maxRow, maxCol;
  var docBody = document.body;
  var _doc = document;
  maxRow = 3000;
  maxCol = 8;
 
  _table = _doc.createElement("table");
  _table.border = "1";
  _table.style.tableLayout = "fixed";
  _tbody = _doc.createElement("tbody");
  _table.insertBefore(_tbody, null);
  docBody.insertBefore(_table, null);
 
  for (var i=0; i<maxRow; i++) {
  tr = _doc.createElement("tr");
   _tbody.insertBefore(tr, null);
  for(var j = 0; j<maxCol; j++){
   td = _doc.createElement("td");
   text = _doc.createTextNode("Text");
   td.insertBefore(text, null);
   tr.insertBefore(td, null);
  }
  }
}
</script>
</body>
</html>

vision 0.7 【耗时2210ms】
最后的一个版本的调优就是给单元格赋值的方式。在所有的示例中,创建了一个TextNode,并添加给TD。而在这个版本中我们将使用innerText代替插入一个text节点,代码调整为:
td.innerText = "Text";
(注意:innerText只在IE中受支持,属于IE扩展,兼容FireFox可使用innerHTML,但是innerHTML正如文章开头所说的,效率非常低下,不建议使用)
<html>
<body onload="init()">
<script defer>
  function init() {
  var _table, _tbody, tr, td, text, maxRow, maxCol;
  var docBody = document.body;
  var _doc = document;
  maxRow = 3000;
  maxCol = 8;
 
  _table = _doc.createElement("table");
  _table.border = "1";
  _table.style.tableLayout = "fixed";
  _tbody = _doc.createElement("tbody");
 
  docBody.insertBefore(_table, null);
  _table.insertBefore(_tbody, null);
 
  for (var i=0; i<maxRow; i++) {
  tr = _doc.createElement("tr");
   _tbody.insertBefore(tr, null);
  for(var j = 0; j<maxCol; j++){
   td = _doc.createElement("td");
   td.innerText = "Text";
   tr.insertBefore(td, null);
  }
  }
}
</script>
</body>
</html>

vision 0.8 【耗时672ms】终极优化
将字符串作为数组对象的方式是目前效率最高,性能最优的方式。
<script>
 var t1 = new Date();
</script>
<html>
 <head>
  <title></title>
  <script>
   function testTime(){
    var t2 = new Date();
    alert(t2-t1+"ms");
   }
  
  </script>
 
 </head>
 <body onload="init();testTime();">
  <div id="tableDiv"></div>
  <script>
   var maxRow =3000;
   var maxCol = 8;
   var strTbody = ["<table border='1'><tbody>"];
  
   for(var i = 0; i < maxRow; i++){
    strTbody.push("<tr>");
     for(var j = 0; j < maxCol; j++){
      strTbody.push("<td>test</td>");
     }
    strTbody.push("</tr>");
   }
  
   strTbody.push("</tbody></table>");
  
   var obj = document.getElementById("tableDiv");
   obj.innerHTML = strTbody.join("");
  </script>
 </body>
</html>

分享到:
评论

相关推荐

    js调试工具,javascript调试工具

    除了基本的断点调试,现代JavaScript调试工具还提供了性能分析功能,如Chrome的Timeline和Profiler面板,用于测量代码执行时间、内存占用、CPU使用率等,帮助优化代码性能。 六、错误追踪与日志记录 利用`console....

    鬼鬼调试JS工具7.5(鬼鬼调试工具)

    【鬼鬼调试JS工具7.5】是一款专为JavaScript开发者设计的强大调试工具,它提供了丰富的功能,帮助开发者在JS代码的编写过程中进行错误检测、性能优化以及代码调试。这款工具以其简洁的用户界面和高效的调试能力深受...

    鬼鬼JS调试工具

    7. **性能分析**:鬼鬼JS调试工具还包含了性能分析模块,可以帮助开发者发现代码中的性能瓶颈,进行优化。 8. **网络请求监控**:对于涉及网络交互的项目,工具可以记录所有的HTTP/HTTPS请求,分析请求的细节,如...

    发条js调试工具.rar

    总的来说,发条JS调试工具是一个全面的解决方案,旨在帮助JavaScript开发者在各个阶段进行高效的代码调试,解决各种类型的问题,无论是语法错误、逻辑问题还是性能瓶颈。通过熟练掌握这个工具,开发者可以大大提高...

    WT-JS逆向调试工具

    3. **性能分析**:可能包含性能剖析功能,监测CPU使用率,内存占用,以及函数调用耗时,辅助性能优化。 4. **源码映射**:对于压缩或编译后的代码,WT-JS可能支持源码映射,使开发者能直接在原始源码上进行调试。 ...

    js调试工具,v7.5爬虫工程师必备

    JavaScript是Web开发中的核心语言,尤其对于爬虫工程师而言,理解和掌握JS的调试技巧至关重要。本文将详细介绍一款名为“编程喵JS调试工具”的版本7.5,它专为爬虫工程师设计,支持V8引擎和浏览器环境下的JS调试,...

    鬼鬼js调试工具 js逆向必备

    **鬼鬼JS调试工具**是专门针对JavaScript代码进行逆向工程的一款强大工具,尤其对于JS逆向分析工作来说,它是不可或缺的辅助软件。在互联网安全领域,JavaScript逆向工程经常被用于理解恶意代码的行为,或者在开发...

    发条js 调试工具下载 即用

    发条JS,又称Turbolinks,是由Ruby on Rails团队开发的一款前端性能优化库,旨在提高Web应用的页面切换速度,通过跟踪点击事件并只更新页面的必要部分,从而减少全页刷新,提升用户体验。Turbolinks的工作原理在于,...

    鬼鬼JS调试工具.zip

    除此之外,鬼鬼JS调试工具可能还集成了性能分析工具,用于检测和优化JavaScript代码的运行效率。通过分析函数调用的时间消耗,内存使用等,开发者可以发现性能瓶颈,优化代码,提高应用的响应速度和用户体验。 在...

    高性能网站建设进阶指南:WEB开发者性能优化最佳PDF

    《高性能网站建设进阶指南》是一本专为WEB开发者设计的性能优化手册,旨在帮助开发者们构建更快、更稳定、更高效的网站。这本书深入探讨了JavaWeb和Java在网站开发中的应用,结合实际案例,提供了丰富的优化策略和...

    发条JS调试工具JS-ED_1.9

    发条JS调试工具JS-ED 1.9是一款专为JavaScript开发者设计的强大调试工具,它可以帮助程序员高效地定位并解决代码中的错误,优化性能,以及提升开发效率。在本文中,我们将详细介绍JS-ED 1.9的主要功能、使用方法以及...

    好用的javascript调试工具

    Chrome的Performance面板可以帮助开发者分析页面加载和运行时性能,找出CPU或内存瓶颈,优化JavaScript的执行效率。 通过熟练掌握这些调试工具,开发者可以更有效地定位和修复JavaScript代码中的问题,提升开发效率...

    WT-JS_DEBUG v1.4 ,本地JS调试工具。

    然而,随着项目规模的扩大和复杂性的增加,JS代码的调试变得越来越必要,以确保代码的正确性、性能优化以及问题定位。 ### 二、WT-JS_DEBUG v1.4 的核心特性 1. **断点调试**:此工具允许用户在代码中设置断点,当...

    鬼鬼JS调试工具7.5.zip

    在鬼鬼JS调试工具中,V8引擎的集成使得开发者可以直接在调试环境中查看和分析V8引擎的执行情况,这对于理解和优化JS代码性能具有极大的帮助。 鬼鬼JS调试工具7.5.exe则是该工具的主程序文件,用户通过运行这个可...

    javascript 编辑调试工具

    3. **性能分析**:JavaScript性能分析工具如Chrome的Timeline或Performance面板,可以记录页面加载和用户交互时的性能数据,帮助开发者找到瓶颈并优化代码。 4. **代码质量和风格检查**:ESLint是一款流行的静态...

    jsdt JavaScript 调试工具

    在性能优化方面,`jsdt`提供性能分析工具,可以记录和分析代码的运行时间,找出性能瓶颈。这对于大型应用或性能敏感的项目尤其重要。你还可以使用内存分析工具监控内存使用情况,防止内存泄漏。 `jsdt`的文档(如...

    IE js调试工具

    由于 IE 浏览器的市场份额和兼容性需求,开发者常常需要面对 IE 特有的问题,这时就需要利用 IE 自带的 JavaScript 调试工具进行问题排查和性能优化。本文将详细介绍如何使用 IE 的 JS 调试工具。 ### 1. **开启...

Global site tag (gtag.js) - Google Analytics