ajax 处理页面大量数据

时间:2024-04-08 18:58:15

背景:一个页面需要输出list中所有数据 (list大小>1000,客户要求不分页),生成的页面时间会很长,浏览器会出现短暂的空白。

 

700条XX信息数据大小965.9KB,耗时1.66s

1000条XX数据大小1803.6KB,耗时2.68s

100条数据 大小  194.8KB 耗时 140ms

 

 

 

优化思路:将数据分成多块,分多次响应给客户端。 如:优化700条数据,第一次输出100条数据(这样用户就很快看到有页面出来),剩余的600条数据,通过ajax分6次请求,每次也是100条数据,给客户端。(这里相当于:用户的一个请求结果,被切割成7请求来完成)

 

这里有关键的几个点:

  第一: 7次的请求怎么保证他们操作的都说同一个list。(缓存第一次从数据库查出来的list,缓存的key要唯一性,可以采用时间戳来做key)

  第二: 判断是否是最后一次请求,是。。就要清空这次的缓存

  第三: 后台返回的不是一个list,而是一个已经在jsp中生成好的html,ajax直接把后台生成html,inner进当前页面。

       

  流程:  ajax 处理页面大量数据

 

  解释:

        1.用户第一次请求

        2.方法1>>去数据库取数据,判断返回list的大小。若大于100,取list中的 0-99放到listB中,返回。同时把list缓存起来,以时间戳做key,同时把key也返回。

        3,4.去jsp1>> jsp1中有<div id="data"> <table>表头</table> <jsp:include page="jsp2.jsp"></jsp:include> </div> 。

        5.jsp1最后还会调用一段js,把list大小和key传进去,

        6.js 根据list大小算出还要发送多少个请求

       

 /**
	  * 分页请求方法
	  * @param {} count 结果集大小
	  * @param {}  key  
	  */
	 page:function(count,key){
		var divId="data";
	 	var pageCount = count/fundQuery.limit;//默认100
	 	if(pageCount == 0){//结果小于 每页显示数
	 		return;
	 	}
	 	for(var i=1;i<=pageCount;i++){//循环创建div
	 		var _span = document.createElement("div");
			_span.id = divId + i;
			var newText = document.createTextNode(" ");
			_span.appendChild(newText); 
		  	TFL.dom.selector(divId).append(_span);	
	 	}
	 	for(var i=1;i<=pageCount;i++){//循环发送请求
	 		var last=false;
	 		if(i==pageCount){
	 			last=true;
	 		}
	 		var pageurl ="funds/fundsquery.jhtm";
	 		var vars ="service=page&start="+i+"&limit="+fundQuery.limit+"&last="+last+"&key="+key;
	 		var requestObject = 
		 	{
		 		url: pageurl,
		 		getType: "1",
		 		vars: vars, 
		 		method: "post",
		 		
		 		callBack: function(html){
		 			var start = parseInt(ajaxGetPage.gup('start',this.vars));//获取 vars 中的参数
		 			TFL.dom.selector("data"+start).html(html); //将后台返回的html inner进指定的div
		 		}
			};
			var ajax = new TFL.ajax2();
			ajax.ajaxRequest(requestObject);//ajax封装
	 	}
	 	
	 }

 

 

 

 

 

  7.ajax调用controller的方法:

     

	public OutputVO page(FundNavInput in,Boolean last,Long key){
		OutputVO out = new OutputVO();
		List<FundNavInfoVO> result = (List<FundNavInfoVO>)map.get(key);
		List<FundNavInfoVO> res = null;
		if(result != null){
			int startIndex = in.getStart() * in.getLimit(); //开始的索引 = 页码*大小
			int toIndex = startIndex + in.getLimit() >result.size()?result.size():startIndex+in.getLimit();//结束索引=开始索引+每页条数
			
			res = result.subList(startIndex, toIndex);
			out.setList(res);
			out.setCount(res.size());
			if(last){//最后一次 移除这次的结果
				map.remove(key);
			}	
		}
		ViewUtil.setViewName("jsp2");
		return out;
		
	}

 

 

 8.jsp2中  <table cellpadding="0" cellspacing="0" class="list" style="border-bottom: #d3d2d3 0px solid;">
              <c:forEach var="dataRow" items="${outputVO.list}" varStatus="stat"> <tr>.....<tr> </c:forEach>

 

 

            </table>

 9.返回一段已经画好的表格。js ajax回调函数中把这段html inner 进指定的div

 

总结:

     这种解决方案其实相当于  隐式的分页。。。。  个人挺满意这种方案。! 欢迎大伙拍砖!