最近在做前端的一些事情。
使用echart绘图。遇到一个问题,就是用ajax 接收后端返回的json数据。测试发现速度很慢,调试发现后端返回的数据有54.7M,ajax接收时间在32-43秒左右,如图:
项目使用spring mvc框架,服务端使用@ResponseBody 自动打包 HttpServletResponse的返回内容,return HashMap,返回类型是application/json
这是在使用Ehcache 后的结果。令笔者想不到的是,返回的数据竟有54.7M大小,由于前端等待时间较长,因此需要做些优化。
首先,有哪些优化手段呢?ajax的格式是这样的:
$.ajax({
type: "POST",
url: '**/getModelData',
data: {jobId:jobId},
dataType:'json',
cache: false,
async: true,
success: function(data){
//
}
});
可以从同步/异步,cache入手。然而,异步通常用于加载dom,并不适用这里,网上一些异步方式讨论的也跟这里无关。笔者把cache 设置为true后,速度并没有提高。按理说,cache在接收第一次同样的数据后,会把数据临时缓存,下一次请求速度会快一些,实际发现,请求仍然是在返回后端的数据。没有看出明显提升。这让笔者有点奇怪。
既然无效,可不可以用一个js全局变量,临时存储后端返回的数据呢?这里每一个请求返回的数据大小都在几十M的规模,多请求几次,页面临时内存会有达到几百M的可能,这样是不是有些笨拙?
总之,并没有使用这样方式。剩下还有几种方式:
(1)压缩
(2)缓存
(3)服务端做优化。
首先是压缩。这是比较好的思路。tomcat,spring mvc,nginx 都提供压缩配置,主流的压缩格式是Gzip,恰好以上三者都提供。这里并没有用到nginx,所以,只考虑spring mvc和tomcat。
spring mvc 使用Gzip 需要一个GZIPResponseWrapper 类来继承HttpServletRespose,另外,fliter层需要GZIPFilter 实现Filter接口,简单说,就是再封装HttpServletResponse.
具体代码如下:
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class GZIPFilter implements Filter {
public void doFilter(ServletRequest req, ServletResponse res, FilterChain chain)
throws IOException, ServletException {
if (req instanceof HttpServletRequest) {
HttpServletRequest request = (HttpServletRequest) req;
HttpServletResponse response = (HttpServletResponse) res;
String ae = request.getHeader("accep