前言
互聯(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請求流程說明:
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:
其中:
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)大降淮。
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ò)請求的各種情況。
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壓縮前
開啟Gzip壓縮后
對比發(fā)現(xiàn),開啟Gzip后可以減少57.3%的數(shù)據(jù)傳輸量
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ā)/運維工程師一起聊聊這個話題吧:)