前言
互聯網時代, App作為于用戶交互的端, 可以說實際上是一個界面, 產品的業務, 服務都是由Server提供的. 而App與Server的交互依賴于網絡, 故而網絡優化, 也是我們的App優化中不可缺少的一個優化項
1、網絡連接對用戶的影響
App的網絡連接對于用戶來說, 影響很多, 且多數情況下都很直觀, 直接影響用戶對這個App的使用體驗. 其中較為重要的幾點:
- 流量 App的流量消耗對用戶來說是比較敏感的, 畢竟流量是花錢的嘛. 現在大部分人的手機上都有安裝流量監控的工具App, 用來監控App的流量使用. 如果我們的App這方面沒有控制好, 會給用戶不好的使用體驗.
- 電量 電量相對于用戶來說, 沒有那么明顯. 一般用戶可能不會太注意. 但是如前文電量優化中說的那樣, 網絡連接(radio)是對電量影響很大的一個因素. 所以我們也要加以注意.
- 用戶等待 也就是用戶體驗, 良好的用戶體驗, 才是我們留住用戶的第一步. 如果App請求等待時間長, 會給用戶網絡卡, 應用反應慢的感覺, 如果有對比, 有替代品, 我們的App很可能就會被用戶無情拋棄.
2、分析網絡連接的工具
2.1.NETwork Monitor
Android Studio內置的Monitor工具中就有一個Network Monitor:

其中:
- Rx — R(ecive) 表示下行流量, 即下載接收.
- Tx — T(ransmit) 表示上行流量, 即上傳發送.
2.2 網絡代理工具
一般來說, 網絡代理工具有兩個作用:
- 截獲網絡請求響應包, 分析網絡請求
- 設置代理網絡, 移動App開發中一般用來做不同網絡環境的測試, 例如wifi/4G/3G/弱網等.
代理工具很多, 諸如Wireshark, Fiddler, Charles等, 在此不一一細說了
3, 哪些方面取優化網絡連接
簡單來說, 兩個方面:
減少Radio活躍時間
1. 也就是減少網絡數據獲取的頻次.
2. 這就減少了radio的電量消耗, 控制電量使用.
減少獲取數據包的大小
1. 可以減少流量消耗
2. 也可以讓每次請求更快, 在網絡情況不好的情況下也有良好表現, 提升用戶體驗.
那么, 具體應該從哪些方面著手呢?
3.1 接口設計
API設計
App與Server之間的API設計要考慮網絡請求的頻次, 資源的狀態等. 以便App可以以較少的請求來完成業務需求和界面的展示.
例如, 注冊登錄. 正常會有兩個API, 注冊和登錄, 但是設計API時我們應該給注冊接口包含一個隱式的登錄. 來避免App在注冊后還得請求一次登錄接口(有可能失敗, 從而導致業務流程失敗).
再例如, 上文提到的獲取repo詳情, 實際上請求了4個接口, 請求了repo的信息, forks列表, contributors列表, readme, 這是因為github提供的接口是盡量單一職責的. 然而在我們的實際開發中, 我們的Server除了提供這些單一職責的小接口外, 最好還能組合一個滿足客戶端業務需求的repo詳情接口出來.
Gzip壓縮
使用Gzip來壓縮request和response, 減少傳輸數據量, 從而減少流量消耗.
考慮使用Protocol Buffer代替JSON
從前我們傳輸數據使用XML, 后來使用JSON代替了XML, 很大程度上也是為了可讀性和減少數據量(當然還有映射成POJO的方便程度).
Protocol Buffer是google推出的一種數據交換格式.
如果我們的接口每次傳輸的數據量很大的話, 可以考慮下protobuf, 會比JSON數據量小很多.
當然相比來說, JSON也有其優勢, 可讀性更高.
圖片的Size
上面Network Monitor中看到的22s到27s之間的有多次請求, 且數據量還很大. 就是在獲取圖片資源.
圖片相對于接口請求來說, 數據量要大得多. 故而也是我們需要優化的一個點.
我們可以在獲取圖片時告知服務器需要的圖片的寬高, 以便服務器給出合適的圖片, 避免浪費.
我們現在很多公司的圖片資源都是使用第三方的云存儲服務的(七牛, 阿里云存儲之類的).
以七牛為例, 可以在請求圖片的url中添加諸如質量, 格式, width, height等path來獲取合適的圖片資源:
<pre spellcheck="false" class="md-fences md-end-block ty-contain-cm modeLoaded" lang="JAVA" cid="n57" mdtype="fences" style="box-sizing: border-box; overflow: visible; font-family: var(--monospace); font-size: 0.9em; display: block; break-inside: avoid; text-align: left; white-space: normal; background-image: inherit; background-position: inherit; background-size: inherit; background-repeat: inherit; background-attachment: inherit; background-origin: inherit; background-clip: inherit; background-color: rgb(248, 248, 248); position: relative !important; border: 1px solid rgb(231, 234, 237); border-radius: 3px; padding: 8px 4px 6px; margin-bottom: 15px; margin-top: 15px; width: inherit; color: rgb(51, 51, 51); font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">imageView2/<mode>/w/<LongEdge>
/h/<ShortEdge>
/format/<Format>
/interlace/<Interlace>
/q/<Quality>
/ignore-error/<ignoreError>
</pre>
3.2 網絡緩存
適當的緩存, 既可以讓我們的應用看起來更快, 也能避免一些不必要的流量消耗.
3.3 打包網絡請求
當接口設計不能滿足我們的業務需求時. 例如可能一個界面需要請求多個接口, 或是網絡良好, 處于Wifi狀態下時我們想獲取更多的數據等.
這時就可以打包一些網絡請求, 例如請求列表的同時, 獲取Header點擊率較高的的item項的詳情數據.
可以通過一些統計數據來幫助我們定位用戶接下來的操作是高概率的, 提前獲取這部分的數據.
3.4 監聽相關狀態
通過監聽設備的狀態:
- 休眠狀態
- 充電狀態
- 網絡狀態
結合JobScheduler來根據實際情況做網絡請求. 比方說Splash閃屏廣告圖片, 我們可以在連接到Wifi時下載緩存到本地; 新聞類的App可以在充電, Wifi狀態下做離線緩存.
3.5 弱網測試&優化
除了正常的網絡優化, 我們還需考慮到弱網情況下, App的表現.
3.5.1 弱網測試
有幾種方式來模擬弱網進行測試.
Android Emulator
創建和啟動Android模擬器可以設置網絡速度和延遲:
創建時:

啟動時, 使用emulator命令:
使用網絡代理工具
以Charles為例:
保持手機和PC處于同一個局域網, 在手機端wifi設置高級設置中設置代理方式為手動, 代理ip填寫PC端ip地址, 端口號默認8888.

其他模擬弱網方式
如果你恰好也是IOS的開發者, Apple提供了Network Link Conditioner, 非常好用.
可以模擬的網絡情況與上述類似:

如果你使用linux環境開發, 還可以試下facebook出的ATC.
3.5.2 弱網優化
利用上述工具模擬弱網, 在弱網情況下體驗我們的App. 一般來說, 網絡延遲在60ms內, 是OK的, 超過200ms就比較糟糕了. 我們需要做的是在比較糟糕的網絡環境下還能給用戶較好的體驗.
弱網優化, 本質上是在弱網的情況下能讓用戶流暢的使用我們的App. 我們要做的就是結合上述的優化項:
- 壓縮/減少數據傳輸量
- 利用緩存減少網絡傳輸
- 針對弱網(移動網絡), 不自動加載圖片
- 界面先反饋, 請求延遲提交
例如, 用戶點贊操作, 可以直接給出界面的點贊成功的反饋, 使用JobScheduler在網絡情況較好的時候打包請求