Ajax 与 Gzip 交互

时间:2022-07-22
本文章向大家介绍Ajax 与 Gzip 交互,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

目标

实现后台GZIP压缩,pako.js 前端解压

原因

数据库获取9576条数据耗时:3320ms

利用ajax获取数据大小12.7M,耗时6.27s

这样相当于从获取数据到渲染,耗时10

优化手段

  1. 压缩
  2. 缓存
  3. 服务端做优化。

示例(压缩)

Gzip工具类

package com.jeeplus.modules.ztfx.utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

public class GzipUtils {
    /**
     * 字符串的压缩
     * @param str 待压缩的字符串
     * @return    返回压缩后的字符串
     * @throws IOException
     */
    public static String compress(String str) throws IOException {
        if (null == str || str.length() <= 0) {
            return null;
        }
        // 创建一个新的 byte 数组输出流
        ByteArrayOutputStream out = new ByteArrayOutputStream();
        // 使用默认缓冲区大小创建新的输出流
        GZIPOutputStream gzip = new GZIPOutputStream(out);
        // 将 b.length 个字节写入此输出流
        gzip.write(str.getBytes("UTF-8"));
        gzip.close();
        // 使用指定的 charsetName,通过解码字节将缓冲区内容转换为字符串
        return out.toString("ISO-8859-1");
    }

    /**
     * 字符串的解压
     * @param b 对字符串解压
     * @return    返回解压缩后的字符串
     * @throws IOException
     */
    public static String unCompress(byte[] b) {
        try {
            if (null == b || b.length <= 0) {
                return null;
            }
            // 创建一个新的 byte 数组输出流
            ByteArrayOutputStream out = new ByteArrayOutputStream();
            // 创建一个 ByteArrayInputStream,使用 buf 作为其缓冲区数组
            ByteArrayInputStream in;
            in = new ByteArrayInputStream(b);

            // 使用默认缓冲区大小创建新的输入流
            GZIPInputStream gzip = new GZIPInputStream(in);
            byte[] buffer = new byte[256];
            int n = 0;
            while ((n = gzip.read(buffer)) >= 0) {// 将未压缩数据读入字节数组
                // 将指定 byte 数组中从偏移量 off 开始的 len 个字节写入此 byte数组输出流
                out.write(buffer, 0, n);
            }
            // 使用指定的 charsetName,通过解码字节将缓冲区内容转换为字符串
            return out.toString("UTF-8");

        } catch (Exception e) {
            e.printStackTrace();
        }
        return null;
    }

}

Java 控制层

@RequestMapping(value = "baiduMapAjax")
@ResponseBody
public String baiduMapAjax(ZtWgxx ztWgxx) throws IOException {

	long start = System.currentTimeMillis();

	if(StringUtils.isNotBlank(ztWgxx.getDate())) {
		String[] datas = ztWgxx.getDate().split(" ~ ");
		ztWgxx.setDateStart(datas[0]);
		ztWgxx.setDateEnd(datas[1]);
	}

	List<ZtWgxx> ztWgxxList = ztWgxxService.findListByBaiduNew0506(ztWgxx);

	long end = System.currentTimeMillis() - start;
	logger.error("baiduMapAjax 耗时: {}", end);

	Result result = ResultGenerator.genSuccessResult(ztWgxxList);
	if (ztWgxxList.size()>0){
		result.setMsg("1");
	}else {
		result.setMsg("0");
	}
	
	// 改写后返回的是 String,这里将对象转换成String
	return GzipUtils.compress(JSON.toJSONString(result));
	
	// 原返回的是 Result
	//return result;
}

前端页面

<%--压缩解压缩库--%>
<script type="text/javascript" src="${ctxStatic}/pako/pako.min.js" charset="utf-8"></script>


$.ajax({
    url: "${ctx}/ztfx/ztWgxx/baiduMapAjax?carNo="+carNo+
    "&type="+type+
    "&xw="+xw+
    "&qdView="+qdView,
    async: true,
    method: 'GET',
    // 原来是 json 传输
    // dataType: "json",
    // 改写后是 text 传输
    dataType: "text",
    cache: false,
    success: function (result) {
        // 这里需要将 String 转换成 json,转换后像之前一样正常获取数据
        result=JSON.parse(unzip(result));//解压缩
        // console.log("result-----"+result)
        //把数据分类加入对应的list对象
        var changdu;
        if (result.msg == "1") {
            changdu = result.data.length;
        } else {
            changdu = 0;
        }
    }
})

    
// 解压
function unzip(str) {
    try {
        var restored = pako.ungzip(str, {to: 'string'});
    } catch (err) {
        console.log("异常:" + err);
    }
    return restored;
}

结果

数据库获取9576条数据耗时:3422ms

利用ajax获取数据大小7.68kB,耗时3.99s

这样相当于从获取数据到渲染,耗时7.4