基于 unity 对 CDN 自动压缩进行的一次尝试

343 阅读4分钟

前言

目前各大 cdn 厂商都支持 cdn 自动压缩,在符合文件类型的情况下,上传到 cdn 的静态文件会被自动压缩成 gzip 或者 brotli 格式,以减少传输时间和流量消耗。对于静态网站、webgl 的相关资料很多,但对于客户端的资料较少。本文基于 Unity 开发对此进行了一些尝试和探索。

基础知识

Brotli 是什么

Brotli是开源的一种新型压缩算法,Brotli压缩比Gzip压缩性能更好。开启Brotli压缩功能后,cdn 节点会对资源进行智能压缩后返回,缩小传输文件大小,提升文件传输效率,减少带宽消耗。

Brotli 效果怎么样

以本项目为例,brotli 和 gzip 都采用默认压缩级别,本地测试对比如下:

asset bundle 的压缩:

配置文件的压缩:

哪些 cdn 厂商支持自动压缩

仅举例,包括但不限于:

aws(cloudfront):docs.aws.amazon.com/AmazonCloud…

腾讯云:cloud.tencent.com/document/pr…

阿里云:help.aliyun.com/zh/edge-sec…

客户端对 brotli 的支持情况

.NET Standard 2.1 支持 brotli 压缩:learn.microsoft.com/en-us/dotne…

但不同于浏览器自动解压缩,客户端需要主动对压缩的数据进行解压缩:

using Stream responseStream = new BrotliStream(response.GetResponseStream(), CompressionMode.Decompress);

支持哪些文件类型(content-type)

参考各家 cdn 所列出的类型:

aws:docs.aws.amazon.com/AmazonCloud…

腾讯云:cloud.tencent.com/document/pr…

阿里云:help.aliyun.com/zh/edge-sec…

注意:cdn 上的文件类型不仅仅是在上传时根据后缀设置的,还可以手动设置、更改。

另外,各家 cdn 支持的文件大小也不相同:

Aws 和阿里云支持 1KB ~ 10MB,腾讯云支持 256B ~ 30MB。

Cdn 开启自动压缩的入口

aws:

腾讯云:

阿里云:

工作流程

image.png

实现方式

首先按照前文的入口确认 cdn 已经打开了自动压缩。

  1. 设置文件上传时的文件类型(content-type)

在资源上传 cdn 时,需要设置文件类型,使自动压缩生效。以腾讯云的 c# sdk 为例:

PutObjectRequest request = new PutObjectRequest(BucketName, cosKey, fileInfo.FullName);
request.SetRequestHeader("Content-Type", "application/protobuf");

注意这里设置类型为 application/protobuf 并不代表真实的文件类型,只是为了让 cdn 识别。

  1. 请求文件

在通过 http 请求 cdn 文件时,需要附带 br 标头。仍然以 c# 为例:

HttpWebRequest request = WebRequest.Create(url) as HttpWebRequest;
request.Headers.Add("Accept-Encoding", "br");

3. ### 解压缩文件

using Stream responseStream = new BrotliStream(response.GetResponseStream(), CompressionMode.Decompress);

这里建议通过识别返回的标头来判断是否用 brotli 解压缩:

if (response.Headers["Content-Encoding"] == "br")
{
    using Stream responseStream = new BrotliStream(response.GetResponseStream(), CompressionMode.Decompress);
};

实际效果如何

Asset bundle

以一个实际的 ab 包为例:

大小Brotli 压缩级别
Ab 源文件806K
Aws cdn 返回的压缩文件751K未知
br0782K0
br1759K1
br2749K2
br3747K3
.........
br11714K11

可以看出 aws 使用的 brotli 压缩级别大概是 2 级。

配置文件

笔者没有对配置文件进行实际的上传和下载,只进行了本地压缩测试:

大小Brotli 压缩级别
配置源文件1.5M
br0255K0
br1213K1
br2173K2
br3172K3

分析

  1. 对 asset bundle 压缩的效果一般

一般而言,unity 项目都开启了 ChunkBasedCompression,这意味着打出的 asset bundle 本身就是一个压缩包。在此基础上进行二次压缩,效果一般。

  1. 对配置文件压缩的效果比较好

本项目的配置文件为 protobuf 格式,pb 本身仅仅是编码,没有压缩。所以压缩效果较好也是符合预期的。

  1. 落地与否的考量

就本项目而言,下载 asset bundle 的数据量远大于配置,但 ab 的压缩效果不尽人意。另外,本项目的下载存在着分块和断点续传的逻辑,这意味着如果要接入 br 下载,还需要考虑版本兼容。综上,此方案在本项目实施的性价比不高。

其他项目可根据实际情况而定,例如某些项目下载的资源没有进行预先打包,又或者某些项目的配置量比较大,可以考虑 br 压缩下载。