Web 前端设计模式--Dom重构...
1. 设计场景
某个周末的早上躲在家里睡大觉,突然我们老大(亿网公司的技术总监)一个电话拨过来,他说:智华,你赶紧从床上跳起来,不要刷牙,不要洗脸,滚到电脑面前,打开电脑,我们的印刷网(http://www.51ysw.com/index.html)出问题了...
等我收拾完毕,打开电脑,果然发现印刷网的问题:首页那边有一个产品浏览的版块在延迟载入的时候,将我所有的隐藏帧的项都显示出来(如图,我本意是显示两行图片,可是在载入卡住,将下面一些隐藏元素都显示出来了),整体画面粗糙凌乱,整个网页完全载入并顺利运行的时间延迟超过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里面 ,尝试一下,确实性能高了很多...

<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>
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | /隐藏标签 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标签...该方法有个名称,叫做“多阶段下载...”,这样就不用每次都进行元素更新,代码如下...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 | //隐藏标签 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树的不断更新而造成页面显示性能低下...
如图:
源码下载:(https://files.cnblogs.com/wzh2010/DomForm.rar)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)