对于不断增长的web应用,性能优化,用户体验从未间断,如何逆水行舟,不进则退撤退。随着通信技术的飞速发展,Web应用程序在近几年迅速增加并流行起来,已经成为人们不可或缺的工具,充斥在生活、商务、娱乐、旅游、工作的方方面面。随着用户规模的扩大,Web应用的内容和功能也越来越丰富。各大应用的用户体验、流量、内存、性能优化也越来越高。人们不仅需要看到自己需要的内容,还对响应速度、动画的流畅度、浏览网页的等待时间等提出了非常大的要求。对于网页首屏的优化,我们尝试使用异步加载页面数据来提高用户的流畅度,同时也增加了一些离线模板的技术规划。在代码的底层组件上,我们引入了新的方向,减少用户点击事件后对页面DOM节点的操作,从而提升用户体验。我们希望slarkjs是一个简单、通用、易于理解和使用的框架,我们的团队成员也保持一个正常的心态来丰富我们的框架。我们希望slarkjs是很多初级h5开发者想要了解的东西。为了熟悉,我会用很多很白话的概念思路来分析我们的框架组件,给一些对h5和slarkjs感兴趣的前端开发童鞋,了解一下组件开发思路和框架概念。回到dom优化,一开始我们打算用domdiff的概念来进行数据比较,而这些数据比较完全是在js中实现的,精简之后再进行dom操作。举个简单的例子,一个dom节点可能是这样的:
- 1
- 2
- 3
- 4 /ul>我们想把它变成这样
- 1
- 2
- 3
- 5
- 6
- 6/li>就可以达到我们需要的结果。我们需要一个组件来帮助我们操作dom节点进行分析。一般的domdiff应用存在于大部分聊天室、评论区,以及一些dom经常被替换的地方。我们希望它是一个小的、方便的应用程序,一个适合框架的小应用程序。在开发期间,我们也花了将近两周的时间,对现在非常流行的react和react-native进行了详细的技术调研。不得不说react的开发效率是我目前见过最快的框架。他模块化开发的思想,virtualdom的概念是我非常喜欢的一种方式,我们也尝试将其合并到slarkjs框架中。一开始我们只是希望让它负责视图层的重绘,但实际上我们更希望它能够负责更多的内容。不幸的是,在web层面使用react有一定的局限性,需要花费大量的开发时间去修改一些组件。不幸的是,我们暂时停止了这个项目的开发进度,但是在应用程序上开发react-native是最有潜力的壮举。在接下来的文章中,我们将继续为大家带来slarkjs框架如何吸收react-native并将其融入到app的开发中。.现在让我们回到domdiff的逻辑。首先,我们在构建domdiff的时候,思路很简单,1.我们需要它接收2个参数,1.现在页面上的节点,2.我们需要让它看起来像什么。vardomdiff=function(oldid,newid){vara1=document.getElementById(oldid);vara2=document.getElementById(newid);vardd=newdiffDOM();dd.apply(a2,dd.diff(a2,a1));};vartdomdiff=function(oldid,newid){vara2=document.getElementById(oldid);vara3=document.createElement('div');a3.innerHTML=newid;vardd=newdiffDOM();dd.apply(a2,dd.差异(a2,a3));};2、我们需要它比较两个参数的数据,并把它放回一个列表中,这个列表包含最少的DOM操作if(!tree1||!tree2){returnfalse;}if(tree1.nodeType!==tree2.nodeType){returnfalse;}if(tree1.nodeType===3){if(tree2.nodeType!==3){returnfalse;}returnpreventRecursion?true:tree1.data===tree2.data;}if(tree1.nodeName!==tree2.nodeName){returnfalse;}if(tree1.tagName===tree2.tagName){....}if(tree1.childNodes.length!==tree2.childNodes.length){returnfalse;}3.实现listObject.keys(options).forEach(function(t){diff[t]=options[t];});从开发的角度来看,1、3是非常容易实现的,而第二步会让大部分前端开发者感到头疼。这时候我们需要引入两个容易被遗忘、不经常使用的属性nodeTpye和childNodes。其实有很多JS的Attributes是我们或者在业务开发和技术实现中很少用到的。相对来说,这也影响了我们更深入的技术开发方向,所以很多时候,我们提倡看一些伟大的开发者的代码。其实我们想看看他们使用了哪些属性以及他们的开发逻辑思路,而不是照搬他们的代码NodeType,这样我们就可以得到body元素的节点类型。简单来说,就是让我们知道当前节点是一个元素,属性,文本内容等。ChildNodes会让我们获取body元素的子节点集合,作为一个NodeList对象。简单的解释就是返回一个列表,这个列表包含了当前节点下的所有子节点,包括class、text、select、option等。后面就很容易分析我们的思路了。使用NodeType获取节点,判断节点属性。当然你还需要判断当前页面的节点是否唯一。然后使用ChildNodes比较节点属性之间的差异,需要添加一些属性作为标签,比如判断当前是否应该修改,修改的顺序等等。OK,开始吧,于是就有了如下逻辑图(点击图片查看大图)我们在diff中上传了一个空的list数组,然后将2个nodeType传给了finddiff,finddiff会做两件事,就是判断在finddiff-out中是否在body中是唯一的,然后把里面的数据分离出来,把第一个修改项加入到链表中,也就是最外层的修改项。然后使用Finddiff-inner中的ChildNodes分析内部结构,循环判断两组数据是否重叠。这里有一个小问题,就是需要用距离值来填充匹配得到相同的内容。例如:
- 1
- 2
- 3
- 4
- 1
- 5
- 6
- 3
- 4