前言
目前各大 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:
腾讯云:
阿里云:
工作流程
实现方式
首先按照前文的入口确认 cdn 已经打开了自动压缩。
-
设置文件上传时的文件类型(content-type)
在资源上传 cdn 时,需要设置文件类型,使自动压缩生效。以腾讯云的 c# sdk 为例:
PutObjectRequest request = new PutObjectRequest(BucketName, cosKey, fileInfo.FullName);
request.SetRequestHeader("Content-Type", "application/protobuf");
注意这里设置类型为 application/protobuf 并不代表真实的文件类型,只是为了让 cdn 识别。
-
请求文件
在通过 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 | 未知 |
| br0 | 782K | 0 |
| br1 | 759K | 1 |
| br2 | 749K | 2 |
| br3 | 747K | 3 |
| ... | ... | ... |
| br11 | 714K | 11 |
可以看出 aws 使用的 brotli 压缩级别大概是 2 级。
配置文件
笔者没有对配置文件进行实际的上传和下载,只进行了本地压缩测试:
| 大小 | Brotli 压缩级别 | |
|---|---|---|
| 配置源文件 | 1.5M | 无 |
| br0 | 255K | 0 |
| br1 | 213K | 1 |
| br2 | 173K | 2 |
| br3 | 172K | 3 |
分析
-
对 asset bundle 压缩的效果一般
一般而言,unity 项目都开启了 ChunkBasedCompression,这意味着打出的 asset bundle 本身就是一个压缩包。在此基础上进行二次压缩,效果一般。
-
对配置文件压缩的效果比较好
本项目的配置文件为 protobuf 格式,pb 本身仅仅是编码,没有压缩。所以压缩效果较好也是符合预期的。
-
落地与否的考量
就本项目而言,下载 asset bundle 的数据量远大于配置,但 ab 的压缩效果不尽人意。另外,本项目的下载存在着分块和断点续传的逻辑,这意味着如果要接入 br 下载,还需要考虑版本兼容。综上,此方案在本项目实施的性价比不高。
其他项目可根据实际情况而定,例如某些项目下载的资源没有进行预先打包,又或者某些项目的配置量比较大,可以考虑 br 压缩下载。