18、Android性能优化之网络优化:数据压缩(Gzip)、请求合并、缓存策略、DNS优化
网络优化,说白了就是让App在用户手机上和服务器“少说话、说短话、说有用的话”。
我刚开始做Android开发那会儿,总觉得网络请求能通就行。直到有一次,用户反馈App在2G/3G网络下卡得像个PPT,我才意识到——网络优化不是锦上添花,而是雪中送炭。
今天咱们就聊聊网络优化的四个核心方向:数据压缩、请求合并、缓存策略、DNS优化。这四个点,你吃透了,App的网络性能至少能提升一个档次。
1. 数据压缩:让传输的每一字节都值钱
数据压缩,说白了就是让服务器和App之间传的数据“瘦身”。
Gzip压缩是业界最常用的方式。你想想看,一个JSON接口返回几百KB,Gzip一压可能就剩几十KB。我习惯在OkHttp的拦截器里统一开启Gzip,这样所有请求都自动受益。
Content-Encoding: gzip,客户端自动解压。OkHttp默认支持,但记得在请求头里加 Accept-Encoding: gzip。
// OkHttp 全局开启 Gzip(其实默认就支持,但显式设置更保险)
OkHttpClient client = new OkHttpClient.Builder()
.addInterceptor(chain -> {
Request originalRequest = chain.request();
Request compressedRequest = originalRequest.newBuilder()
.header("Accept-Encoding", "gzip")
.build();
return chain.proceed(compressedRequest);
})
.build();
除了Gzip,图片压缩也很关键。我在项目中遇到过,一个列表页加载20张高清图,流量直接爆炸。后来统一用WebP格式,体积平均减少30%以上。Android从4.0就开始支持WebP了,放心用。
2. 请求合并:别让App“频繁眨眼”
你有没有遇到过这种情况?一个页面刚打开,瞬间发起七八个网络请求。每个请求都有TCP握手、TLS协商、数据传输……加起来耗时翻倍。
我建议的做法是:把多个小请求合并成一个批量接口。比如首页需要用户信息、推荐列表、公告,完全可以合并成一个 /home/page 接口,一次性返回所有数据。
如果后端不支持合并,客户端也可以做“请求队列”。我记得在做一个社交App时,点赞、关注、评论这些操作,我让它们先在本地排队,每500ms或攒够5条再统一发送。效果立竿见影,服务器压力小了,用户也觉得更流畅。
3. 缓存策略:让数据“随叫随到”
缓存,是网络优化里性价比最高的手段。没有之一。
我习惯把缓存分为三层:内存缓存、磁盘缓存、离线缓存。
| 缓存层级 | 速度 | 容量 | 典型实现 |
|---|---|---|---|
| 内存缓存 | 纳秒级 | 小(几MB) | LruCache |
| 磁盘缓存 | 毫秒级 | 大(几十MB) | DiskLruCache / OkHttp Cache |
| 离线缓存 | 秒级(需加载) | 视情况而定 | Room / SQLite |
OkHttp自带的缓存机制非常强大。你只需要配置一个Cache目录和大小,它就会自动根据响应头(Cache-Control、ETag、Last-Modified)来决定是否缓存、是否使用缓存。
// OkHttp 磁盘缓存配置
int cacheSize = 10 * 1024 * 1024; // 10 MB
Cache cache = new Cache(cacheDir, cacheSize);
OkHttpClient client = new OkHttpClient.Builder()
.cache(cache)
.build();
这里有个坑:服务端必须正确返回缓存相关的响应头。我曾经遇到一个项目,客户端配了缓存,但服务端每次返回 Cache-Control: no-cache,结果缓存形同虚设。后来我跟后端同学沟通,统一改成 Cache-Control: max-age=3600,问题才解决。
no-cache。
4. DNS优化:别让“查地址”拖慢网速
DNS解析,说白了就是把域名翻译成IP地址。这个过程虽然快,但每次请求都要做一次,而且可能被运营商劫持、解析慢、甚至返回错误IP。
我推荐两个优化手段:DNS预解析和HTTPDNS。
DNS预解析:在App启动时或者空闲时,提前把常用域名解析好,缓存起来。这样真正请求时直接拿IP,省去DNS查询时间。
// 使用 OkHttp 的 Dns 接口做预解析
OkHttpClient client = new OkHttpClient.Builder()
.dns(new Dns() {
@Override
public List<InetAddress> lookup(String hostname) throws UnknownHostException {
// 先从本地缓存查,查不到再走系统DNS
List<InetAddress> cached = cache.get(hostname);
if (cached != null) return cached;
List<InetAddress> result = Dns.SYSTEM.lookup(hostname);
cache.put(hostname, result);
return result;
}
})
.build();
HTTPDNS:直接使用HTTP协议向专门的DNS服务器查询IP,绕过运营商DNS,避免劫持和解析慢的问题。阿里云、腾讯云都有现成的HTTPDNS服务。我曾在海外项目中使用过,效果很明显,解析成功率从95%提升到99.5%以上。
总结一下
网络优化,其实就四个字:少、快、准、省。
- 少:数据压缩,减少传输量
- 快:请求合并,减少请求次数
- 准:缓存策略,减少重复请求
- 省:DNS优化,减少等待时间
这四个方向,你不需要一次性全部做完。先从最容易的Gzip和缓存入手,效果立竿见影。等遇到瓶颈了,再考虑请求合并和HTTPDNS。
嗯,网络优化这块,说到底就是让用户感觉“快”。用户不会关心你用了什么技术,他只关心App是不是秒开、刷视频是不是流畅。咱们做开发的,就是要在背后把这些细节做到位。