Brotli压缩、Brotli优势、压缩效率、Android接入Brotli、BrotliInterceptor拦截器
Brotli压缩、Brotli优势、压缩效率、Android接入Brotli、BrotliInterceptor拦截器
Brotli压缩
一、Brotli 简介
Brotli 是 Google 推出的一种无损压缩算法,通过变种的LZ77算法、Huffman编码以及等方式进行数据压缩。Brotli压缩数据格式的规范在RFC 7932中定义。与其他压缩算法相比(如zip,gzip等),无论是压缩时间,还是压缩体积上看,它都有着更高的效率。
Brotli mailing list:
https://groups.google.com/forum/#! forum/brotli
- Brotli压缩支持单文件
支持的文件类型: text/xml、text/plain、text/css、text/javascript、application/javascript、application/x-javascript、application/rss+xml、application/json、application/xml、image/tiff、image/svg+xml - 可结合tar, 达到支持文件夹
二、Brotli优势
HTTP的gzip压缩可节省网络流量,提升网络速度,但gzip压缩率还不够高,通过调研,有大量算法压缩率都比gzip高。综合压缩率和实现成本,brotli压缩算法落地成本最低,且业界字节app已有多个域名使用brotli算法。
brotli有11个级别,通过测试发现选用中间级别—7级别比较合适,brotli相对gzip消耗的CPU和内存资源更多,但在可接受范围内。
参考链接:https://juejin.cn/post/7194627379656917047
三、Brotli接入到android
对于 web 和 ios 端,在浏览器和系统层已经开始支持 br 的自动解压了,但 Android 系统不会自动解析 br 数据,需要在应用层自己去实现。
Okhttp 中发现了 BrotliInterceptor 的拦截器,但它是 Brotli 库的 Java 描述,没有真正的 Java 编码器实现。
1. 首先请求头中加入Content-Encoding:br
val request = chain.request().newBuilder()
.header("Accept-Encoding", "br,gzip")
.build()
2. OkHttp请求的时候添加拦截器
- 直接使用square公司的拦截器
implementation("com.squareup.okhttp3:okhttp-brotli:4.1.0")
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(BrotliInterceptor.INSTANCE)
.build();
- 依赖implementation("org.brotli:dec:0.1.2”),自行实现拦截器
implementation("org.brotli:dec:0.1.2") //https://mvnrepository.com/artifact/org.brotli/dec
拦截器
object BrotliInterceptor : Interceptor {
override fun intercept(chain: Interceptor.Chain): Response {
return if (chain.request().header("Accept-Encoding") == null) {
val request = chain.request().newBuilder()
.header("Accept-Encoding", "br,gzip")
.build()
val response = chain.proceed(request)
uncompress(response)
} else {
chain.proceed(chain.request())
}
}
fun uncompress(response: Response): Response {
if (!HttpHeaders.hasBody(response)) {
return response
}
val body = response.body() ?: return response
val encoding = response.header("Content-Encoding") ?: return response
val decompressedSource = when {
encoding.equals("br", ignoreCase = true) ->
BrotliInputStream(body.source().inputStream()).source().buffer()
encoding.equals("gzip", ignoreCase = true) ->
GzipSource(body.source()).buffer()
else -> return response
}
return response.newBuilder()
.removeHeader("Content-Encoding")
.removeHeader("Content-Length")
.body(decompressedSource.asResponseBody(body.contentType(), -1))
.build()
}
}
四、Brotli相关GitHub 仓库添加链接描述
https://github.com/google/brotli
https://github.com/square/okhttp
五、写在最后
此文章为个人开发时记录,有时时间有限,无法深入研究,若看到此文章后有其他见解或解决方式,欢迎留言交流👇👇👇
————————————————
版权声明:转载请附上原文出处链接及本声明。
原文链接:
https://blog.csdn.net/weixin_44158429/article/details/130252308
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)