Node v12.7 如何实现本地的brotli、gzip和deflate压缩缓冲区。

5

我是一名前端开发人员,在这里提高自己的后端技能。

我有一个Node express服务器,它在同一台服务器/AWS EC2实例上托管应用程序和提供REST API服务。

我曾经使用过 express-static-gzip npm包为静态应用程序捆绑包和资源启用Brotli压缩。这很不错。但是由于手机无法处理大量数据集解析,我必须切换到SSR以处理Three.js对象。遗憾的是,它没有将压缩应用于我的REST数据。

目前,在过渡期间,我已禁用express-static-gzip并启用了 compression npm包。这只能启用gzip,但适用于静态捆绑包和REST API。

我特别需要Brotli与GZIP/Deflate回退压缩同时适用于我的静态捆绑包和REST API。最大的未压缩GET请求可以达到138MB。 GZIP将其减少到12.8MB。我希望通过Brotli将其减少到10MB以下。

我的意图是使express-static-gzip在我的捆绑包上运行压缩,手动使用node-zlib压缩我的REST API。如果这不可行,则手动使用node-zlib压缩所有内容!

我不理解有关缓冲区和后端类型的事情...也许您可以告诉我我在这里做错了什么:

app.get('/quakeData/:index', function(req, res){
    // Send Specific Selection or All
    const encoding = req.headers['accept-encoding'], 
          index    = req.params.index,
          jsonArr  = index != "all" ? [ quakes[index], threeData[index] ] : [ quakes, threeData ],
          jsonStr  = JSON.stringify(jsonArr),
          bData    = Buffer.from(jsonStr);

    if (encoding.includes('br')) {
        console.log("BROTLI RES");
        zlib.brotliCompress(bData, (err, result) => {
            console.log(result);
            !err ? res.send(result) : console.warn(err);
        });

    } else if (encoding.includes('gzip')) {
        console.log("GZIP RES");
        zlib.gzip(bData, (err, result) => {
            console.log(result);
            !err ? res.send(result) : console.warn(err);
        });

    } else if (encoding.includes('deflate')) {
        console.log("DEFLATE RES");
        zlib.deflate(bData, (err, result) => {
            console.log(result);
            !err ? res.send(result) : console.warn(err);
        })

    } else {
        console.warn("Unsupported Content Encoding Headers");
        res.setHeader('Content-Type', 'application/json');
        res.json(jsonArr);
    }

此外,我已经意识到压缩模块会删除 Content Length 头信息,因为我的 XHR 进度 API 代码停止工作了。无论采用何种解决方案,我都需要 Content Length 头信息。我该如何处理?此外,是否有一种方法可以设置 GET 请求提前接收内容长度以估算下载时间?
谢谢!
1个回答

7
我已经将它弄好了。尽管现在我有一个问题,即如何具有不同压缩选项的可动态选择时间范围。我将不得不修改它,因为压缩数据需要相当长的时间。
显然Brotli要优越得多。我想当我重构并测试我的月度数据时,数据节省将令人印象深刻。以下是我拥有的使上述内容工作的代码。当然,它在每个API请求上进行压缩,在生产中这是没有意义的,但对于测试来说很好。
(更新) 我重新设计了代码,实现了更终的实现,包括写入txt文件等。我没有提供代码,但是下面是使用Brotli和GZIP进行的最终压缩比字节长度比较。虽然GZIP提供更快的压缩,但体积更大。
Brotli: [ 5433, 137501, 952538, 6438971 ]
GZIP: [ 6818, 194843, 1544908, 10451525 ]
上述的字节长度数组分别用于小时、日、周和月份数据集。月份数据集在压缩之前约为138MB。
此外,FYI XHR进度API损坏了,所以即使您发送字节大小的内容标头,它也无法正常工作。我必须创建一个单独的API,在数据的AJAX之前发送字节长度。
const jsonStr  = JSON.stringify(jsonArr),
          bData    = Buffer.from(jsonStr, 'utf-8');

    if (encoding.includes('br')) {
        console.log("BROTLI RES");
        zlib.brotliCompress(bData, (err, result) => {
            console.log(result);
            res.writeHead(200, {
                'Content-Type':     'application/json',
                'Content-Encoding': 'br',
                'Content-Length':   bData.length
            });

            !err ? res.end(result) : console.warn(err);
        });

    } else if (encoding.includes('gzip')) {
        console.log("GZIP RES");
        zlib.gzip(bData, (err, result) => {
            console.log(result);
            res.writeHead(200, {
                'Content-Type':     'application/json',
                'Content-Encoding': 'gzip',
                'Content-Length':   bData.length
            });

            !err ? res.end(result) : console.warn(err);
        });

    } else if (encoding.includes('deflate')) {
        console.log("DEFLATE RES");
        zlib.deflate(bData, (err, result) => {
            console.log(result);
            res.writeHead(200, {
                'Content-Type':     'application/json',
                'Content-Encoding': 'deflate',
                'Content-Length':   bData.length
            });

            !err ? res.end(result) : console.warn(err);
        });

    } else {
        console.warn("Unsupported Content Encoding Headers");
        res.setHeader('Content-Type', 'application/json');
        return res.json(compressed);
    }

1
最终的 'Content-Encoding': 'gzip', 是否应该改为 'Content-Encoding': 'deflate', - Peter W

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接