php压缩返回给前端的json数据

最近在优化一个页面:ajax请求异步数据,特定情况下,json数据达到100MB左右,仅数据传输时间就需要10-20s左右,简直太慢了。

检索资料看怎么压缩json数据

模拟数据:

<?php
ini_set('memory_limit', -1);

function getTestJson()
{
    $file = './files/test.json';
    $data = [];
    for ($i = 0; $i < 3000000; $i++) {
    $data[] = ['name' => '中文a' . $i, 'age' => random_int(10, 99)];
    }
    $json = json_encode($data);
    file_put_contents($file, $json);  
}

getTestJson();

生成的json文件大小120MB左右。

<script>
  fetch("../php-demos/test-gz.php")
    .then((res) => {
      if (res.ok) {
        return res.json();
      } else {
        throw Error("error");
      }
    })
    .then((data) => console.log(data))
    .catch((error) => console.log("error"));
</script>

本地测试

方法1:使用ob_start回调函数ob_gzhandler来对数据进行压缩

Ajax接收到的是json数据

<?php
ini_set('memory_limit', -1);
ini_set('zlib.output_compression_level', 1); //设置压缩级别,默认6
ob_start('ob_gzhandler'); //压缩数据
header('Content-Type: application/json');

$file = './files/test.json';
$json = file_get_contents($file);
echo $json;

本地测试,压缩后数据大小变小很多,时间稍稍变长,但影响不大。

方法2:使用gzcompress()等函数进行压缩

ajax接收到文本数据,需进行转换处理

<?php
ini_set('memory_limit', -1);
header('Content-Type: application/json');

$file = './files/test.json';
$json = file_get_contents($file);
echo $json;
$json = json_encode($data);

// $json = gzdeflate($json, 1);
$json = gzcompress($json, 1);
// $json = gzencode($json, 1);

$json = base64_encode($json);
echo $json; 

获取数据

<script src="./plugins/pako.min.js"></script>
<script>
  fetch("../php-demos/test-gz.php")
    .then((res) => {
      if (res.ok) {
        return res.text();
      } else {
        throw Error("error");
      }
    })
    .then((data) => {
      var strData = base64ToUint8Array(data);
      var data = JSON.parse(pako.inflate(strData, { to: "string" }));
      console.log(data);
    })
    .catch((error) => console.log("error"));

  // base64字符串转为uint8array数组
  function base64ToUint8Array(base64String) {
    let padding = "=".repeat((4 - (base64String.length % 4)) % 4);
    let base64 = (base64String + padding).replace(/\-/g, "+").replace(/_/g, "/");
    let rawData = window.atob(base64);
    let outputArray = new Uint8Array(rawData.length);
    for (var i = 0; i < rawData.length; ++i) {
      outputArray[i] = rawData.charCodeAt(i);
    }
    return outputArray;
  }
</script>

 

放到server上看下效果

由此可见,压缩数据后可大大减小数据传输长度和缩短响应时间。

posted @ 2023-11-21 21:32  carol2014  阅读(210)  评论(0)    收藏  举报