客戶端加載耗時(shí)優(yōu)化方案(上)
編輯導(dǎo)語:我們經(jīng)常能碰到客戶端加載耗時(shí)的情況,那么應(yīng)該如何優(yōu)化解決這種問題,提升用戶體驗(yàn)感呢?本文作者總結(jié)了刷新加載loading的三個(gè)階段,在本篇文章中,主要是針對(duì)第一階段,為我們闡述了優(yōu)化方案。
任何一件事情的發(fā)生可能背后有很多種原因,要解決好一個(gè)問題,都要明確造成這個(gè)問題的原因是什么,然后針對(duì)這些原因進(jìn)行優(yōu)化。
在刷新加載loading的過程,經(jīng)歷了三個(gè)階段:
- 客戶端觸發(fā)頂部刷新;
- 服務(wù)器收到請(qǐng)求后準(zhǔn)備要下發(fā)的數(shù)據(jù);
- 客戶端收到服務(wù)器數(shù)據(jù)進(jìn)行展示。
本文針對(duì)第一階段:“客戶端觸發(fā)頂部刷新”聊一聊怎么減少耗時(shí)問題(下一篇文章會(huì)針對(duì)另外兩個(gè)階段闡述優(yōu)化方案)。
01
交互層面:使用占位策略緩解用戶焦慮
app某個(gè)界面一直空白,或者界面一直在轉(zhuǎn)loading,在這樣的過程中,用戶任何信息都獲取不到,會(huì)讓用戶產(chǎn)生等待焦慮。
1)動(dòng)畫策略
動(dòng)畫策略是一個(gè)比較常用的策略,比如可以使用新穎的加載動(dòng)畫來代替老式的loading菊花樣式,用戶在看動(dòng)畫的過程中加載就已經(jīng)結(jié)束了,以此降低用戶預(yù)期的等待時(shí)長。
但新穎的動(dòng)畫不一定適用所有App,不恰當(dāng)?shù)氖褂眯路f的加載動(dòng)畫甚至?xí)又啬承┯脩舻牡却箲],造成用戶流失。所以當(dāng)你決定要采用動(dòng)畫策略時(shí),不妨采用A/B Test的方式進(jìn)行測試,看看新動(dòng)畫是否真的有降低等待焦慮的作用。
2)歷史內(nèi)容策略
歷史內(nèi)容占位是目前主流App最常用的策略,除了用戶首次登陸App沒有歷史信息外,其余每次登陸都會(huì)先使用歷史內(nèi)容來進(jìn)行占位,以此來減少頁面空白加載給用戶帶來的焦慮。
02
技術(shù)層面:預(yù)拉取
預(yù)拉取的基本操作
預(yù)拉取,也即提前拉取,在用戶真正觸發(fā)向后臺(tái)拉取內(nèi)容的網(wǎng)絡(luò)請(qǐng)求之前,就已經(jīng)準(zhǔn)備好數(shù)據(jù),等到用戶真正開始拉取時(shí),直接把上次提前拉取好的數(shù)據(jù)返回給用戶,這種操作甚至可以讓用戶體會(huì)到瞬間拉取的效果。
圖1- 常規(guī)拉取流程
圖2-預(yù)拉取流程
如上圖所示,預(yù)拉取的最關(guān)鍵的問題在于:何時(shí)觸發(fā)預(yù)拉?。?/p>
用戶自然希望每次拉取時(shí),客戶端都把數(shù)據(jù)拉取好,這樣每次都可以體會(huì)到瞬間拉取的效果。那么最直接的方法就是:在一切用戶未進(jìn)行網(wǎng)絡(luò)請(qǐng)求的時(shí)刻,一直向后臺(tái)請(qǐng)求最新的數(shù)據(jù)。
但從用戶流量,服務(wù)器所能接受的并發(fā)請(qǐng)求上限來看,上面這種策略不僅會(huì)浪費(fèi)用戶流量,甚至在用戶數(shù)量多的情況下會(huì)把服務(wù)器搞掛掉,這就得不償失了。
我們不妨換個(gè)思路,如果我們是用戶,我們?cè)谑裁辞闆r下對(duì)拉取內(nèi)容耗時(shí)要求最高?
那自然是我們對(duì)內(nèi)容最迫切的時(shí)候,比如:
- 收到了新通知的紅點(diǎn)
- 首次打開app
下面我們針對(duì)”紅點(diǎn)預(yù)拉取”和”首次預(yù)拉取”討論下具體的產(chǎn)品方案。
03
紅點(diǎn)預(yù)拉取
在介紹紅點(diǎn)預(yù)拉取之前,我們先明確下紅點(diǎn)本身的定位,紅點(diǎn)大致可以被分為兩種類型:
- 消息型紅點(diǎn):比如朋友圈和視頻號(hào)的紅點(diǎn),會(huì)在你的朋友有輸出型行為(點(diǎn)贊、發(fā)表、評(píng)論等)時(shí)給予你通知,這種紅點(diǎn)強(qiáng)調(diào)實(shí)時(shí)性,需要具有過期和撤回的能力;
- 功能型紅點(diǎn):不強(qiáng)調(diào)實(shí)時(shí)性,一般在給用戶介紹新功能時(shí)起引導(dǎo)的作用,只有當(dāng)你手動(dòng)點(diǎn)擊時(shí)這種紅點(diǎn)才會(huì)消失,這種紅點(diǎn)基本不需要具備過期和撤回的能力。
因?yàn)槲覀冃枰ㄟ^預(yù)拉取來獲取新的內(nèi)容,遂下面討論的主要是”消息型紅點(diǎn)”。
紅點(diǎn)在app中無處不在,以朋友圈舉例,當(dāng)我在發(fā)現(xiàn)頁收到一個(gè)”同事A的頭像+小紅點(diǎn)”類型的紅點(diǎn),這時(shí)在我點(diǎn)進(jìn)朋友圈之前,我內(nèi)心的預(yù)期自然是想看 同事A 點(diǎn)贊了什么內(nèi)容。
在我點(diǎn)進(jìn)朋友圈如果加載的loading時(shí)間過長,我的預(yù)期就沒有被滿足。
那么用紅點(diǎn)預(yù)拉取怎么做呢?
當(dāng)我收到”同事A的頭像+小紅點(diǎn)”類型的紅點(diǎn)(紅點(diǎn)中要帶上”同事A剛發(fā)的那條內(nèi)容背后的id”)時(shí),客戶端立馬通過這個(gè)id去服務(wù)器請(qǐng)求內(nèi)容數(shù)據(jù),客戶端收到內(nèi)容數(shù)據(jù)中先存在緩存里。
當(dāng)我真正點(diǎn)進(jìn)朋友圈觸發(fā)頂部刷新時(shí),這時(shí)直接把我已經(jīng)從服務(wù)器拉取到數(shù)據(jù)進(jìn)行展示。這樣的一個(gè)流程可以被稱為”紅點(diǎn)預(yù)拉取”。
但是, 紅點(diǎn)預(yù)拉取就這么簡單嗎?非也非也。
我們不妨看幾個(gè)關(guān)于紅點(diǎn)預(yù)拉取的問題(相關(guān)解釋在文末~):
- 問題1:用戶收到紅點(diǎn)之后對(duì)紅點(diǎn)對(duì)應(yīng)的內(nèi)容進(jìn)行了預(yù)拉取,但這條內(nèi)容在客戶端收到紅點(diǎn)和發(fā)起內(nèi)容之間被作者刪除了,也就是預(yù)拉取拉不到內(nèi)容了,怎么辦?
- 問題2:用戶收到A紅點(diǎn)后,客戶端對(duì)A內(nèi)容進(jìn)行了預(yù)拉取,但在真正消費(fèi)預(yù)拉取內(nèi)容之前,A內(nèi)容因?yàn)榘踩珕栴}被處罰打擊刪除了,這時(shí)A紅點(diǎn)會(huì)被撤銷,那已經(jīng)預(yù)拉取的內(nèi)容怎么辦?
- 問題3:用戶收到A紅點(diǎn)后,客戶端對(duì)A內(nèi)容進(jìn)行了預(yù)拉取,但在真正消費(fèi)預(yù)拉取內(nèi)容之前,用戶又收到了B紅點(diǎn),且B紅點(diǎn)把A紅點(diǎn)進(jìn)行了覆蓋,那么已經(jīng)預(yù)拉取過的A內(nèi)容該怎么辦?
- 問題4:用戶收到A紅點(diǎn)后,客戶端對(duì)A內(nèi)容進(jìn)行了預(yù)拉取,但用戶在12小時(shí)候之后才進(jìn)入了朋友圈,這時(shí)應(yīng)該展示A內(nèi)容嗎?
04
旁路預(yù)拉取
旁路預(yù)拉取在多tab的產(chǎn)品中較為常用,以抖音為例,抖音有”同城、關(guān)注、推薦”這三個(gè)主流tab,目前抖音出現(xiàn)頻率最多的紅點(diǎn)為關(guān)注紅點(diǎn)。
大部分人點(diǎn)進(jìn)抖音都是進(jìn)入了”關(guān)注tab”,關(guān)注tab可以通過紅點(diǎn)觸發(fā)預(yù)拉取,但在用戶點(diǎn)到推薦tab時(shí),因?yàn)橥扑]tab沒有做預(yù)拉取,所以用戶頂部刷新加載內(nèi)容耗時(shí)會(huì)比較長(大約2s),很多用戶在這2s內(nèi)就離開了抖音。
既然關(guān)注tab可以有紅點(diǎn)觸發(fā)的預(yù)拉取,關(guān)注tab的拉取耗時(shí)進(jìn)行了優(yōu)化,那我們能不能讓關(guān)注tab幫一幫推薦tab(或同城tab)呢?
答案是可以的,這時(shí)就可以采取”旁路預(yù)拉取”。
客戶端在關(guān)注tab加載數(shù)據(jù),向服務(wù)器請(qǐng)求數(shù)據(jù)時(shí),服務(wù)器可以和客戶端約定一個(gè)開關(guān):enablePrefectSwitch。
當(dāng)服務(wù)器給客戶端下發(fā)了 enablePrefectSwitch 等于 YES 的指令,我們就去預(yù)拉取推薦tab的內(nèi)容,那么當(dāng)用戶在關(guān)注tab刷完內(nèi)容切到推薦tab,會(huì)發(fā)現(xiàn)推薦tab的拉取耗時(shí)很短(因?yàn)橐呀?jīng)做了預(yù)拉取了)。
問題1:服務(wù)器應(yīng)該什么時(shí)候告訴客戶端enablePrefectSwitch 等于 YES 呢?
問題2:在關(guān)注tab觸發(fā)旁路預(yù)拉取去進(jìn)行推薦tab的預(yù)拉取,在推薦tab預(yù)拉取成功前,用戶就已經(jīng)切到了推薦tab手動(dòng)進(jìn)行了頂部刷新,那么這個(gè)時(shí)候推薦tab要展示的是預(yù)拉取的內(nèi)容,還是手動(dòng)觸發(fā)頂部刷新的內(nèi)容?
05
1. 曝光預(yù)拉取
以微信為例,當(dāng)用戶切到發(fā)現(xiàn)頁時(shí),會(huì)曝光”朋友圈”的入口,也會(huì)曝光”視頻號(hào)”的入口,曝光預(yù)拉取也即當(dāng)入口曝光時(shí),觸發(fā)預(yù)拉取的邏輯。
曝光預(yù)拉取的策略比較好理解,但也有一些需要注意的小問題(相關(guān)解釋在文末~):
問題1:如果客戶端采取曝光預(yù)拉取的策略,從訪問流量上考慮,服務(wù)器需要注意什么問題呢?
06
定時(shí)預(yù)拉?。?/strong>
定時(shí)預(yù)拉取比較好理解,即每隔n分鐘觸發(fā)一次預(yù)拉取。
定時(shí)預(yù)拉取的策略比較好理解,但也有一些需要注意的小問題(相關(guān)解釋在文末~):
問題1:以微信這樣的產(chǎn)品為例,如果打算對(duì)視頻號(hào)采取定時(shí)預(yù)拉?。ū热缑?0分鐘就對(duì)視頻號(hào)內(nèi)容進(jìn)行預(yù)拉取),會(huì)不會(huì)有問題?
問題2:采取定時(shí)預(yù)拉取,用戶首次啟動(dòng)app時(shí)(也即0分鐘時(shí)),是否要進(jìn)行預(yù)拉???
07
預(yù)拉取要注意的細(xì)節(jié)
1)方案兼容問題
我們發(fā)現(xiàn)以上的預(yù)拉取方案都有一定的缺點(diǎn),所以實(shí)際工程中一般是將上面所有方案兼容起來,取長補(bǔ)短。
比如以紅點(diǎn)預(yù)拉取為主體,其它預(yù)拉取方案作為輔助的產(chǎn)品策略。
紅點(diǎn)預(yù)拉取到的內(nèi)容被用戶使用的概率比較大,旁路預(yù)拉取可以優(yōu)化多tab瀏覽時(shí)用戶切tab的體驗(yàn),曝光預(yù)拉取與定時(shí)預(yù)拉取相結(jié)合,解決某些App廠商在某些時(shí)間點(diǎn)統(tǒng)一殺App進(jìn)程導(dǎo)致后臺(tái)在某個(gè)時(shí)間點(diǎn)訪問點(diǎn)突增的問題。
在紅點(diǎn)撤銷、熱門紅點(diǎn)過期、新增熱門紅點(diǎn)時(shí)候丟棄之前預(yù)加載的內(nèi)容,但在有紅點(diǎn)的背景下觸發(fā) 旁路、曝光或定時(shí) 預(yù)拉取時(shí),要帶上相應(yīng)的紅點(diǎn)信息。
2)預(yù)拉取要做假耗時(shí)
這里需要注意一個(gè)交互上的細(xì)節(jié),預(yù)拉取的初衷是降低拉取的等待耗時(shí),但如果將等待耗時(shí)降低到了0秒,可能會(huì)給用戶一種并沒有拉取成功,而是展示了歷史占位的錯(cuò)覺。
所以即使客戶端已經(jīng)進(jìn)行了內(nèi)容預(yù)拉取,在用戶觸發(fā)加載時(shí)也要等待0.5s后再給用戶展示數(shù)據(jù),當(dāng)然這0.5s是個(gè)經(jīng)驗(yàn)值,實(shí)際工程中可以通過實(shí)驗(yàn)進(jìn)行配置,找到一個(gè)既讓用戶感受到加載的過程,又能盡可能多的降低用戶等待焦慮的時(shí)間點(diǎn)。
3)在預(yù)拉取方案下,所有的網(wǎng)絡(luò)請(qǐng)求都應(yīng)該設(shè)計(jì)成串行的
看到這里,你可能會(huì)發(fā)現(xiàn)采用預(yù)拉取會(huì)有一個(gè)風(fēng)險(xiǎn)點(diǎn):預(yù)拉取的請(qǐng)求(標(biāo)記為預(yù)拉取A) 和 用戶手動(dòng)刷新的請(qǐng)求(標(biāo)記為手動(dòng)拉取B) 同時(shí)請(qǐng)求了服務(wù)器,那么用戶到底應(yīng)該展示哪個(gè)內(nèi)容?
這里有兩個(gè)方案:
- 用戶觸發(fā)手動(dòng)拉取B時(shí),主動(dòng)取消掉上一次的預(yù)拉取A,用戶展示的內(nèi)容以手動(dòng)拉取B為準(zhǔn);
- 用戶觸發(fā)手動(dòng)拉取B時(shí),這時(shí)發(fā)現(xiàn)預(yù)拉取A已經(jīng)在請(qǐng)求服務(wù)器內(nèi)容了,那么手動(dòng)拉取B以預(yù)拉取A返回的數(shù)據(jù)為準(zhǔn)。
附:實(shí)際上并發(fā)請(qǐng)求的后果比展示哪個(gè)內(nèi)容更嚴(yán)重,并發(fā)請(qǐng)求甚至?xí)?dǎo)致數(shù)據(jù)丟失,或下發(fā)重復(fù)數(shù)據(jù)等問題。
08
預(yù)拉取存在的問題
通過上面的預(yù)拉取方案,實(shí)際過程中會(huì)發(fā)現(xiàn)兩個(gè)問題:
- 高并發(fā),后臺(tái)服務(wù)器成本高;
- 紅點(diǎn)頻率推送高的產(chǎn)品,經(jīng)常會(huì)在上一個(gè)紅點(diǎn)預(yù)拉取內(nèi)容還未消費(fèi)前,就被新的紅點(diǎn)給覆蓋了,預(yù)拉取存在浪費(fèi)的情況。
所以我們可不可以在減少預(yù)拉取頻率的基礎(chǔ)上,還能提高預(yù)拉取內(nèi)容的使用率呢?答案是可行的,可以將人工智能和預(yù)拉取融合。
AI與預(yù)拉?。涸谡归_講解AI與預(yù)拉取策略之前,我們先做幾個(gè)用戶使用習(xí)慣的合理假設(shè):
- 假設(shè)一:不同用戶對(duì)不同的紅點(diǎn)樣式刺激不同,部分用戶有著強(qiáng)烈查看特定紅點(diǎn)內(nèi)容的沖動(dòng);
- 假設(shè)二:不同用戶使用產(chǎn)品的頻率不同;
- 假設(shè)三:不同用戶有著不同的高頻使用產(chǎn)品的時(shí)間段,每個(gè)用戶有著自己高頻使用產(chǎn)品的特定時(shí)間段。
1)根據(jù)用戶畫像觸發(fā)預(yù)拉取
根據(jù)假設(shè)一,A用戶可能對(duì)某個(gè)明星發(fā)的內(nèi)容紅點(diǎn)比較好奇,B用戶可能對(duì)自己愛慕的人發(fā)新內(nèi)容的紅點(diǎn)比較沖動(dòng),千人前面,每個(gè)人對(duì)不同紅點(diǎn)代表的含義查看沖動(dòng)不同。
可以通過建立模型來刻畫用戶感興趣內(nèi)容的用戶畫像,只針對(duì)用戶感興趣的消息紅點(diǎn)觸發(fā)預(yù)拉取,且可以提升這類紅點(diǎn)的優(yōu)先級(jí),在不影響紅點(diǎn)本身體系的情況下,讓這類紅點(diǎn)盡可能長的存在于用戶界面上。
2)使用頻率
根據(jù)假設(shè)二,有部分用戶可能一直都接受到各種類型的消息紅點(diǎn),但始終沒有對(duì)這類紅點(diǎn)進(jìn)行過消費(fèi)。
所以針對(duì)這類用戶可以適當(dāng)?shù)倪M(jìn)行紅點(diǎn)懲罰,比如20分鐘內(nèi)不再推紅點(diǎn),又或者降低紅點(diǎn)觸發(fā)預(yù)拉取的頻率,只針對(duì)用戶感興趣的紅點(diǎn)觸發(fā)預(yù)拉取,當(dāng)用戶頻率和畫像越來越全面時(shí),再動(dòng)態(tài)調(diào)整預(yù)拉取策略。
3)使用時(shí)間段
根據(jù)假設(shè)三,不同用戶的使用時(shí)段可能不同,比如A用戶上班時(shí)間較長,可能只會(huì)在晚上11點(diǎn)-12點(diǎn)期間進(jìn)行內(nèi)容消費(fèi),白天大部分時(shí)間即使收到了紅點(diǎn)也沒有時(shí)間去查看,通過建立統(tǒng)計(jì)模型明確用戶高頻使用時(shí)長,在這段時(shí)間段內(nèi)提升用戶預(yù)拉取的觸發(fā)頻率。
09
相關(guān)問題解釋:
1. 紅點(diǎn)預(yù)拉取
問題1:用戶收到紅點(diǎn)之后對(duì)紅點(diǎn)對(duì)應(yīng)的內(nèi)容進(jìn)行了預(yù)拉取,但這條內(nèi)容在客戶端收到紅點(diǎn)和發(fā)起內(nèi)容之間被作者刪除了,也就是預(yù)拉取拉不到內(nèi)容了,怎么辦?
答:這種情況下預(yù)拉取沒拉取到內(nèi)容是正常表現(xiàn),應(yīng)該啟用紅點(diǎn)撤回機(jī)制。
問題2:用戶收到A紅點(diǎn)后,客戶端對(duì)A內(nèi)容進(jìn)行了預(yù)拉取,但在真正消費(fèi)預(yù)拉取內(nèi)容之前,A內(nèi)容因?yàn)榘踩珕栴}被處罰打擊刪除了,這時(shí)A紅點(diǎn)會(huì)被撤銷,那已經(jīng)預(yù)拉取的內(nèi)容怎么辦?
答:A紅點(diǎn)被撤銷后,對(duì)應(yīng)的預(yù)拉取的A內(nèi)容就要進(jìn)行銷毀。也即:有A紅點(diǎn)不一定要求有A內(nèi)容,但A紅點(diǎn)被撤銷時(shí),預(yù)拉取到的A內(nèi)容一定也要撤銷掉。
問題3:用戶收到A紅點(diǎn)后,客戶端對(duì)A內(nèi)容進(jìn)行了預(yù)拉取,但在真正消費(fèi)預(yù)拉取內(nèi)容之前,用戶又收到了B紅點(diǎn),且B紅點(diǎn)把A紅點(diǎn)進(jìn)行了覆蓋,那么已經(jīng)預(yù)拉取過的A內(nèi)容該怎么辦?
答:B紅點(diǎn)覆蓋掉A紅點(diǎn)后,應(yīng)該先立即撤銷掉對(duì)A內(nèi)容的預(yù)拉取,接著再進(jìn)行B內(nèi)容的預(yù)拉取。
問題4:用戶收到A紅點(diǎn)后,客戶端對(duì)A內(nèi)容進(jìn)行了預(yù)拉取,但用戶在12小時(shí)候之后才進(jìn)入了朋友圈,這時(shí)應(yīng)該展示A內(nèi)容嗎?
答:A紅點(diǎn)屬于”消息型紅點(diǎn)”,有時(shí)效性,12個(gè)小時(shí)都沒有對(duì)A紅點(diǎn)進(jìn)行消費(fèi),那么A紅點(diǎn)應(yīng)該走過期銷毀的邏輯,同時(shí)也應(yīng)該撤銷預(yù)拉取到的A內(nèi)容。
2. 曝光預(yù)拉取
問題1:如果客戶端采取曝光預(yù)拉取的策略,從訪問流量上考慮,服務(wù)器需要注意什么問題呢?
答:早上8、9點(diǎn)是用戶起床的高峰期,但這段時(shí)間可能公司還沒有開始上班,針對(duì)這段時(shí)間用戶訪問的峰值要提前進(jìn)行監(jiān)控,防止出現(xiàn)服務(wù)器宕機(jī)事故。
3. 定時(shí)預(yù)拉取
問題1:以微信這樣的產(chǎn)品為例,如果打算對(duì)視頻號(hào)采取定時(shí)預(yù)拉?。ū热缑?0分鐘就對(duì)視頻號(hào)內(nèi)容進(jìn)行預(yù)拉?。?,會(huì)不會(huì)有問題?
答:會(huì)有問題,微信主打即時(shí)通訊的產(chǎn)品,通訊才是最高頻的使用場景。如果在微信打開期間都定時(shí)做視頻號(hào)的內(nèi)容預(yù)拉取,預(yù)拉取的內(nèi)容被消費(fèi)的幾率不大,且可能會(huì)對(duì)服務(wù)器產(chǎn)生不必要的請(qǐng)求。
問題2:采取定時(shí)預(yù)拉取,用戶首次啟動(dòng)app時(shí)(也即0分鐘時(shí)),是否要進(jìn)行預(yù)拉???
答:有些安卓機(jī)出于性能考慮,會(huì)在某個(gè)時(shí)間點(diǎn)強(qiáng)殺所有app,所以在這種情況下所有用戶重新打開app,對(duì)服務(wù)器的預(yù)拉取訪問會(huì)出現(xiàn)一個(gè)突刺,而且用戶打開app,實(shí)際上并不一定是要訪問預(yù)拉取的內(nèi)容,所以不建議在首次啟動(dòng)app時(shí)就直接去進(jìn)行預(yù)拉取。
作者,和產(chǎn)品經(jīng)理聊技術(shù);公眾號(hào):和產(chǎn)品經(jīng)理聊技術(shù)
本文由 @和產(chǎn)品經(jīng)理聊技術(shù) 原創(chuàng)發(fā)布于人人都是產(chǎn)品經(jīng)理,未經(jīng)作者許可,禁止轉(zhuǎn)載。
題圖來自Unsplash,基于CC0協(xié)議。
講得太好了!講實(shí)踐也講原理, 基礎(chǔ)邏輯很清晰,讓小白也能看懂!感謝作者
插眼