Web 前端设计模式--Dom重构 提高显示性能


Posted in Javascript onOctober 22, 2010

1. 设计场景

首页那边有一个产品浏览的版块在延迟载入的时候,将我所有的隐藏帧的项都显示出来(如图,我本意是显示两行图片,可是在载入卡住,将下面一些隐藏元素都显示出来了),整体画面粗糙凌乱,整个网页完全载入并顺利运行的时间延迟超过5秒,在这种交互性极强的在线印刷网站是非常致命的,这给用户一种极其糟糕的Web体验,并归结为网站的不稳定...

此时不能责怪公司的服务器烂,网速卡之类的,那样很可能会导致老大对我一顿胖揍甚至扣奖金...
所以只能从网站性能方面进行改良...

2.设计目标
减少页面载入时不必要的元素,构建一个轻量级的Web页面...

3.解决方案
当初我接到这个Case的时候,最初的设计方案毫无疑问是隐藏帧做法,这是最好用也是最容易简单的,它的方法就是将四个标签tab(画册,手提袋,挂历,包装)所对应的四个Div全部载入页面,并在载入时显示第一个tab(画册)的Div,在鼠标轮滑过tab的时候显示相应tab标签的Div,隐藏其他tab标签的Div...
因此才会出现上述的情况,我想起我前一天晚上看的一本Web设计模式的书,上面的一段话引曾起我的注意:使用页面元素更新来重构Dom树往往比隐藏帧的性能要高得多...所以此时我的想法便是重构Dom树...

Web页面的源码很简单,重要的在于 id="tabcontent" 的那个Div,它是关键,它里面元素的变换取决于上面的四个<li>标签,当鼠标经过时就将不同的内容更新到Div里面,这使得页面不用一开始就将所有的元素都载入,并进行不厌其烦的隐藏和显示,实现代码如下。。。
这样,就有四个id分别tabcontent1,tabcontent2,tabcontent3,tabcontent4为Div不断的轮换 替换进id="tabcontent"的 Div里面 ,尝试一下,确实性能高了很多...

<div class="menu"> 
<ul> 
<li><a href="#" id="tablink1" onclick="return false">包装盒 </a></li> 
<li><a href="#" id="tablink2" onclick="return false">画册 </a></li> 
<li><a href="#" id="tablink3" onclick="return false">手提袋 </a></li> 
<li><a href="#" id="tablink4" onclick="return false">三折页 </a></li> 
</ul> 
</div> 
<div class="border2 w1" id="tabcontent"> 
</div>

/隐藏标签 
function tabs(i) 
{ 
var num,ids,ordnum; 
switch(i) 
{ 
case 1:{ append(1,1,"f"); break;} 
case 2:{ append(2,5,"s"); break;} 
case 3:{ append(3,9,"t"); break;} 
case 4:{ append(4,13,"fo"); break;} 
} 
} //更新数据 
function append(i,j,type) 
{ 
var str="<div class='show_img h3' id='tabcontent"+i+"'>"; 
str+="<div id='"+type+"demo' class='demo'>"; 
str+="<div id='"+type+"indemo' class='indemo'>"; 
str+="<div id='"+type+"demo1' class='demo1'>"; 
str+="<a href='#'><img src='img/"+j+".png' border='0' /></a>"; 
str+="<a href='#'><img src='img/"+ (++j) +".png' border='0' /></a>"; 
str+="<a href='#'><img src='img/"+ (++j) +".png' border='0' /></a>"; 
str+="<a href='#'><img src='img/"+ (++j) +".png' border='0' /></a>"; 
str+="</div>"; 
str+="<div id='"+type+"demo2' class='demo2'></div>"; 
str+="</div></div><div>"; 
$("#tabcontent").html(str); 
}

到这里应该算结束,可是我突然想起一个问题,这种做法其实和jQuery中的hover思想是一样的,而这边是进行轮询的Dom元素更新,也就是说每一次鼠标移动标签都要有一些数据要发送和接收,相对与上面小段数据是没什么影响,但是大的Case中使用这种方法就不可行,因为它的Dom元素更新可能是十几kb甚至几十kb的数据流,这无疑给Web页面的性能带来极大的挑战...

因此,我又做了一个小小的改动,那就是使用Dom重构+隐藏帧用法,在页面第一次载入的时候,先载入的是第一个标签所对应的Div,即画册所对应的Div,当鼠标移到其他tab标签时候,追加该标签所对应的元素(该元素若存在则去掉隐藏并显示,不存在则追加),并隐藏其他Tab标签所对应的Div标签...该方法有个名称,叫做“多阶段下载...”,这样就不用每次都进行元素更新,代码如下...

//隐藏标签 
function tabs(i) 
{ 
for(var j=1;j<5;j++) 
{ 
$("#tabcontent"+j).hide(); 
} 
$("#tabcontent"+i).show(); 
var num,ids,ordnum; 
var len= $("#tabcontent"+i).length;//这句话很重要,它是杜绝将元素重复载入的判断(如果该元素存在,就不需再次追加) 
if(len==0) 
{ 
switch(i) 
{ 
case 1:{ append(1,1,"f"); break;} 
case 2:{ append(2,5,"s"); break;} 
case 3:{ append(3,9,"t"); break;} 
case 4:{ append(4,13,"fo"); break;} 
} 
} 
} //载入数据 
function append(i,j,type) 
{ 
var str="<div class='show_img h3' id='tabcontent"+i+"'>"; 
str+="<div id='"+type+"demo' class='demo'>"; 
str+="<div id='"+type+"indemo' class='indemo'>"; 
str+="<div id='"+type+"demo1' class='demo1'>"; 
str+="<a href='#'><img src='img/"+j+".png' border='0' /></a>"; 
str+="<a href='#'><img src='img/"+ (++j) +".png' border='0' /></a>"; 
str+="<a href='#'><img src='img/"+ (++j) +".png' border='0' /></a>"; 
str+="<a href='#'><img src='img/"+ (++j) +".png' border='0' /></a>"; 
str+="</div>"; 
str+="<div id='"+type+"demo2' class='demo2'></div>"; 
str+="</div></div><div>"; 
$("#tabcontent").append(str); 
}

4.设计小结
网站的性能提高了,既不会出现在首次载入的时候页面元素负荷过重而造成的延迟,也不会因为Dom树的不断更新而造成页面显示性能低下...

如图:
Web 前端设计模式--Dom重构 提高显示性能

源码下载 /201010/yuanma/DomForm.rar

Javascript 相关文章推荐
JavaScript中操作字符串小结
May 04 Javascript
基于jQuery实现的菜单切换效果
Oct 16 Javascript
一览画面点击复选框后获取多个id值的方法
May 30 Javascript
JSON格式的时间/Date(2367828670431)/格式转为正常的年-月-日 格式的代码
Jul 27 Javascript
JavaScript蒙板(model)功能的简单实现代码
Aug 04 Javascript
javascript数据类型详解
Feb 07 Javascript
快速解决vue-cli不能初始化webpack模板的问题
Mar 20 Javascript
今天,小程序正式支持 SVG
Apr 20 Javascript
JS根据Unix时间戳显示发布时间是多久前【项目实测】
Jul 10 Javascript
Bootstrap table 实现树形表格联动选中联动取消功能
Sep 30 Javascript
Vue+Element ui 根据后台返回数据设置动态表头操作
Sep 21 Javascript
vuex中遇到的坑,vuex数据改变,组件中页面不渲染操作
Nov 16 Javascript
jQuery中add实现同时选择两个id对象
Oct 22 #Javascript
jquery下动态显示jqGrid以及jqGrid的属性设置容易出现问题的解决方法
Oct 22 #Javascript
为jQuery.Treeview添加右键菜单的实现代码
Oct 22 #Javascript
使用jQuery模板来展现json数据的代码
Oct 22 #Javascript
jQuery 表单验证扩展(四)
Oct 20 #Javascript
jQuery 表单验证扩展(三)
Oct 20 #Javascript
jQuery 表单验证扩展代码(二)
Oct 20 #Javascript
You might like
PHP 类相关函数的使用详解
2013/05/10 PHP
PHP打印输出函数汇总
2016/08/28 PHP
ThinkPHP框架实现的邮箱激活功能示例
2018/06/15 PHP
JSON 编辑器实现代码
2009/12/06 Javascript
Jquery 常用方法经典总结
2010/01/28 Javascript
javascript基础知识大集锦(二) 推荐收藏
2011/01/13 Javascript
js window.print实现打印特定控件或内容
2013/09/16 Javascript
Flexigrid在IE下不显示数据的处理的解决方法
2013/10/24 Javascript
深入理解javascript变量声明
2014/11/20 Javascript
Javascript基础教程之if条件语句
2015/01/18 Javascript
jQuery实现垂直半透明手风琴特效代码分享
2015/08/21 Javascript
jQuery animate()实现背景色渐变效果的处理方法【使用jQuery.color.js插件】
2017/03/15 Javascript
React Native使用百度Echarts显示图表的示例代码
2017/11/07 Javascript
解决node修改后需频繁手动重启的问题
2018/05/13 Javascript
使用D3.js构建实时图形的示例代码
2018/08/28 Javascript
koa大型web项目中使用路由装饰器的方法示例
2019/04/02 Javascript
微信小程序停止其他视频播放当前视频的实例代码
2019/12/25 Javascript
如何通过JS实现转码与解码
2020/02/21 Javascript
python实现分析apache和nginx日志文件并输出访客ip列表的方法
2015/04/04 Python
Python使用pygame模块编写俄罗斯方块游戏的代码实例
2015/12/08 Python
python连接mysql实例分享
2016/10/09 Python
Python编程判断一个正整数是否为素数的方法
2017/04/14 Python
详解将Django部署到Centos7全攻略
2018/09/26 Python
Python在图片中插入大量文字并且自动换行
2019/01/02 Python
centos 安装Python3 及对应的pip教程详解
2019/06/28 Python
python中的函数递归和迭代原理解析
2019/11/14 Python
浅谈tensorflow中dataset.shuffle和dataset.batch dataset.repeat注意点
2020/06/08 Python
工商学院毕业生个人自我评价
2013/09/19 职场文书
2014年十一国庆向国旗敬礼寄语
2014/04/11 职场文书
旅游安全协议书
2014/04/21 职场文书
事业单位人员的自我评价范文
2014/09/21 职场文书
社区务虚会发言材料
2014/10/20 职场文书
群众路线自查自纠工作情况报告
2014/10/28 职场文书
运动员入场前导词
2015/07/20 职场文书
SQL基础的查询语句
2021/11/11 MySQL
Win11怎么启动任务管理器?Win11启动任务管理器的几种方法
2021/11/23 数码科技