整合營(yíng)銷服務(wù)商

          電腦端+手機(jī)端+微信端=數(shù)據(jù)同步管理

          免費(fèi)咨詢熱線:

          品質(zhì)優(yōu)化 - 圖文詳情頁(yè)秒開(kāi)實(shí)踐

          品質(zhì)優(yōu)化 - 圖文詳情頁(yè)秒開(kāi)實(shí)踐

          作為一個(gè)內(nèi)容類應(yīng)用,看新聞讀資訊一直是頭條用戶的核心需求,頁(yè)面的打開(kāi)速度直接關(guān)系到用戶使用頭條的核心體驗(yàn),在頭條中,為了更多的承載足夠豐富的樣式和邏輯下保持多端體驗(yàn)的統(tǒng)一,詳情頁(yè)的內(nèi)容我們是通過(guò) WebView 來(lái)承載的,但 WebView 本身的性能相比 Native 來(lái)說(shuō)比較差,因此,技術(shù)團(tuán)隊(duì)一直致力于優(yōu)化詳情頁(yè)的加載速度。

          經(jīng)過(guò)不斷的優(yōu)化,目前中詳情頁(yè)在線上的打開(kāi)體驗(yàn),從肉眼上基本已經(jīng)感知不到加載過(guò)程。在接下來(lái)這篇文章里,我們會(huì)逐步拆解和介紹我們對(duì)詳情頁(yè)加載優(yōu)化的思路和實(shí)踐。

          先讓我們來(lái)看看優(yōu)化前后的效果吧~

          詳情頁(yè)加載體驗(yàn)優(yōu)化前

          詳情頁(yè)加載體驗(yàn)優(yōu)化后

          數(shù)據(jù)建立

          性能

          當(dāng)我們開(kāi)始著手優(yōu)化頁(yè)面加載速度之前,我們需要明確一個(gè)問(wèn)題,怎樣才是用戶真正體驗(yàn)到的頁(yè)面加載時(shí)間。

          首先我們可以看下面這個(gè)公式:

          頁(yè)面加載時(shí)間 = 頁(yè)面加載完成時(shí)間 - 頁(yè)面開(kāi)始加載時(shí)間
          

          頁(yè)面開(kāi)始加載時(shí)間很好確定,當(dāng)用戶點(diǎn)擊了 Feed 上的卡片,我們就可以認(rèn)為頁(yè)面開(kāi)始加載了。

          問(wèn)題是怎么定義頁(yè)面加載完成了呢?從客戶端的角度上看,無(wú)論是 iOS 還是 Android,WebView 都提供了一個(gè) loadFinsih 的回調(diào),但在實(shí)際應(yīng)用中我們發(fā)現(xiàn),loadFinish 回調(diào)并不能反應(yīng)用戶的真實(shí)體驗(yàn)。

          一般來(lái)說(shuō),WebView 渲染需要經(jīng)過(guò)下面幾個(gè)步驟

          1. 解析 HTML 文件
          2. 加載 JavaScript 和 CSS 文件
          3. 解析并執(zhí)行 JavaScript
          4. 構(gòu)建 DOM 結(jié)構(gòu)
          5. 加載圖片等資源
          6. 頁(yè)面加載完畢

          而 loadFinish 實(shí)際上是在頁(yè)面加載完畢階段,而 DOM 構(gòu)建完成時(shí)頁(yè)面結(jié)構(gòu)就已經(jīng)基本渲染完成,所以從用戶真實(shí)體驗(yàn)的角度出發(fā),我們以 DOM 結(jié)構(gòu)構(gòu)建完成(即 domReady)的時(shí)間點(diǎn)作為頁(yè)面加載完成時(shí)間點(diǎn)。

          白屏

          在詳情頁(yè)瀏覽過(guò)程中,除了頁(yè)面加載速度之外,還有一個(gè)特別影響用戶體驗(yàn)的問(wèn)題,就是頁(yè)面的白屏,也是早期的時(shí)候用戶反饋比較多的問(wèn)題,但有很多場(chǎng)景都可能導(dǎo)致詳情頁(yè)發(fā)生白屏,比如說(shuō)網(wǎng)絡(luò)異常,WebView 異常等等,需要從用戶體驗(yàn)的角度出發(fā)去檢測(cè)用戶發(fā)生白屏的情況。

          目前可以想到最直觀的方案就是對(duì) WebView 進(jìn)行截圖,遍歷截圖的像素點(diǎn)的顏色值,如果非白屏顏色的顏色點(diǎn)超過(guò)一定的閾值,就可以認(rèn)為不是白屏,目前需要考慮的是這個(gè)方案的性能問(wèn)題和檢測(cè)時(shí)機(jī)。

          iOS 中提供了 WebView 快照的接口獲取當(dāng)前 WebView 渲染的內(nèi)容,底層采用異步回調(diào)的實(shí)現(xiàn)方式,API 耗時(shí) 10ms 左右,用戶基本無(wú)感知。

          - (void)takeSnapshotWithConfiguration:(nullable WKSnapshotConfiguration *)snapshotConfiguration completionHandler:(void (^)(UIImage * _Nullable snapshotImage, NSError * _Nullable error))completionHandler API_AVAILABLE(ios(11.0));
          

          Android 中系統(tǒng)提供的獲取視圖內(nèi)容的接口為 getDrawingCache,API 耗時(shí)在 40ms 左右,性能損耗也不是特別大。

          除了截圖的性能損耗,像素點(diǎn)檢測(cè)也是白屏檢測(cè)中比較耗時(shí)的場(chǎng)景,經(jīng)過(guò)實(shí)驗(yàn),我們把 WebView 截圖的圖片進(jìn)行縮小到原圖的 1/6,遍歷檢測(cè)圖片的像素點(diǎn),當(dāng)非白色的像素點(diǎn)大于 5% 的時(shí)候我們就認(rèn)為是非白屏的情況,可以相對(duì)高效檢測(cè)準(zhǔn)確得出詳情頁(yè)是否發(fā)生了白屏。

          指標(biāo)建立

          確定好口徑之后,我們還有需要明確的一個(gè)問(wèn)題是,什么指標(biāo)可以反映用戶刷頭條時(shí)的真實(shí)體驗(yàn)。

          最早的時(shí)候,我們用的是詳情頁(yè)頁(yè)面的頁(yè)面平均加載時(shí)長(zhǎng),也就是頁(yè)面加載時(shí)長(zhǎng)的總和/頁(yè)面 pv,在開(kāi)始的時(shí)候這個(gè)指標(biāo)也的確可以明確我們的加載速度。

          后來(lái)隨著詳情頁(yè)的加載優(yōu)化逐漸的深入,會(huì)發(fā)現(xiàn)平均加載時(shí)長(zhǎng)雖然也可以反映詳情頁(yè)加載速度,但是因?yàn)樵斍轫?yè)的 pv 比較高,如果使用平均加載速度化很多用戶體驗(yàn)問(wèn)題就被平均掉了,并不能反映用戶的真實(shí)情況,后面我們又調(diào)整了口徑,將指標(biāo)調(diào)整為所有用戶進(jìn)入詳情頁(yè)的 80 分位值,比如說(shuō),假如頭條詳情頁(yè)加載速度 80 分位值是 1 秒,那么就說(shuō)明 80% 的情況下用戶進(jìn)入詳情頁(yè)都能在 1s 內(nèi)加載完成,當(dāng)然經(jīng)過(guò)我們的不斷優(yōu)化,詳情頁(yè)加載的 80 分位值已經(jīng)能夠達(dá)到 0.3s 以內(nèi),也就是說(shuō),80% 的情況下用戶都能夠在 0.3s 內(nèi)完成頁(yè)面加載。

          80分位優(yōu)化數(shù)據(jù)對(duì)比

          再后來(lái)我們又發(fā)現(xiàn),在頭條詳情頁(yè)的量級(jí)下面,即使是 80 分位的數(shù)據(jù)也不能反應(yīng)許多長(zhǎng)尾用戶的真實(shí)情況,也為了更極致的追求詳情頁(yè)的加載性能,我們最后將詳情頁(yè)的性能口徑調(diào)整到 95 分位。到目前在我們的努力下,詳情頁(yè)的加載速度 95 分位也優(yōu)化了將近 80% 。

          我們究竟做了什么呢,接下來(lái)會(huì)慢慢介紹一下。

          模板優(yōu)化

          模板拆分

          如前所述,圖文詳情頁(yè)是通過(guò) WebView 來(lái)承載的,而 WebView 承載頁(yè)面最簡(jiǎn)單的做法就是直接通過(guò) URL 去加載一個(gè)線上頁(yè)面。那么先來(lái)一道簡(jiǎn)單的面試題,當(dāng)用戶從瀏覽器輸入一個(gè) URL 到頁(yè)面展現(xiàn)發(fā)生了什么呢?

          之前已經(jīng)介紹過(guò)頁(yè)面的渲染流程了,現(xiàn)在我們?cè)俸?jiǎn)單看看用戶從點(diǎn)擊到看到頁(yè)面內(nèi)容需要經(jīng)歷如下幾個(gè)階段:

          WebView 加載流程


          可以看到,通過(guò)線上頁(yè)面加載用戶每次進(jìn)入詳情頁(yè)都要通過(guò)多次網(wǎng)絡(luò)加載,極容易受網(wǎng)絡(luò)波動(dòng)的影響,這種情況下,也無(wú)法保證頁(yè)面加載的時(shí)長(zhǎng)和成功率,極大的影響了用戶體驗(yàn)。

          于是在頭條中,我們將新聞中標(biāo)題和正文內(nèi)容進(jìn)行拆分,把頭條詳情頁(yè)的公共樣式 CSS 和 邏輯 JS 都抽離出來(lái),形成一個(gè)獨(dú)立而完備的詳情頁(yè)模板,這樣我們就可以把模板直接內(nèi)置在客戶端中。

          同時(shí)我們會(huì)與前端約定好的 JS 腳本,通過(guò)接口將正文內(nèi)容數(shù)據(jù)注入頁(yè)面完成詳情頁(yè)的頁(yè)面展示,通過(guò)該這種方式我們可以將接口放到客戶端上進(jìn)行請(qǐng)求。

          這樣用戶進(jìn)入詳情頁(yè)的時(shí)候只需要本地加載模板,而且加載模板的時(shí)候也可以同時(shí)并行請(qǐng)求詳情頁(yè)數(shù)據(jù),再將數(shù)據(jù)注入進(jìn)模板中。

          那么用戶點(diǎn)擊到看到頁(yè)面內(nèi)容只需要經(jīng)歷下面的階段:

          模板拆分


          如上圖所示,我們只需要通過(guò)一次網(wǎng)絡(luò)加載就可以完成頁(yè)面渲染。

          還能不能更快一點(diǎn)呢?當(dāng)然能!

          為了提高頁(yè)面的加載速度,客戶端通過(guò)一定的策略去預(yù)加載新聞數(shù)據(jù),這樣在理想狀態(tài)下用戶進(jìn)入頁(yè)面時(shí)看到頁(yè)面時(shí)就可以直接使用緩存的數(shù)據(jù),用戶在看新聞的時(shí)候可以實(shí)現(xiàn)完全離線化,避免受到網(wǎng)絡(luò)的影響。

          本地加載

          模板預(yù)熱

          完全脫離了網(wǎng)絡(luò)加載之后,還能再快一點(diǎn)呢?當(dāng)然還是可以的!

          當(dāng)全流程離線化之后,頁(yè)面加載的瓶頸就變成了本地模板的加載時(shí)間,所以我們接下來(lái)要做的就是優(yōu)化模板加載時(shí)間。

          對(duì)于模板來(lái)說(shuō),我們做了兩件事情

          1. 模板合并,正常來(lái)說(shuō),WebView 需要在加載玩主 HTML 之后再去加載 HTML 中的 JS 和 CSS,需要多次 IO 操作,于是我們將 JS 和 CSS 還有一些圖片都內(nèi)聯(lián)到一個(gè)文件中,這樣,加載模板時(shí)就只需要一次 IO 操作,也大大減少因?yàn)?IO 加載沖突導(dǎo)致模板加載失敗問(wèn)題
          2. 模板簡(jiǎn)化,我們將部分非必須的腳本異步化拉取,精簡(jiǎn)不必要的樣式和 JS 代碼,將模板大小壓縮了 20% 以上

          通過(guò)上面優(yōu)化,我們就已經(jīng)將模板加載時(shí)間大大優(yōu)化了,但是還能不能更給力呢?還是可以的。

          對(duì)于客戶端來(lái)說(shuō),當(dāng)模板跟數(shù)據(jù)分離之后,由于每次用戶點(diǎn)擊的時(shí)候加載的都是同一個(gè)模板,所以實(shí)際上,我們并不需要在用戶進(jìn)入頁(yè)面的時(shí)候才去創(chuàng)建 WebView 以及加載模板,我們只需要在合適的時(shí)機(jī)在后臺(tái)創(chuàng)建 WebView,并且提前預(yù)熱加載模板,當(dāng)用戶點(diǎn)擊進(jìn)入頁(yè)面的時(shí)候就能使用已經(jīng)加載好模板的 WebView,直接將詳情頁(yè)的內(nèi)容數(shù)據(jù)通過(guò) JS 注入到頁(yè)面中,前端收到數(shù)據(jù)后進(jìn)行頁(yè)面渲染即可。

          此時(shí)用戶進(jìn)入詳情頁(yè)實(shí)際就不再需要重新加載模板了,路徑就變成了:

          模板預(yù)熱

          可以看下,通過(guò)本地測(cè)試的模板預(yù)熱和數(shù)據(jù)預(yù)取的優(yōu)化效果,還是比較明顯的,基本上已經(jīng)達(dá)到了上面的截圖中的驗(yàn)證效果。

          本地測(cè)試數(shù)據(jù)

          模板復(fù)用

          當(dāng)我們拆分完模板和數(shù)據(jù)之后,數(shù)據(jù)上優(yōu)化已經(jīng)比較明顯,但我們說(shuō)過(guò),除了驗(yàn)證數(shù)據(jù),我們還需要看線上用戶的真實(shí)體驗(yàn)數(shù)據(jù),從 95 分位上看實(shí)際數(shù)據(jù)優(yōu)化卻不是很明顯,所以我們從數(shù)據(jù)上觀察,用戶預(yù)熱模板的命中率只有 53%,還有進(jìn)一步的提升空間。

          模板預(yù)熱率

          為了盡可能的提高頁(yè)面的加載速度,我們希望用戶每次進(jìn)入詳情頁(yè)的時(shí)候都能夠使用預(yù)熱好模板的 WebView,一般情況下,我們都會(huì)使用模板預(yù)創(chuàng)建池的手段來(lái)優(yōu)化用戶進(jìn)入詳情頁(yè)時(shí)的預(yù)熱模板命中率。

          但其實(shí)在很多情況下,WebView 的創(chuàng)建是一個(gè)性能開(kāi)銷比較大的操作,如果我們使用預(yù)創(chuàng)建池的方案,那么就會(huì)在后臺(tái)頻繁創(chuàng)建 WebView,這樣對(duì)用戶在 Feed 場(chǎng)景的瀏覽體驗(yàn)也會(huì)有一定的影響。

          而且假如用戶頻繁且快速進(jìn)出詳情頁(yè)時(shí),實(shí)際場(chǎng)景中用戶也很容易遇到無(wú)法命中預(yù)熱模板的場(chǎng)景。

          這個(gè)時(shí)候?yàn)榱藘?yōu)化用戶的體驗(yàn),如前文所述,我們每次使用的時(shí)候都是同一個(gè)模板,所以我們使用完當(dāng)前 WebView 之后,只需要在用戶退出頁(yè)面的時(shí)候把正文數(shù)據(jù)清空,這樣進(jìn)入下一個(gè)頁(yè)面的時(shí)候就能夠繼續(xù)復(fù)用這個(gè) WebView 重新注入數(shù)據(jù)即可。

          通過(guò)這個(gè)手段,我們既避免了頻繁在后臺(tái)預(yù)創(chuàng)建 WebView 對(duì)用戶刷 Feed 體驗(yàn)的影響,把用戶進(jìn)入頁(yè)面時(shí)候的預(yù)熱模板命中率從 53% 提升到 92%,優(yōu)化了用戶體驗(yàn)。

          預(yù)熱模板命中率

          網(wǎng)絡(luò)優(yōu)化

          說(shuō)完我們?cè)谀0?WebView 方面的優(yōu)化之后,再介紹一下我們?cè)趦?nèi)容請(qǐng)求上的優(yōu)化。

          CDN 加速

          由于頭條詳情頁(yè)請(qǐng)求有以下特點(diǎn)

          1. 流量大,之前說(shuō)過(guò),看新聞作為用戶在頭條的核心場(chǎng)景,每天都有上億用戶在使用頭條,詳情頁(yè)的數(shù)據(jù)流量十分大。
          2. 數(shù)據(jù)屬性基本不變,在詳情頁(yè)的請(qǐng)求中,很多熱點(diǎn)文章是重復(fù)渲染計(jì)算的,正文、標(biāo)題、作者信息、圖片控制以及一些樣式和業(yè)務(wù)邏輯渲染是基本不變的,這部分重復(fù)計(jì)算耗費(fèi)了帶寬、服務(wù)器資源,是比較沒(méi)有必要的。
          3. 用戶分布廣,網(wǎng)絡(luò)狀況難以保證,頭條的用戶量很大,覆蓋了各種運(yùn)營(yíng)商網(wǎng)絡(luò)和網(wǎng)絡(luò)狀態(tài),網(wǎng)絡(luò)質(zhì)量無(wú)法得到很好的保證。而 CDN 能夠?qū)?shù)據(jù)緩存在各地的邊緣節(jié)點(diǎn),用戶就近接入了邊緣節(jié)點(diǎn),避免在網(wǎng)絡(luò)質(zhì)量無(wú)法保證的公網(wǎng)上長(zhǎng)時(shí)間傳輸,從而提高了響應(yīng)速度和響應(yīng)的成功率。
          4. 接口數(shù)據(jù)大,由于正文數(shù)據(jù)的存在,接口返回的數(shù)據(jù)常常會(huì)很大,如果每一次都實(shí)時(shí)返回,對(duì)網(wǎng)絡(luò)的壓力會(huì)比較大,可能會(huì)把帶寬打滿而影響其他服務(wù)

          所以我們將詳情頁(yè)內(nèi)容數(shù)據(jù)分為靜態(tài)和動(dòng)態(tài)兩部分,將正文內(nèi)容、標(biāo)題、作者欄等用戶主要消費(fèi)的又基本不變的內(nèi)容托管到了 CDN 上。

          CDN 的全稱是 Content Delivery Network,即內(nèi)容分發(fā)網(wǎng)絡(luò)。其目的是通過(guò)在現(xiàn)有的 Internet 中增加一層新的網(wǎng)絡(luò)架構(gòu),將網(wǎng)站的內(nèi)容發(fā)布到最接近用戶的網(wǎng)絡(luò)“邊緣”,使用戶可以就近取得所需的內(nèi)容,提高用戶訪問(wèn)網(wǎng)站的響應(yīng)速度。CDN 有別于鏡像,因?yàn)樗如R像更智能,或者可以做這樣一個(gè)比喻:CDN=更智能的鏡像+緩存+流量導(dǎo)流。因而,CDN 可以明顯提高 Internet 網(wǎng)絡(luò)中信息流動(dòng)的效率。從技術(shù)上全面解決由于網(wǎng)絡(luò)帶寬小、用戶訪問(wèn)量大、網(wǎng)點(diǎn)分布不均等問(wèn)題,提高用戶訪問(wèn)網(wǎng)站的響應(yīng)速度。

          托管到 CDN 之后,全國(guó)各地的用戶可以直接從最佳節(jié)點(diǎn)就獲取到詳情頁(yè)數(shù)據(jù),也大大節(jié)省了帶寬成本。

          容災(zāi)

          1. 多域名備份

          為了防止某個(gè) CDN 出現(xiàn)故障,導(dǎo)致服務(wù)雪崩,服務(wù)端會(huì)下發(fā)多個(gè) CDN 鏈接,當(dāng)用戶訪問(wèn)當(dāng)前 CDN 節(jié)點(diǎn)的出異常時(shí),可以快速自動(dòng)切換到下個(gè) CDN 節(jié)點(diǎn)。

          2. 快速超時(shí)

          一般的超時(shí)策略,客戶端在請(qǐng)求時(shí),會(huì)遍歷請(qǐng)求 CDN 1、2、3。如果這些 CDN 都請(qǐng)求失敗,則整個(gè)網(wǎng)絡(luò)請(qǐng)求算作失敗。

          但這個(gè)方案的問(wèn)題是,假設(shè)請(qǐng)求 CDN 的超時(shí)時(shí)間是 15s。如果 CDN 1 出現(xiàn)故障,則需要等待 15s 才能切換到 CDN 2 上,這對(duì)于詳情頁(yè)的加載時(shí)間來(lái)說(shuō)是不可接受,如果用戶網(wǎng)絡(luò)突然變差,則需要等待 45s 才能返回失敗展示錯(cuò)誤頁(yè)。

          基于此我們?cè)O(shè)計(jì)了詳情頁(yè)請(qǐng)求的快速動(dòng)態(tài)超時(shí)策略

          • 單次請(qǐng)求 CDN 的超時(shí)時(shí)間,根據(jù)上次成功請(qǐng)求 CDN 的值計(jì)算,因子 1.5(z 值)。且最小為 1s(x 值),最大為 4s(y 值)。超過(guò)這一時(shí)間不取消,直接請(qǐng)求下個(gè) CDN。
          • 單次請(qǐng)求 CDN 有一個(gè)硬性超時(shí)時(shí)間 4s(w 值,w 需>=y),超過(guò)這一時(shí)間請(qǐng)求取消。n 個(gè) CDN 的請(qǐng)求全部取消后反饋用戶失敗。

          幾個(gè) case:

          • 第 1 個(gè) CDN 突然掛掉(假設(shè)上次成功請(qǐng)求的耗時(shí)為 a) 下一次請(qǐng)求:第一個(gè) CDN 很快超時(shí)(a _ 1.5);開(kāi)始請(qǐng)求第二個(gè) CDN(超時(shí)時(shí)間為 a _ 1.5,但實(shí)際上 b 秒就會(huì)返回請(qǐng)求)。用戶本次等待時(shí)間為 a _ 1.5 + b 下兩次請(qǐng)求:第一個(gè) CDN 很快超時(shí)(b _ 1.5);開(kāi)始請(qǐng)求第二個(gè) CDN(超時(shí)時(shí)間為 b _ 1.5,但實(shí)際 c 秒就會(huì)返回請(qǐng)求)。用戶本次等待時(shí)間為 b _ 1.5 + c

          • 用戶突然進(jìn)入了一個(gè)網(wǎng)絡(luò)很差的環(huán)境(假設(shè)上次成功請(qǐng)求的耗時(shí)為 a) 下一次請(qǐng)求:第一個(gè) CDN 很快超時(shí)(a _ 1.5);開(kāi)始請(qǐng)求第二個(gè) CDN(a _ 1.5)也超時(shí);開(kāi)始請(qǐng)求第三個(gè) CDN(a _ 1.5)。最后一個(gè)請(qǐng)求會(huì)在 a _ 3 + w 后返回失敗(這個(gè)值會(huì)在 12s 以內(nèi))。

          可以看到,通過(guò)多域名備份和快速超時(shí)的策略,即使用戶在網(wǎng)絡(luò)或者服務(wù)異常的情況下,也能快速恢復(fù)或者讓用戶能感知到自身網(wǎng)絡(luò)問(wèn)題。

          渲染優(yōu)化

          當(dāng)我們?cè)谀0鍖雍途W(wǎng)絡(luò)層優(yōu)化到極致的時(shí)候,限制我們的就是 WebView 的渲染速度了!

          服務(wù)端預(yù)渲染

          正常來(lái)講,正常的內(nèi)容數(shù)據(jù)可能是類似 JSON 等數(shù)據(jù),客戶端獲取到數(shù)據(jù)之后,將數(shù)據(jù)注入給前端,前端還需要將 JSON 數(shù)據(jù)跟模板進(jìn)行組裝,拼上 HTML 標(biāo)簽等模板了之后再呈現(xiàn)到 WebView 渲染,導(dǎo)致前端渲染上耗時(shí)也比較久。

          為了提高用戶的首屏效率,我們?cè)诜?wù)端就會(huì)把所有的詳情頁(yè)正文的 HTML 數(shù)據(jù)組裝好,通過(guò)將服務(wù)端直出內(nèi)容注入到頁(yè)面中時(shí),可以直接給 WebView 進(jìn)行渲染,對(duì)于其他動(dòng)態(tài)下發(fā)的內(nèi)容(比如相關(guān)搜索),前端再進(jìn)行二次異步處理,提升用戶效率。

          客戶端渲染

          一般來(lái)說(shuō),我們正文中所有內(nèi)容都是通過(guò) WebView 渲染,經(jīng)過(guò)上述的優(yōu)化之后,文章的文字部分渲染效率已經(jīng)很高了,但是實(shí)際場(chǎng)景中,很多文章會(huì)包含比較多的圖片和視頻場(chǎng)景。

          在實(shí)際場(chǎng)景中,WebView 渲染非文字內(nèi)容會(huì)存在以下問(wèn)題:

          1. 相比于文字內(nèi)容,非文字內(nèi)容比如說(shuō)圖片和視頻類資源的渲染對(duì)于 WebView 來(lái)說(shuō)渲染效率比較差
          2. 在詳情頁(yè)中文章有大量圖片的場(chǎng)景,對(duì)于 WebView 的渲染內(nèi)存占用和滑動(dòng)體驗(yàn)也有問(wèn)題
          3. 最后,如果用戶多次打開(kāi)同一篇文章,這篇文章中的圖片也會(huì)存在多次加載的問(wèn)題,無(wú)法與客戶端進(jìn)行緩存共享,對(duì)用戶的流量也是一種浪費(fèi)。

          所以在詳情頁(yè)中,我們會(huì)將圖片和視頻等非文字內(nèi)容通過(guò)原生組件的方式放在客戶端進(jìn)行渲染,既可以提高渲染效率,也可以減少不必要的流量消耗。

          原生化渲染還有一個(gè)好處,圖片越來(lái)越成為文章體驗(yàn)的重要部分,對(duì)于多圖文章,我們?cè)?Feed 頁(yè)面也可以智能加載詳情頁(yè)需要的圖片,增加用戶的文章首屏體驗(yàn)。

          白屏優(yōu)化

          講完了性能優(yōu)化,最后再分享一下我們對(duì)詳情頁(yè)白屏率的一些優(yōu)化,其實(shí)很多用戶反饋白屏問(wèn)題大部分都可能是由于網(wǎng)絡(luò)等問(wèn)題導(dǎo)致頁(yè)面加載時(shí)間過(guò)長(zhǎng),導(dǎo)致用戶從體驗(yàn)上觀感是白屏了,這部分通過(guò)上面分享的性能優(yōu)化手段已經(jīng)能夠解決,所以下面只是簡(jiǎn)單介紹下一些非網(wǎng)絡(luò)原因的白屏問(wèn)題。

          我們通過(guò)白屏檢測(cè)和上報(bào)之后的數(shù)據(jù)分析之后發(fā)現(xiàn),非網(wǎng)絡(luò)原因?qū)е碌脑斍轫?yè)的白屏問(wèn)題大體是 WebView 加載的問(wèn)題。

          在 iOS 中,我們使用的是系統(tǒng)提供的 WKWebView,WKWebView 是運(yùn)行在一個(gè)獨(dú)立進(jìn)程中的組件,所以當(dāng) WKWebView 上占用內(nèi)存過(guò)大時(shí),WKWebView 所在的 WebContent Process 會(huì)被系統(tǒng) kill 掉,反映在用戶體驗(yàn)上就是發(fā)生了白屏。

          根據(jù)網(wǎng)上的做法,我們可以在 WKWebView 提供的回調(diào) webViewWebContentProcessDidTerminate 函數(shù)中通過(guò) reload 方法重新加載當(dāng)前頁(yè)面恢復(fù),但是這種情況只適用于通過(guò) loadRequest 加載的請(qǐng)求,在詳情頁(yè)中,由于使用了模板化的 WebView 中,重新 reload 只能重新 reload 模板,并不能正常恢復(fù)整個(gè)詳情頁(yè),需要客戶端重新加載模板之后再重新注入數(shù)據(jù)。

          另外由于我們有預(yù)熱模板的邏輯,所以可能在進(jìn)入詳情頁(yè)的時(shí)候使用的 WKWebView 就已經(jīng)崩潰,在調(diào)用 JS 注入數(shù)據(jù)時(shí)會(huì)直接返回失敗,失敗時(shí),我們會(huì)嘗試重新加載模板。但后來(lái)實(shí)際操作中發(fā)現(xiàn)一個(gè)問(wèn)題,如果直接調(diào)用數(shù)據(jù)注入的方法,等待系統(tǒng) WebView 返回失敗的回調(diào)耗時(shí)比較久,所以后續(xù)也調(diào)整了數(shù)據(jù)注入的接口,我們提前在注入的腳本中判斷是否存在數(shù)據(jù)注入的接口,如果不存在,就說(shuō)明模板存在問(wèn)題,直接重試即可。

          而在 Android 中,我們采用的是自研內(nèi)核 WebView,也會(huì)遇到一些奇奇怪怪的坑。

          1. 多線程讀模板文件問(wèn)題,WebView 在運(yùn)行中會(huì)讀取的文件模板,如果此時(shí)另外一個(gè)線程同時(shí)更新模板文件時(shí),就出現(xiàn)了模板加載問(wèn)題,所以需要保證模板加載的原子性
          2. Render 卡死問(wèn)題,內(nèi)核是一個(gè)比較復(fù)雜的邏輯,內(nèi)部渲染極少數(shù)情況也會(huì)出現(xiàn) Render 卡死問(wèn)題,但是在詳情頁(yè)整體用戶的量級(jí)下,即使只有十萬(wàn)分之一的可能,對(duì)用戶來(lái)說(shuō)也是一個(gè)比較大的問(wèn)題,此時(shí)我們會(huì)從業(yè)務(wù)上做白屏監(jiān)控進(jìn)行重試

          當(dāng)然不管是 iOS 和 Android, WebView 加載的邏輯都比較復(fù)雜,有時(shí)候怎么重試也無(wú)法成功,這個(gè)時(shí)候我們會(huì)直接降級(jí)到加載線上的詳情頁(yè),優(yōu)先保證用戶的體驗(yàn)。

          總結(jié)

          限于篇幅原因,我們還做了很多其他事情,包括請(qǐng)求精簡(jiǎn),push 文章預(yù)拉取,數(shù)據(jù)注入的方式優(yōu)化等等,也做了很多其他的方向的探索,這里不做展開(kāi),希望有機(jī)會(huì)能再分享給大家。

          最后總結(jié)一下我們?cè)趦?yōu)化詳情頁(yè)打開(kāi)速度之后的一些想法

          • 數(shù)據(jù)很重要,我們?cè)趦?yōu)化加載速度之前做的第一件事情其實(shí)是建立了一個(gè)詳情頁(yè)的數(shù)據(jù)看板,只有通過(guò)數(shù)據(jù)我們才能真正了解目前線上用戶的現(xiàn)狀,從真實(shí)用戶的體驗(yàn)中找到瓶頸和優(yōu)化點(diǎn)。
          • 用戶體驗(yàn)優(yōu)先,優(yōu)化方案有很多,除了加載速度之外,還需要從整體應(yīng)用體驗(yàn)出發(fā),選擇對(duì)用戶最佳的方案
          • 追求極致,其實(shí)最開(kāi)始的優(yōu)化是比較簡(jiǎn)單的,但是越到后面越難,需要一點(diǎn)點(diǎn)摳細(xì)節(jié),才能達(dá)到極致的用戶體驗(yàn)

          更多分享

          Android Camera 內(nèi)存問(wèn)題剖析

          字節(jié)跳動(dòng)自研線上引流回放系統(tǒng)的架構(gòu)演進(jìn)

          iOS大解密:玄之又玄的KVO

          Android '秒' 級(jí)編譯速度優(yōu)化

          技術(shù)團(tuán)隊(duì)

          技術(shù)團(tuán)隊(duì)不僅致力于在業(yè)務(wù)上不斷深耕挖掘,在技術(shù)上也一直在追求極致的用戶體驗(yàn)。

          如果你也向往在一個(gè)億級(jí) DAU 業(yè)務(wù)里成長(zhǎng),也期待在技術(shù)上有突飛猛進(jìn)的提升,歡迎你加入我們。

          無(wú)論你是 iOS/Android/前端/后端,我們?cè)谏钲?北京/廣州等你來(lái),一起做更有挑戰(zhàn)的事!簡(jiǎn)歷投遞郵箱: tech@bytedance.com ;郵件標(biāo)題:姓名-工作年限-頭條技術(shù)團(tuán)隊(duì)


          歡迎關(guān)注字節(jié)跳動(dòng)技術(shù)團(tuán)隊(duì)

          題:頭條HTML提取失敗的背后:挑戰(zhàn)、創(chuàng)新與數(shù)據(jù)獲取的新紀(jì)元

          在數(shù)字化浪潮的洶涌推動(dòng)下,信息的獲取與利用已不僅僅是技術(shù)的較量,更是策略與智慧的碰撞。當(dāng)我們?cè)趪L試從各大平臺(tái),如頭條,提取HTML內(nèi)容時(shí)遭遇失敗,這不僅僅是一個(gè)簡(jiǎn)單的技術(shù)難題,更是對(duì)當(dāng)前數(shù)據(jù)生態(tài)、技術(shù)局限以及未來(lái)發(fā)展方向的一次深刻反思。本文將從這一現(xiàn)象出發(fā),探討其背后的深層次原因,提出應(yīng)對(duì)策略,并展望數(shù)據(jù)獲取領(lǐng)域的新紀(jì)元。

          一、現(xiàn)象透視:HTML提取失敗的深層含義

          在表面看來(lái),HTML提取失敗似乎只是一個(gè)技術(shù)障礙,實(shí)則不然。它映射出的是當(dāng)前網(wǎng)絡(luò)環(huán)境日益復(fù)雜、數(shù)據(jù)保護(hù)意識(shí)增強(qiáng)的現(xiàn)實(shí)。隨著《數(shù)據(jù)安全法》、《個(gè)人信息保護(hù)法》等法律法規(guī)的出臺(tái),數(shù)據(jù)的合規(guī)性、安全性成為不可逾越的紅線。同時(shí),各大平臺(tái)為了保護(hù)用戶隱私、維護(hù)數(shù)據(jù)主權(quán),也在不斷升級(jí)防護(hù)措施,這使得傳統(tǒng)的數(shù)據(jù)抓取手段面臨前所未有的挑戰(zhàn)。

          二、挑戰(zhàn)與反思:技術(shù)、法律與倫理的多重考驗(yàn)

          技術(shù)挑戰(zhàn):隨著網(wǎng)絡(luò)技術(shù)的發(fā)展,平臺(tái)反爬蟲(chóng)技術(shù)日益成熟,傳統(tǒng)的HTTP請(qǐng)求、解析HTML等技術(shù)手段已難以滿足需求。如何在不違反法律法規(guī)的前提下,有效、高效地獲取所需數(shù)據(jù),成為亟待解決的問(wèn)題。

          法律風(fēng)險(xiǎn):數(shù)據(jù)抓取行為極易觸及法律紅線,如侵犯著作權(quán)、非法獲取個(gè)人信息等。因此,在進(jìn)行數(shù)據(jù)抓取前,必須深入研究相關(guān)法律法規(guī),確保操作合法合規(guī)。

          倫理考量:數(shù)據(jù)的價(jià)值在于流動(dòng)與共享,但這一過(guò)程必須建立在尊重用戶隱私、維護(hù)數(shù)據(jù)主權(quán)的基礎(chǔ)上。因此,在追求數(shù)據(jù)價(jià)值的同時(shí),必須堅(jiān)守倫理底線,避免數(shù)據(jù)濫用。

          三、應(yīng)對(duì)策略:創(chuàng)新驅(qū)動(dòng),多維發(fā)展

          技術(shù)創(chuàng)新:加大研發(fā)投入,探索新的數(shù)據(jù)抓取技術(shù),如基于人工智能的模擬用戶行為、深度學(xué)習(xí)等技術(shù)手段,以提高數(shù)據(jù)抓取的效率和準(zhǔn)確性。同時(shí),加強(qiáng)跨領(lǐng)域合作,引入計(jì)算機(jī)科學(xué)、法律、倫理等多學(xué)科知識(shí),形成合力解決難題。

          合規(guī)建設(shè):建立健全數(shù)據(jù)抓取與使用的合規(guī)體系,明確數(shù)據(jù)抓取的范圍、目的、方式及安全保護(hù)措施。加強(qiáng)員工培訓(xùn),提高員工對(duì)法律法規(guī)的認(rèn)識(shí)和遵守意識(shí)。

          倫理引導(dǎo):樹(shù)立正確的數(shù)據(jù)觀和倫理觀,引導(dǎo)企業(yè)和個(gè)人在數(shù)據(jù)抓取和使用過(guò)程中遵守道德規(guī)范,尊重用戶隱私和數(shù)據(jù)主權(quán)。通過(guò)社會(huì)輿論、行業(yè)自律等方式,形成良好的數(shù)據(jù)生態(tài)環(huán)境。

          四、未來(lái)展望:數(shù)據(jù)獲取的新紀(jì)元

          隨著技術(shù)的不斷進(jìn)步和法律法規(guī)的日益完善,數(shù)據(jù)獲取領(lǐng)域?qū)⒂瓉?lái)新的發(fā)展機(jī)遇。未來(lái),我們將看到更加智能化、高效化、合規(guī)化的數(shù)據(jù)抓取工具的出現(xiàn),它們將能夠在保障用戶隱私和數(shù)據(jù)安全的前提下,滿足各類用戶對(duì)數(shù)據(jù)的需求。同時(shí),隨著區(qū)塊鏈、分布式賬本等新技術(shù)的發(fā)展,數(shù)據(jù)的溯源、驗(yàn)證和共享將更加便捷和透明,為數(shù)據(jù)經(jīng)濟(jì)的發(fā)展提供強(qiáng)有力的支撐。

          總之,頭條HTML提取失敗雖是一個(gè)具體的技術(shù)難題,但它卻引發(fā)了我們對(duì)數(shù)據(jù)獲取領(lǐng)域的深刻反思。在未來(lái)的發(fā)展中,我們必須堅(jiān)持創(chuàng)新驅(qū)動(dòng)、合規(guī)建設(shè)和倫理引導(dǎo)相結(jié)合的原則,共同推動(dòng)數(shù)據(jù)獲取領(lǐng)域向更加健康、可持續(xù)的方向發(fā)展。

          數(shù)字迷霧中:頭條HTML提取的挫敗與深思

          在今日這個(gè)數(shù)據(jù)洪流不息的時(shí)代,每一秒都有無(wú)數(shù)信息如潮水般涌來(lái),我們?nèi)缤驹谛畔⒌暮0哆叄噲D捕捉那些對(duì)我們有價(jià)值的浪花。然而,當(dāng)我們的手伸向“頭條”這片信息海洋,試圖提取其HTML內(nèi)容的珍珠時(shí),卻遭遇了前所未有的挫敗。這不僅僅是一次簡(jiǎn)單的技術(shù)挑戰(zhàn),更是一次對(duì)數(shù)字時(shí)代信息獲取方式的深刻反思。

          一、迷霧中的探索:技術(shù)挑戰(zhàn)與規(guī)則迷宮

          在嘗試揭開(kāi)頭條HTML內(nèi)容的神秘面紗時(shí),我們?cè)庥隽饲八从械淖璧K。這不禁讓人思考,是技術(shù)的瓶頸限制了我們的探索,還是隱藏在背后的規(guī)則迷宮讓我們迷失了方向?

          從技術(shù)層面剖析,HTML內(nèi)容的提取本應(yīng)是爬蟲(chóng)技術(shù)的拿手好戲,它們?nèi)缤W(wǎng)絡(luò)世界的探險(xiǎn)家,穿梭于各個(gè)網(wǎng)站之間,搜集著寶貴的數(shù)據(jù)。然而,隨著反爬蟲(chóng)技術(shù)的日益精進(jìn),這些探險(xiǎn)家們不得不面對(duì)更加復(fù)雜多變的挑戰(zhàn)。頭條,作為信息領(lǐng)域的巨擘,其反爬蟲(chóng)機(jī)制無(wú)疑也是行業(yè)內(nèi)的佼佼者。我們的嘗試,或許正是撞上了這堵由技術(shù)構(gòu)建的堅(jiān)固城墻。

          但另一方面,我們也不能忽視規(guī)則的力量。在這個(gè)信息即財(cái)富的時(shí)代,各大平臺(tái)對(duì)于自身內(nèi)容的保護(hù)意識(shí)日益增強(qiáng)。頭條等平臺(tái)通過(guò)設(shè)置嚴(yán)格的規(guī)則體系,來(lái)確保內(nèi)容的合法使用和傳播。我們的失敗,或許正是因?yàn)闆](méi)有遵循這些規(guī)則,而觸動(dòng)了平臺(tái)的敏感神經(jīng)。

          二、挫敗后的覺(jué)醒:尊重與合作的新視角

          面對(duì)這次挫敗,我們不應(yīng)僅僅停留在沮喪和懊惱之中,而應(yīng)從中汲取教訓(xùn),開(kāi)啟新的視角。首先,我們要深刻認(rèn)識(shí)到尊重規(guī)則的重要性。在這個(gè)法治社會(huì),任何行為都應(yīng)在法律和規(guī)則的框架內(nèi)進(jìn)行。對(duì)于平臺(tái)的內(nèi)容,我們更應(yīng)保持敬畏之心,遵循其使用規(guī)則,避免觸碰法律的紅線。

          其次,我們要積極尋求與平臺(tái)的合作機(jī)會(huì)。在信息共享的時(shí)代背景下,合作已成為不可逆轉(zhuǎn)的趨勢(shì)。我們可以嘗試與頭條等平臺(tái)建立聯(lián)系,共同探討數(shù)據(jù)共享和使用的可能性。通過(guò)合法合規(guī)的途徑獲取數(shù)據(jù),不僅能夠保障數(shù)據(jù)的真實(shí)性和可靠性,還能夠?yàn)殡p方帶來(lái)更多的合作機(jī)會(huì)和共贏的可能。

          三、展望未來(lái):技術(shù)革新與規(guī)則進(jìn)化的交響曲

          雖然這次挫敗讓我們暫時(shí)停下了腳步,但我們也應(yīng)看到前方的希望。隨著技術(shù)的不斷進(jìn)步和規(guī)則的日益完善,我們有理由相信未來(lái)的信息獲取將更加便捷和高效。

          在技術(shù)層面,我們可以期待更加智能和先進(jìn)的爬蟲(chóng)技術(shù)的出現(xiàn)。這些技術(shù)將能夠更好地應(yīng)對(duì)各種反爬蟲(chóng)措施的挑戰(zhàn),為我們提供更加全面和準(zhǔn)確的數(shù)據(jù)支持。同時(shí),隨著人工智能技術(shù)的不斷發(fā)展,我們或許還能夠開(kāi)發(fā)出更加智能化的信息分析工具,幫助我們更好地理解和利用這些數(shù)據(jù)。

          在規(guī)則層面,我們可以預(yù)見(jiàn)各大平臺(tái)將不斷完善自己的規(guī)則體系。這些規(guī)則將更加明確和具體地規(guī)定內(nèi)容的使用方式和限制條件,為數(shù)據(jù)的合法共享和使用提供更好的保障。同時(shí),隨著人們對(duì)數(shù)據(jù)隱私和版權(quán)的重視程度不斷提高,我們也應(yīng)積極參與相關(guān)規(guī)則的制定和完善工作,為構(gòu)建一個(gè)更加健康、有序的信息環(huán)境。

          這次頭條HTML提取的挫敗經(jīng)歷雖然讓我們暫時(shí)受挫,但也為我們提供了寶貴的反思和成長(zhǎng)機(jī)會(huì)。我們不僅要看到技術(shù)的局限性和規(guī)則的約束性,更要從中汲取教訓(xùn)、總結(jié)經(jīng)驗(yàn)、尋找新的出路。在未來(lái)的道路上,我們將以更加開(kāi)放的心態(tài)和敏銳的洞察力去迎接挑戰(zhàn)、把握機(jī)遇、創(chuàng)造更加美好的未來(lái)。


          主站蜘蛛池模板: 亚洲福利视频一区二区| 一区二区3区免费视频| 亚洲国产一区二区三区| 91精品福利一区二区三区野战| 国产日韩AV免费无码一区二区三区| 亚洲精品精华液一区二区| 亚洲AV无码一区东京热| 国产亚洲自拍一区| 久久国产精品免费一区| 精品一区二区三区视频在线观看| 成人精品一区二区三区校园激情| 亚洲国产一区二区a毛片| 久久免费区一区二区三波多野| 熟女少妇精品一区二区| 国产精品男男视频一区二区三区 | 亚洲av无一区二区三区| 视频一区二区精品的福利| 蜜臀AV无码一区二区三区| 国产免费一区二区三区| 91在线精品亚洲一区二区| 亚洲午夜在线一区| 国产麻豆精品一区二区三区| 最新欧美精品一区二区三区| 色综合视频一区二区三区44| 天堂一区人妻无码| 美女免费视频一区二区三区| 一区精品麻豆入口| 一区二区三区在线免费观看视频| 亚州国产AV一区二区三区伊在| 久久久久人妻精品一区三寸| 欧洲精品一区二区三区| 亚洲欧洲∨国产一区二区三区| 成人乱码一区二区三区av| 国产午夜福利精品一区二区三区| 在线免费视频一区| 一区二区高清在线观看| 国产精品特级毛片一区二区三区| 国产爆乳无码一区二区麻豆| 日本一区频道在线视频| 国产在线一区观看| a级午夜毛片免费一区二区|