手机版

Ajax非刷新分页的性能优化方法

时间:2021-09-09 来源:互联网 编辑:宝哥软件园 浏览:

Ajax没有刷新分页,这已经是大家耳熟能详的事情了。很可能是web首页上有一个js方法,通过Ajax请求服务器端的分页数据接口,获取数据后在页面上创建一个html结构呈现给用户,类似如下:

script type="text/javascript "函数getPage(page index){ Ajax({ URL : " Remote interface . CGI ",method:"get ",data : { page index : page index },callback : callback });}函数回调(datalist) {//todo:根据返回的datalist数据创建一个html结构并呈现给用户。}/script,其中RemoteInterface.cgi是服务器端接口。我们这里篇幅有限,涉及的示例代码可能不全,只是为了表达清楚意思。

在UI上,可能有各种样式的分页控件,大家都很熟悉,比如:

但这里只是用户点击控件来触发getPage(pageIndex)方法。这个getPage方法可能没那么简单。

根据代码片段1,我们可以想象用户每次点击翻页,都会请求RemoteInterface.cgi除了第一次,getPage(1)、getPage(2)、getPage(3)等触发的远程接口请求和进出网络的数据流量实际上是重复的,没有必要的。当第一次请求每个页面时,数据可以以某种形式缓存在页面上。如果用户有兴趣回看之前翻过的页面,getPage方法应该首先检查页面数据是否包含在本地缓存中,如果包含,将直接重新显示给用户,而不是调用远程接口。根据这个想法,我们可以修改代码片段1如下:

script type=" text/JavaScript " var page datalist={ };函数get page(page index){ if(page datalist[page index]){//如果本地数据列表包含当前请求的页码的数据,show page(page datalist[page index])//直接显示当前数据} else { Ajax({ URL : " remote interface . CGI ",method:"get ",data : { page index 3360 page index },callback : callback });} }函数回调(pageIndex,datalist){ page datalist[page index]=datalist;//缓存数据show page(data list);//show data}函数showpage (datalist) {//todo:根据返回的datalist数据创建一个html结构并呈现给用户。}/script这节省了网络请求的往返时间,更重要的是节省了宝贵的网络流量,减轻了接口服务器的负担。在低网速环境下或者接口服务器的运行压力已经比较大的情况下,这种必要的改进可以表现出明显的优化效果。雅虎34篇著名文章中的第一篇是尽量减少HTTP请求的数量。Ajax的异步请求无疑在http请求的范围之内。访问量小的Web应用可能会觉得没必要,但想象一下,如果有一个页面每天访问量1000万,用户平均翻5页,重复浏览一页。那么这样的页面按照代码片段1的写入平均每天会触发5000万个数据请求,而按照代码片段2的写入平均至少可以减少1000万个请求。如果每次请求的数据量为20kb,则可以节省1000万*20kb=200,000,000kb或约190G的网络流量。这样,节约的资源是相当可观的。

如果我们想更进一步,代码片段2中的数据缓存方法值得讨论。我们假设分页数据的时效性可以忽略,但这是实际应用中不可避免的问题。缓存无疑会导致时效性的下降,真正的缓存方案还应该依靠对应用时效性需求的分析和权衡。

对于不特别注重时效性的内容,页面上的缓存应该还是可以接受的。首先,用户不会一直停留在一个页面上,当页面之间出现跳转导致重新加载时,可以获得更新的数据。另外,如果用户有刷新页面的习惯,在特别想查看列表中是否有数据更新时,可以选择刷新页面。如果你追求完美,也可以考虑设置一个时间范围,比如5分钟。如果用户在当前页面停留超过5分钟,他会在5分钟内翻页时先读取页面上的缓存,然后在5分钟后翻页时再次请求服务器数据。

在某些情况下,如果我们能够预测数据更新的频率,比如距离数据更新还有多少天,我们甚至可以考虑使用本地存储,并且每隔一定时间只触发一次对服务器数据的请求,从而更彻底地节省请求数量和流量。当然,到底适用什么样的缓存方式,还要看产品的时效性要求,但原则上还是可以节省请求和流量,尽量节省,尤其是访问量大的页面。

对于一类时效性要求很高的数据,缓存是不是完全不适用?当然不是,只是整体思路又要改变了。一般来说,所谓的变化可能主要是列表中数据的增加、减少或变化,但大部分数据保持不变。在大多数情况下,上述设置仍然适用于特定时间段内的缓存。

如果需要实时更新数据,人们可能很容易想到使用计时器,比如每20秒执行一次getPage(pageIndex)并重新绘制列表。但是,只要想到之前假设的1000万页面访问量,就会发现这无疑是一件超级恐怖的事情。按照这个访问量和重试频率,服务器压力很大。至于如何应对这种情况,我想请大家看一下Gmail、163邮箱和新浪邮箱等。它们几乎同时满足了我们之前的假设:超大日访问量、实时数据更新等等。通过分析网络包捕获工具不难发现,当用户重复请求相同页码的数据时,他们不会向服务器发送请求。为了确保在消息更新时能够及时通知用户并更新邮件列表,可以使用定期重复的异步请求,但该请求只是状态查询,而不是列表刷新。只有在获得消息更新的状态时,才会发起获取更新数据的请求,或者状态查询界面发现有更新时,会直接返回更新的数据。其实163邮箱的常规状态查询都是设置长时间间隔的,大概是两分钟,新浪邮箱的时间间隔比较长,大概是五分钟。可以理解,他们正在尽最大努力减少请求数量。但这种处理方式可能不仅仅是前端单方面完成的,实施方案需要与后台接口整体考虑。

现在让我们回到代码片段2中的数据缓存方法。现在,我们将不讨论请求数量和流量的节省。让我们看看在前端实现方面有没有什么值得研究的地方。根据代码片段2所示的处理方法,存储原始数据。再次调用时,showPage(datalist)需要根据数据重构html结构,并展示给用户。然而,我们之前已经完成了创建结构的过程。第一次创建结构时可以考虑直接保存结构吗?这样可以减少js的重复计算,尤其是结构复杂的时候。再想想,这个结构是之前在页面上创建的,翻页的时候破坏重新创建一个新的结构也是很消耗资源的。第一次翻页的时候能不能不破坏,只通过控制CSS样式来隐藏,反复翻页的时候只控制彼此在这些创建的结构之间显示或者隐藏?

最后,这里讨论的方法可能并不适用于所有场景,但它们可能会有所启发,您可以在适当的时候尝试其中的一两种。与此同时,如果这个想法传播开来,它不仅可以应用于非刷新分页。在这里,我们将一起讨论它。

版权声明:Ajax非刷新分页的性能优化方法是由宝哥软件园云端程序自动收集整理而来。如果本文侵犯了你的权益,请联系本站底部QQ或者邮箱删除。