九掂僵、Android性能優(yōu)化之網(wǎng)絡(luò)優(yōu)化

前言

互聯(lián)網(wǎng)時代, App作為于用戶交互的端, 可以說實際上是一個界面, 產(chǎn)品的業(yè)務(wù), 服務(wù)都是由Server提供的. 而App與Server的交互依賴于網(wǎng)絡(luò), 故而網(wǎng)絡(luò)優(yōu)化, 也是我們的App優(yōu)化中不可缺少的一個優(yōu)化項.
典型的HTTP請求流程說明:

典型HTTP請求流程

1、網(wǎng)絡(luò)連接對用戶的影響

App的網(wǎng)絡(luò)連接對于用戶來說, 影響很多, 且多數(shù)情況下都很直觀, 直接影響用戶對這個App的使用體驗. 其中較為重要的幾點:
流量App的流量消耗對用戶來說是比較敏感的, 畢竟流量是花錢的嘛. 現(xiàn)在大部分人的手機(jī)上都有安裝流量監(jiān)控的工具App, 用來監(jiān)控App的流量使用. 如果我們的App這方面沒有控制好, 會給用戶不好的使用體驗.

電量電量相對于用戶來說, 沒有那么明顯. 一般用戶可能不會太注意. 但是如前文電量優(yōu)化中說的那樣, 網(wǎng)絡(luò)連接(radio)是對電量影響很大的一個因素. 所以我們也要加以注意.

用戶等待也就是用戶體驗, 良好的用戶體驗, 才是我們留住用戶的第一步. 如果App請求等待時間長, 會給用戶網(wǎng)絡(luò)卡, 應(yīng)用反應(yīng)慢的感覺, 如果有對比, 有替代品, 我們的App很可能就會被用戶無情拋棄.

2瓢姻、分析網(wǎng)絡(luò)連接的工具

2.1 Network Monitor
Android Studio內(nèi)置的Monitor工具中就有一個Network Monitor:

Network Monitor

其中:
Rx --- R(ecive) 表示下行流量, 即下載接收.
Tx --- T(ransmit) 表示上行流量, 即上傳發(fā)送.

怎么使用Network Monitor?
Network monitor實時跟蹤選定應(yīng)用的數(shù)據(jù)請求情況. 我們可以連上手機(jī), 選定調(diào)試應(yīng)用進(jìn)程, 然后在App上操作我們需要分析的頁面請求.
例如, 上圖就是以CoderPub為例, 針對從repo列表界面進(jìn)入repo詳情界面的監(jiān)控數(shù)據(jù).
可以看到從10s到30s之間, 20s時間內(nèi)發(fā)生了多次數(shù)據(jù)請求, 且22s到27s之間的請求數(shù)據(jù)量還很大.
分析代碼可以看到, 在請求repo詳情的時候是打包了很多請求的:

@Override
public Observable<RepoDetail> getRepoDetail(String owner, String name) {
    return Observable.zip(mRepoService.get(owner, name),
            mRepoService.contributors(owner, name),
            mRepoService.listForks(owner, name, "newest"),
            mRepoService.readme(owner, name),
            isStarred(owner, name),
            new Func5<Repo, ArrayList<User>, ArrayList<Repo>, Content, Boolean, RepoDetail>() {
                @Override
                public RepoDetail call(Repo repo, ArrayList<User> users, ArrayList<Repo> forks, Content readme, Boolean isStarred) {
                    RepoDetail detail = new RepoDetail();

                    repo.setStarred(isStarred);
                    detail.setBaseRepo(repo);
                    detail.setForks(forks);

                    // because the readme content is encode with Base64 by github.
                    readme.content = StringUtil.base64Decode(readme.content);
                    detail.setReadme(readme);

                    detail.setContributors(users);
                    return detail;
                }
            });
}

這也驗證了14s到20s間的四次數(shù)據(jù)請求, 另外由于repo詳情界面會顯示作者以及貢獻(xiàn)者的圖片, 而圖片的數(shù)據(jù)量相對大, 故而23s到27s間有多次數(shù)據(jù)量很大的請求發(fā)生.
這個實際是有很多優(yōu)化空間的, 我們稍后再說.

2.2 Wireshark, Fiddler, Charlesr等抓包工具

使用Charles境蔼、Fiddler等抓包工具同樣可以實現(xiàn)Network Monitor的功能津畸,而且更加強(qiáng)大降淮。

Charles使用

2.3Stetho

Stetho是Facebook出品的一個Android應(yīng)用的調(diào)試工具超埋。無需Root即可通過Chrome,在Chrome Developer Tools中可視化查看應(yīng)用布局佳鳖,網(wǎng)絡(luò)請求,sqlite媒惕,preference等系吩。同樣集成了Stetho之后也可以很方便的查看網(wǎng)絡(luò)請求的各種情況。

Paste_Image.png

3妒蔚、網(wǎng)絡(luò)優(yōu)化

重點來了穿挨,網(wǎng)絡(luò)優(yōu)化主要從三個方面進(jìn)行:1. 速度;2. 成功率肴盏;3. 流量科盛。

3.1 接口設(shè)計

API設(shè)計
App與Server之間的API設(shè)計要考慮網(wǎng)絡(luò)請求的頻次, 資源的狀態(tài)等. 以便App可以以較少的請求來完成業(yè)務(wù)需求和界面的展示.
例如, 注冊登錄. 正常會有兩個API, 注冊和登錄, 但是設(shè)計API時我們應(yīng)該給注冊接口包含一個隱式的登錄. 來避免App在注冊后還得請求一次登錄接口(有可能失敗, 從而導(dǎo)致業(yè)務(wù)流程失敗).
再例如, 上文提到的獲取repo詳情, 實際上請求了4個接口, 請求了repo的信息, forks列表, contributors列表, readme, 這是因為github提供的接口是盡量單一職責(zé)的. 然而在我們的實際開發(fā)中, 我們的Server除了提供這些單一職責(zé)的小接口外, 最好還能組合一個滿足客戶端業(yè)務(wù)需求的repo詳情接口出來.
Gzip壓縮
使用Gzip來壓縮request和response, 減少傳輸數(shù)據(jù)量, 從而減少流量消耗.
考慮使用Protocol Buffer代替JSON
從前我們傳輸數(shù)據(jù)使用XML, 后來使用JSON代替了XML, 很大程度上也是為了可讀性和減少數(shù)據(jù)量(當(dāng)然還有映射成POJO的方便程度).

下圖是對比Json數(shù)據(jù)使用 Gzip 壓縮前后對比圖
返回內(nèi)容開啟 Gzip壓縮前

Paste_Image.png

開啟Gzip壓縮后

Paste_Image.png

對比發(fā)現(xiàn),開啟Gzip后可以減少57.3%的數(shù)據(jù)傳輸量

Paste_Image.png

Protocol Buffer是Google推出的一種數(shù)據(jù)交換格式.
如果我們的接口每次傳輸?shù)臄?shù)據(jù)量很大的話, 可以考慮下protobuf, 會比JSON數(shù)據(jù)量小很多.
當(dāng)然相比來說, JSON也有其優(yōu)勢, 可讀性更高.
本文以網(wǎng)絡(luò)流量優(yōu)化的角度推薦protobuf作為一個選擇, 具體還需更具實際情況考慮.

圖片的Size
上面Network Monitor中看到的22s到27s之間的有多次請求, 且數(shù)據(jù)量還很大. 就是在獲取圖片資源.
圖片相對于接口請求來說, 數(shù)據(jù)量要大得多. 故而也是我們需要優(yōu)化的一個點.
我們可以在獲取圖片時告知服務(wù)器需要的圖片的寬高, 以便服務(wù)器給出合適的圖片, 避免浪費.
我們現(xiàn)在很多公司的圖片資源都是使用第三方的云存儲服務(wù)的(七牛, 阿里云存儲之類的).
以七牛為例, 可以在請求圖片的url中添加諸如質(zhì)量, 格式, width, height等path來獲取合適的圖片資源:

imageView2/<mode>/w/<LongEdge>
                 /h/<ShortEdge>
                 /format/<Format>
                 /interlace/<Interlace>
                 /q/<Quality>
                 /ignore-error/<ignoreError>

參考七牛官方文檔.

3.2 圖片處理
3.2.1 圖片下載
使用縮略圖

App中需要加載的圖片按需加載菜皂,列表中的圖片根據(jù)需要的尺寸加載合適的縮略圖即可贞绵,只有用戶查看大圖的時候才去加載原圖。不僅節(jié)省流量恍飘,同時也能節(jié)省內(nèi)存榨崩!之前使用某公司的圖片存儲服務(wù)在原圖鏈接之后拼接寬高參數(shù),根據(jù)參數(shù)的不同返回相應(yīng)的圖片章母。

有許多方式來使得圖片更加容易下載母蛛,比如使用 WebP圖片,動態(tài)地調(diào)整大小的圖片乳怎,以及使用圖片加載框架彩郊。

使用WebP圖片

通過網(wǎng)絡(luò)提供WebP文件來減少圖片加載的時間和節(jié)省網(wǎng)絡(luò)帶寬,WebP文件通常會比它的PNG或者JPG文件小蚪缀,但會擁有同樣的圖片質(zhì)量秫逝。甚至是使用有損的設(shè)置,WebP也可以輸出一個和原圖幾乎完全一樣的圖片椿胯。安卓系統(tǒng)從Android4.0(API 14)添加了有損耗的WebP support并且在Android4.2(API 17)對無損的筷登,清晰的WebP提供了支持。
使用WebP格式哩盲;同樣的照片前方,采用WebP格式可大幅節(jié)省流量狈醉,相對于JPG格式的圖片,流量能節(jié)省將近 25% 到 35 %惠险;相對于 PNG 格式的圖片苗傅,流量可以節(jié)省將近80%。最重要的是使用WebP之后圖片質(zhì)量也沒有改變班巩。

動態(tài)修改圖片

應(yīng)用要求按指定的渲染大小來從網(wǎng)絡(luò)上請求圖片渣慕,這個渲染大小和設(shè)備規(guī)格有關(guān),并且服務(wù)器提供的是合適大小的圖片抱慌。這樣能夠最小化網(wǎng)絡(luò)上的數(shù)據(jù)傳輸逊桦,減少持有圖片對內(nèi)存的大量損耗,直接影響到性能的提高和用戶滿意度抑进。

當(dāng)用戶不得不等待圖片下載的時候用戶體驗就會有所下降强经,使用合適的圖片尺寸有助于解決這些問題,可以考慮讓圖片的請求都基于網(wǎng)絡(luò)的類型或者網(wǎng)絡(luò)連接的質(zhì)量寺渗,這個尺寸可能會比目標(biāo)值小匿情。

使用圖片加載框架

你的APP不應(yīng)該重復(fù)獲取圖片,圖片加載框架比如Glide或者Picasso獲取圖片信殊,然后緩存炬称,然后hook到你的View來顯示占位符圖片,直到真正的圖片準(zhǔn)備好了顯示真正的圖片涡拘。因為圖片被緩存下來了玲躯,當(dāng)圖片下次被請求的時候,這些圖片加載框架會直接從本地緩存中獲取鲸伴。

圖片加載框架會管理他們的緩存大小府蔗,保留最近使用過的圖片,這樣你的APP的大小不會無限制地增長汞窗。

3.2.2 圖片上傳

圖片(文件)的上傳失敗率比較高姓赤,不僅僅因為大文件,同時帶寬仲吏、時延不铆、穩(wěn)定性等因素在此場景下的影響也更加明顯;

避免整文件傳輸裹唆,采用分片傳輸誓斥;
根據(jù)網(wǎng)絡(luò)類型以及傳輸過程中的變化動態(tài)的修改分片大小许帐;
每個分片失敗重傳的機(jī)會劳坑。
備注:圖片上傳是一項看似簡單、共性很多但實際上復(fù)雜成畦、需要細(xì)分的工作距芬。移動互聯(lián)網(wǎng)的場景和有線的場景是有很多區(qū)別的涝开,例如移動網(wǎng)絡(luò)的質(zhì)量/帶寬經(jīng)常會發(fā)生“跳變”,但有線網(wǎng)絡(luò)卻是“漸變”框仔。

3.3 網(wǎng)絡(luò)緩存

適當(dāng)?shù)木彺? 既可以讓我們的應(yīng)用看起來更快, 也能避免一些不必要的流量消耗.
關(guān)于Android App的網(wǎng)絡(luò)緩存, 請參考MVP架構(gòu)實現(xiàn)的Github客戶端(4-加入網(wǎng)絡(luò)緩存)一文.

3.4 打包網(wǎng)絡(luò)請求

當(dāng)接口設(shè)計不能滿足我們的業(yè)務(wù)需求時. 例如可能一個界面需要請求多個接口, 或是網(wǎng)絡(luò)良好, 處于Wifi狀態(tài)下時我們想獲取更多的數(shù)據(jù)等.
這時就可以打包一些網(wǎng)絡(luò)請求, 例如請求列表的同時, 獲取Header點擊率較高的的item項的詳情數(shù)據(jù).
可以通過一些統(tǒng)計數(shù)據(jù)來幫助我們定位用戶接下來的操作是高概率的, 提前獲取這部分的數(shù)據(jù).

3.5 監(jiān)聽相關(guān)狀態(tài)

通過監(jiān)聽設(shè)備的狀態(tài):
休眠狀態(tài)
充電狀態(tài)
網(wǎng)絡(luò)狀態(tài)

在狀態(tài)弱網(wǎng)下優(yōu)化:

壓縮/減少數(shù)據(jù)傳輸量
利用緩存減少網(wǎng)絡(luò)傳輸
針對弱網(wǎng)(移動網(wǎng)絡(luò)), 不自動加載圖片
界面先反饋, 請求延遲提交例如, 用戶點贊操作, 可以直接給出界面的點贊成功的反饋, 使用JobScheduler在網(wǎng)絡(luò)情況較好的時候打包請求.

結(jié)合JobScheduler來根據(jù)實際情況做網(wǎng)絡(luò)請求. 比方說Splash閃屏廣告圖片, 我們可以在連接到Wifi時下載緩存到本地; 新聞類的App可以在充電, Wifi狀態(tài)下做離線緩存.

3.6 調(diào)整數(shù)據(jù)傳輸

有幾種方式讓你的APP適應(yīng)網(wǎng)絡(luò)條件舀武,提供一個較好的用戶體驗的,比如离斩,對請求劃分優(yōu)先等級來最小化用戶等待信息的時間银舱。也可以檢測并適應(yīng)較慢網(wǎng)絡(luò)速度和發(fā)生網(wǎng)絡(luò)連接的時候的發(fā)生的改變。

優(yōu)先考慮帶寬
不應(yīng)該假設(shè)設(shè)備連接的網(wǎng)絡(luò)是一個長時間持續(xù)并且穩(wěn)定可靠的網(wǎng)絡(luò)跛梗,app應(yīng)該對網(wǎng)絡(luò)請求劃分優(yōu)先級盡可能快地展示最有用的信息給用戶寻馏。

立刻呈現(xiàn)給用戶一些實質(zhì)的信息是一個比較好的用戶體驗,相對于讓用戶等待那些不那么必要的信息來說核偿。這可以減少用戶不得不等待的時間操软,增加APP在慢速網(wǎng)絡(luò)時的實用性。

為了達(dá)到這個目的宪祥,對網(wǎng)絡(luò)請求進(jìn)行排序比如文本的獲取應(yīng)該在富媒體之前,文本請求一般都比較小家乘,壓縮更好蝗羊,并且傳輸速度快,這意味著你的APP可以快速地先顯示內(nèi)容仁锯。

在慢速網(wǎng)絡(luò)的時候使用更少的帶寬
你的APP傳輸數(shù)據(jù)的能力是否及時取決于網(wǎng)絡(luò)連接耀找,檢測這些網(wǎng)絡(luò)的質(zhì)量并且調(diào)整你的APP使用網(wǎng)絡(luò)的行為可以提供一個更好的用戶體驗。

使用下列的方法來檢測外部不容易觀察的網(wǎng)絡(luò)質(zhì)量业崖,使用從這些方法返回的數(shù)據(jù)野芒,你的APP應(yīng)該調(diào)整對網(wǎng)絡(luò)的使用來為用戶的操作提供一個及時的響應(yīng)

ConnectivityManager> isActiveNetworkMetered()
ConnectivityManager> getActiveNetworkInfo()
ConnectivityManager> getNetworkCapabilities(Network)
TelephonyManager> getNetworkType()
在一個慢速的網(wǎng)絡(luò)連接中,考慮只下載低分辨率的媒體或者直接不下載双炕。確保你的用戶可以在慢速網(wǎng)絡(luò)中繼續(xù)使用你的APP狞悲,對于沒有圖片或者圖片仍然在加載的情況,應(yīng)該先顯示一個占位符妇斤,使用 Palette library創(chuàng)建一個動態(tài)的占位符摇锋,生成一個符合目標(biāo)圖片顏色的占位符

在Android 7.0或更高版本的設(shè)備上,用戶可以打開Data Saver設(shè)置站超,可以幫助最小化數(shù)據(jù)的使用荸恕,Android 7.0擴(kuò)展ConnectivityManager來檢測Data Saver設(shè)置。

檢測網(wǎng)絡(luò)改變死相,然后修改APP的行為
網(wǎng)絡(luò)質(zhì)量不是固定不變的融求,它會隨著地理位置,網(wǎng)絡(luò)流量和當(dāng)?shù)厝丝诿芏劝l(fā)生改變算撮。APP 應(yīng)該檢測網(wǎng)絡(luò)中的改變并且相應(yīng)地調(diào)整帶寬生宛,讓APP可以更好地適應(yīng)網(wǎng)絡(luò)質(zhì)量县昂,可以實現(xiàn)下面的這些方法檢測網(wǎng)絡(luò)狀態(tài):

ConnectivityManager> getActiveNetworkInfo()
ConnectivityManager> getNetworkCapabilities(Network)
TelephonyManager> getDataState()

隨著網(wǎng)絡(luò)質(zhì)量的下降,減少請求的數(shù)量茅糜,隨著網(wǎng)絡(luò)質(zhì)量的提升七芭,你可以提高你的請求量到最優(yōu)級別。
在更高的網(wǎng)絡(luò)質(zhì)量下蔑赘,不計費使用流量的網(wǎng)絡(luò)狸驳,可以考慮預(yù)取數(shù)據(jù)讓數(shù)據(jù)提前可用。從用戶體驗的立場缩赛,這可能意味著一個新聞閱讀應(yīng)用在2G網(wǎng)絡(luò)下一次只能獲取3篇文章耙箍,而在WIFI狀態(tài)下一次可以獲取20篇文章。

當(dāng)網(wǎng)絡(luò)連接狀態(tài)發(fā)生改變時會發(fā)出CONNECTIVITY_CHANGE廣播酥馍,APP在前臺運行的情況下辩昆,可以通過注冊廣播接收器來接受這個廣播,在接收廣播以后旨袒,你應(yīng)該再評估當(dāng)前的網(wǎng)絡(luò)狀態(tài)并且調(diào)整你的UI汁针,處理網(wǎng)絡(luò)請求,不能夠在manifest文件中聲明這個廣播Action砚尽,因為在Android7.0版本之后這個Action就被刪除了施无。

3.6 IP直連與HttpDns;

DNS解析的失敗率占聯(lián)網(wǎng)失敗中很大一種必孤,而且首次域名解析一般需要幾百毫秒猾骡。針對此,我們可以不用域名敷搪,才用IP直連省去 DNS 解析過程兴想,節(jié)省這部分時間。

另外熟悉阿里云的小伙伴肯定知道HttpDns:HttpDNS基于Http協(xié)議的域名解析赡勘,替代了基于DNS協(xié)議向運營商Local DNS發(fā)起解析請求的傳統(tǒng)方式嫂便,可以避免Local DNS造成的域名劫持和跨網(wǎng)訪問問題,解決域名解析異常帶來的困擾狮含。

3.7請求打包

合并網(wǎng)絡(luò)請求顽悼,減少請求次數(shù)。對于一些接口類如統(tǒng)計几迄,無需實時上報蔚龙,將統(tǒng)計信息保存在本地,然后根據(jù)策略統(tǒng)一上傳映胁。這樣頭信息僅需上傳一次木羹,減少了流量也節(jié)省了資源。

3.8請求頻率優(yōu)化

可以通過提供一個最佳的網(wǎng)絡(luò)體驗來增強(qiáng)用戶體驗,比如坑填,你可以讓你的APP在離線狀態(tài)下依然可以使用抛人,使用GcmNetworkManager和ContentProvider,刪除重復(fù)的網(wǎng)絡(luò)請求脐瑰。

讓你的APP在離線狀態(tài)下依然可用
在一些比較偏僻的地方妖枚,通常網(wǎng)絡(luò)信號都不會很好,APP失去網(wǎng)絡(luò)連接是很常見的事情苍在。創(chuàng)建一個能夠在離線狀態(tài)依然正常使用的APP意味著用戶可以在任何時候和你的APP進(jìn)行互動绝页。可以通過把網(wǎng)絡(luò)數(shù)據(jù)保存在本地來實現(xiàn)這個需求寂恬,緩存數(shù)據(jù)续誉,并且把發(fā)出的請求添加到隊列中,當(dāng)網(wǎng)絡(luò)恢復(fù)的時候再及時發(fā)出初肉。
在可能的情況下酷鸦,app不應(yīng)該通知用戶網(wǎng)絡(luò)已經(jīng)失去連接了,只有當(dāng)用戶進(jìn)行操作牙咏,并且這個操作一定需要網(wǎng)絡(luò)連接的支持臼隔,才通知用戶當(dāng)前處于沒有網(wǎng)絡(luò)的狀態(tài)。

當(dāng)一個設(shè)備處于沒有網(wǎng)絡(luò)連接狀態(tài)時妄壶,應(yīng)用應(yīng)該允許用戶發(fā)出的網(wǎng)絡(luò)請求躬翁,在網(wǎng)絡(luò)連接恢復(fù)以后再執(zhí)行這些網(wǎng)絡(luò)請求。一個例子就是一個郵件客戶端允許用戶在設(shè)備處于離線的狀態(tài)下依然能夠創(chuàng)建盯拱,發(fā)送,查看例嘱,移動和刪除已經(jīng)存在的郵件狡逢,就是因為這些操作被保存下來并且在網(wǎng)絡(luò)恢復(fù)以后再執(zhí)行。這樣的話拼卵,APP就能夠在設(shè)備有網(wǎng)絡(luò)和沒有網(wǎng)絡(luò)的時候都提供一個相似的用戶體驗奢浑。

使用GcmNetworkManager和contentProvider
確保你的APP使用數(shù)據(jù)庫或者相似的結(jié)構(gòu)來保存所有的數(shù)據(jù)到磁盤上,這樣它就能夠在不管網(wǎng)絡(luò)條件如何的情況下表現(xiàn)出極佳的體驗腋腮,比如使用(SQLite和ContentProvider)緩存數(shù)據(jù)雀彼, GCM Network Manager ( GcmNetworkManager)提供一個健全的機(jī)制和服務(wù)器同步數(shù)據(jù)當(dāng) content providers (ContentProvider)緩存這些數(shù)據(jù),結(jié)合來提供一個允許在離線狀態(tài)繼續(xù)使用的結(jié)構(gòu)即寡。

App應(yīng)該緩存從網(wǎng)絡(luò)上獲取的內(nèi)容徊哑,在發(fā)起持續(xù)的請求之前,app應(yīng)該先顯示本地的緩存數(shù)據(jù)聪富。這確保了app不管設(shè)備有沒有網(wǎng)絡(luò)連接或者是很慢或者是不可靠的網(wǎng)絡(luò)莺丑,都能夠為用戶提供服務(wù)。

除去網(wǎng)絡(luò)請求
一個離線優(yōu)先的結(jié)構(gòu)初始化時會嘗試從本地獲取數(shù)據(jù),失敗以后梢莽,從網(wǎng)絡(luò)請求數(shù)據(jù)萧豆。從網(wǎng)絡(luò)檢索以后,數(shù)據(jù)會緩存到本地昏名。這就確保對于同一塊數(shù)據(jù)發(fā)起網(wǎng)絡(luò)請求只會發(fā)生一次涮雷,對隨后的請求都會使用本地數(shù)據(jù)來完成請求。為了達(dá)到這個轻局,使用本地數(shù)據(jù)庫來對數(shù)據(jù)持久化(通常使用android.database.sqlite 或者 SharedPreferences)

這個結(jié)構(gòu)同樣簡化一個APP的流暢性洪鸭,在離線和在線狀態(tài)之間一方從網(wǎng)絡(luò)獲取數(shù)據(jù)保存到本地,另一方從緩存獲取數(shù)據(jù)展示給用戶嗽交。

對于短暫不持續(xù)的數(shù)據(jù)卿嘲,也就是內(nèi)容更新快的數(shù)據(jù),使用一個有大小夫壁,或者時間限制的磁盤緩存拾枣,比如DiskLruCache,數(shù)據(jù)通常不會發(fā)生改變的就只從網(wǎng)絡(luò)請求一次然后緩存下來以后使用盒让,這樣的數(shù)據(jù)一般是圖片或者非臨時的文檔比如新聞文章或者推送消息梅肤。

4.結(jié)語

網(wǎng)絡(luò)優(yōu)化, 是App優(yōu)化中相當(dāng)重要的一項優(yōu)化. 除了客戶端, 接口的優(yōu)化外, 很多一部分優(yōu)化還依賴于服務(wù)器端, 包括服務(wù)器端的代碼開發(fā), 部署方式等. 跟你的服務(wù)器開發(fā)/運維工程師一起聊聊這個話題吧:)

特別感謝
黑白咖
夜之魔
anly_jun
石先

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市邑茄,隨后出現(xiàn)的幾起案子姨蝴,更是在濱河造成了極大的恐慌,老刑警劉巖肺缕,帶你破解...
    沈念sama閱讀 218,386評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件左医,死亡現(xiàn)場離奇詭異,居然都是意外死亡同木,警方通過查閱死者的電腦和手機(jī)浮梢,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,142評論 3 394
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來彤路,“玉大人秕硝,你說我怎么就攤上這事≈拮穑” “怎么了远豺?”我有些...
    開封第一講書人閱讀 164,704評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長坞嘀。 經(jīng)常有香客問我躯护,道長,這世上最難降的妖魔是什么丽涩? 我笑而不...
    開封第一講書人閱讀 58,702評論 1 294
  • 正文 為了忘掉前任榛做,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘检眯。我一直安慰自己厘擂,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,716評論 6 392
  • 文/花漫 我一把揭開白布锰瘸。 她就那樣靜靜地躺著刽严,像睡著了一般。 火紅的嫁衣襯著肌膚如雪避凝。 梳的紋絲不亂的頭發(fā)上舞萄,一...
    開封第一講書人閱讀 51,573評論 1 305
  • 那天,我揣著相機(jī)與錄音管削,去河邊找鬼倒脓。 笑死,一個胖子當(dāng)著我的面吹牛含思,可吹牛的內(nèi)容都是我干的崎弃。 我是一名探鬼主播,決...
    沈念sama閱讀 40,314評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼含潘,長吁一口氣:“原來是場噩夢啊……” “哼饲做!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起遏弱,我...
    開封第一講書人閱讀 39,230評論 0 276
  • 序言:老撾萬榮一對情侶失蹤盆均,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后漱逸,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體泪姨,經(jīng)...
    沈念sama閱讀 45,680評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,873評論 3 336
  • 正文 我和宋清朗相戀三年饰抒,在試婚紗的時候發(fā)現(xiàn)自己被綠了驴娃。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,991評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡循集,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出蔗草,到底是詐尸還是另有隱情咒彤,我是刑警寧澤,帶...
    沈念sama閱讀 35,706評論 5 346
  • 正文 年R本政府宣布咒精,位于F島的核電站镶柱,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏模叙。R本人自食惡果不足惜歇拆,卻給世界環(huán)境...
    茶點故事閱讀 41,329評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧故觅,春花似錦厂庇、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,910評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至贯溅,卻和暖如春拄氯,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背它浅。 一陣腳步聲響...
    開封第一講書人閱讀 33,038評論 1 270
  • 我被黑心中介騙來泰國打工译柏, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人姐霍。 一個月前我還...
    沈念sama閱讀 48,158評論 3 370
  • 正文 我出身青樓鄙麦,卻偏偏與公主長得像,于是被迫代替她去往敵國和親邮弹。 傳聞我的和親對象是個殘疾皇子黔衡,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,941評論 2 355

推薦閱讀更多精彩內(nèi)容