iOS 下载优化:下载效率提升 4 倍,赶超 WhatsApp

402 阅读1分钟

最原始的下载优化就是直接一个 get 请求,下载缓慢,用户等待时间长,体验不好,故对此进行优化。

直接上结果:文件下载速度提升 4 倍,减少了网络交互次数,下载速度赶超 WhatsApp

1. 原始下载

sequenceDiagram
App->>Server: get(file url)
Server-->>App: success

2. 第一次优化:分片下载,下载速率提升几倍

先判断文件服务商是否支持分片下载以及获取文件长度,然后再决定是走分片下载还是普通下载。走分片下载会创建多线程进行下载,减少用户等待时间。

sequenceDiagram
App->>Server: getFileTotalLength(HEAD 请求)
Server-->>App: totalLength、isSupportResume
alt supportResume=true
    App->>Server: 多线程分片下载
    Server-->>App: Success
    App->>App: 本地通过 NSFileManager 合并
else supportResume=false
    App->>Server: 普通下载get(file url)
    Server-->>App: success
end

3. 再次优化:小文件下载速度赶超 WhatsApp

通过第一次优化后观察了一段时间,发现图片等小文件下载速度还是不如 WhatsApp 的快,启动再次优化。

直接去进行下载,range 传入 5M,如果文件小于 5M 则直接下载完成,如果文件大于 5M 则启动分片下载。

小文件减少了网络交互次数,下载速度赶超 WhatsApp。

sequenceDiagram
App->>Server: predownload(GET请求,HTTPHeaderField 设置 {Range:bytes=0-5242880})
alt statusCode=200
    Server-->>App: success
else statusCode=206
    Server-->>App: 前 5M 下载完成
    App->>Server: 后续文件进行分片下载
    Server-->>App: success
    App->>App: 本地通过 NSFileManager 合并
else statusCode=other 
    Server-->>App: 下载失败或者其他错误码
    App->>Server: 重试逻辑
end

4. 一些注意事项

  1. 云厂商为 STC 时,需要指定 Accept-Encoding 为 identity,否则会导致获取不到 length
  2. didFinishDownloadingToURL 这个回调中的临时路径会很快被覆盖,需要第一时间取出来保存
  3. 再次优化中的“前 5M 是否下载完成的判断”需要根据云厂商完善判断条件