日本综合一区二区|亚洲中文天堂综合|日韩欧美自拍一区|男女精品天堂一区|欧美自拍第6页亚洲成人精品一区|亚洲黄色天堂一区二区成人|超碰91偷拍第一页|日韩av夜夜嗨中文字幕|久久蜜综合视频官网|精美人妻一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
淺談Web容器設(shè)計(jì)的邊界和目標(biāo)

就歷史沉淀而言,UC是做瀏覽器的,在對Webview優(yōu)化上的積累自然也是最多。由于UC有對瀏覽器內(nèi)核有定制優(yōu)化的能力,很多時(shí)候?qū)eb的優(yōu)化和問題從前端側(cè)可能是很難找原因,但從內(nèi)核的“上帝視角”卻很容易找到思路和解法。在瀏覽器里面做業(yè)務(wù),只要沒有超過Web容器的能力范圍,我們一般會(huì)優(yōu)先考慮用Web技術(shù)來滿足業(yè)務(wù)的訴求。

當(dāng)然,要想準(zhǔn)確把握Webview的能力范圍并不是件容易的事,而不同人或團(tuán)隊(duì)對于Webview能力邊界的理解也是不太一樣的。當(dāng)我們在討論一項(xiàng)技術(shù)的邊界時(shí),關(guān)鍵的不是了解該技術(shù)能做好什么,而是知道它做不好什么。

注意,說的是做不好,不是做不了。很多時(shí)候,我們所說的“做不好”指的是,達(dá)不到最優(yōu)秀的用戶體驗(yàn),通常與使用Native并經(jīng)過優(yōu)化后的效果進(jìn)行對比。在用戶體驗(yàn)競爭越來越激烈的情況下,每個(gè)產(chǎn)品都期望能用最好的天花板最高的技術(shù)來落地。

但在現(xiàn)實(shí)的技術(shù)方案設(shè)計(jì)中,除了考慮技術(shù)所能達(dá)到的最優(yōu)效果外,還需要綜合考慮開發(fā)成本、開發(fā)周期、維護(hù)效率、線上風(fēng)險(xiǎn)等因素,以及根據(jù)業(yè)務(wù)發(fā)展、人力資源配置情況,綜合考慮后最終選擇一個(gè)ROI最高的方案。

好了,方案選擇的路徑不是這里討論的重點(diǎn),還是來聊聊動(dòng)態(tài)容器吧。下面筆者將列舉一些典型的用Webview技術(shù)的Cover起來有難度的場景。

Web 容器的邊界場景

一、復(fù)雜的媒體播控

1. 視頻播控

并不是說Webview(H5)、小程序處理不了視頻,而是對于視頻的細(xì)節(jié)處理不夠好。我們都知道web原生的video播放控件功能單一,沒有快進(jìn)/退、倍速、音量調(diào)節(jié)、亮度調(diào)節(jié)、對緩沖無感知等問題。此外,動(dòng)態(tài)容器處理視頻還有以下常見問題:

  • 自動(dòng)播放控制:主要是iOS的限制,在webview內(nèi)的video標(biāo)簽需要用戶的許可,因此雙端自動(dòng)播放邏輯是不一致的。在iOS上為了解決自動(dòng)播放的問題,通常在body上綁一個(gè)video的play事件,用戶觸碰一下頁面就代表授權(quán)了,但這解法其實(shí)挺雞賊的,并不能代表用戶的真實(shí)意愿。
  • 播放時(shí)長統(tǒng)計(jì):video播放時(shí)長統(tǒng)計(jì)是業(yè)務(wù)和算法的需要,如果前端業(yè)務(wù)開發(fā)者來做video播放時(shí)間統(tǒng)計(jì)會(huì)存在,在點(diǎn)擊播放時(shí)視頻資源才開始下載,什么時(shí)候視頻開始起播基本完全靠估算,播放過程中網(wǎng)絡(luò)緩沖時(shí)間也可能被統(tǒng)計(jì)到播放時(shí)長內(nèi),因此時(shí)長統(tǒng)計(jì)由前端業(yè)務(wù)來完成非常容易帶來統(tǒng)計(jì)誤差,業(yè)務(wù)往往是不可接受的。
  • 封面無縫切視頻:由于video真正的播放視頻時(shí)間(起播時(shí)間)不精確,也帶來視頻的封面圖片替換為視頻播放畫面的過渡體感會(huì)比較生硬,如果點(diǎn)擊播放后立刻將封面圖片替換掉,而這時(shí)視頻還在加載就會(huì)出現(xiàn)黑屏效果,體感不ok。
  • 播控面板UI定制:在webview內(nèi)對video的UI調(diào)整也是有難度的事情,常見的實(shí)現(xiàn)是先隱藏原生video的控制條,然后在video上覆蓋一層自定義UI,接著在自定UI上通過事件的方式來控制底下的video。這樣的封裝有很多開源的方案,但整體體驗(yàn)與Native定制的播放器有很大落差,在自有App內(nèi)幾乎不會(huì)用,站外分享才會(huì)考慮這類方案,實(shí)際也是一個(gè)不得已的選擇。
  • 多視頻播控:如果在一個(gè)頁面中存在多個(gè)視頻,在播放其中視頻時(shí),需要對其他視頻進(jìn)行暫?;蜾N毀處理;如果這是一個(gè)視頻長列表,產(chǎn)品期望根據(jù)用戶滾動(dòng)的位置實(shí)現(xiàn)視頻的自動(dòng)播控,那么多視頻問題會(huì)更復(fù)雜,因此很少看到有業(yè)務(wù)使用動(dòng)態(tài)技術(shù)構(gòu)建包含視頻自動(dòng)播控的長列表業(yè)務(wù)。在這個(gè)場景,技術(shù)要么native,要么flutter。

包含多視頻的長列表滾動(dòng)到可視范圍內(nèi)自動(dòng)播放,技術(shù)以native/flutter為主

當(dāng)然,webview處理video帶來的細(xì)節(jié)體驗(yàn)問題還有不少,有一些問題通過native托管可以有效解決。在各大App自有業(yè)務(wù)內(nèi),對Webview的video播放器的優(yōu)化基本都走native托管的模式,在技術(shù)實(shí)現(xiàn)上叫混合渲染或同層渲染。

2. 音頻播控

音頻媒體資源的播控問題與video是類似的,webview內(nèi)的audio標(biāo)簽也存在功能單一,沒有快進(jìn)/退、倍速、音量調(diào)節(jié)、對緩沖無感知等問題。

在我們的業(yè)務(wù)中涉及的音頻播控場景比較少,目前為止包含音頻播控的場景主要是圖文的語音播報(bào)功能,由于需要對音頻播控在App?;钇陂g全局生效,音頻播控的落地頁面自然不能使用h5的audio標(biāo)簽來處理TTS音頻,而是對接Native自定義的語音控制事件體系,頁面則繪制一個(gè)播控音頻的UI面板。

目前,針對音頻播控的訴求行業(yè)主要方案是Native base,F(xiàn)lutter實(shí)現(xiàn)應(yīng)該也沒問題,Web的實(shí)現(xiàn)相對較少。目前,我們已完成了此場景Web化,這里需要解決的邊界問題是在后臺(tái)模式下的頁面?;詈蜕芷谕卣?。

3. 動(dòng)圖播控

動(dòng)圖包括gif、apng、webp等,在動(dòng)態(tài)容器只有img標(biāo)簽一種圖片處理方式,在一些動(dòng)圖很多的場景,就很難實(shí)現(xiàn)對動(dòng)圖的播放有效控制。例如:

  • 多宮格圖片的順序播放:由于不知道動(dòng)圖什么時(shí)候播放完成,在多宮格的動(dòng)圖列表中需要等待上一個(gè)動(dòng)圖播完再接著播下一個(gè)的需求是無法用現(xiàn)有img標(biāo)簽來實(shí)現(xiàn)的。在業(yè)界碰到類似的問題,如果非要用web的方式解決,往往將動(dòng)圖轉(zhuǎn)化為video來處理,或者就直接標(biāo)記為“動(dòng)圖”讓用戶自己點(diǎn)擊播放。

實(shí)際上,業(yè)務(wù)需要?jiǎng)訄D播放可控的功能,要解決的實(shí)際問題是動(dòng)圖可以逐幀暫停/播放、播放開始和結(jié)束都有對應(yīng)的事件,也就是需要一個(gè)功能完備的動(dòng)圖播放器,而不只是用封面替換動(dòng)圖來模擬實(shí)現(xiàn)暫停而又不知道最后一幀啥時(shí)候完成的半成品。

目前針對動(dòng)圖進(jìn)行有序播控的訴求,我們采用的是Flutter方案,本質(zhì)是Native的實(shí)現(xiàn),而在Webview容器內(nèi)可以通過類似視頻播放器一樣,通過同層渲染技術(shù)實(shí)現(xiàn)對動(dòng)圖的逐幀播控。

二、高性能的長列表

1. 長列表的性能問題

在Web容器下,性能是長列表面臨的最棘手問題。問題會(huì)表現(xiàn)為:

  • 在不停下拉滾動(dòng)的過程中,當(dāng)列表插入的頁面節(jié)點(diǎn)越來越多,則會(huì)導(dǎo)致滑動(dòng)越來越卡頓(掉幀);
  • 如果列表內(nèi)容過多而不做 DOM 節(jié)點(diǎn)回收或分頁處理,頁面的內(nèi)存可能占用過大,進(jìn)而導(dǎo)致頁面或 App 崩潰;
  • 在做了頁面節(jié)點(diǎn)回收后會(huì)導(dǎo)致在快速滑動(dòng)的過程中,頁面節(jié)點(diǎn)回收而Dom渲染速度跟不上滾動(dòng)的速度,而導(dǎo)致用戶有明顯的白屏體感。

2. 行業(yè)方案分析

對于這些問題,前端業(yè)界有很多解決方案,解決思路大致兩個(gè)方向:

  • 針對圖片過多

圖片過多,這是引起性能問題的最常見因素,因此在有大量圖片的頁面中,我們都會(huì)使用 lazyload 的方式按需加載圖片,長列表的場景也是一樣的。

  • 針對節(jié)點(diǎn)過多

業(yè)界普遍的解決方案是虛擬長列表,根據(jù)列表容器的可視范圍,動(dòng)態(tài)計(jì)算出在可視范圍內(nèi)的列表節(jié)點(diǎn) item,然后只渲染視野邊界內(nèi)容的 item,通過控制頁面節(jié)點(diǎn)數(shù)避免內(nèi)存線性增加。

在具體的實(shí)現(xiàn)方案中,目前行業(yè)方案有:

  • 給列表容器設(shè)置 height 或 padding 值撐開容器: react-virtualized& vue-virtual-scroll-list
  • 通過 transform 對列表 item 進(jìn)行位置偏移,同時(shí)用一個(gè)影子容器來實(shí)現(xiàn)滾動(dòng)條的模擬:ngx-virtual-scroller
  • 小程序方案:微信小程序recycle-view、taro虛擬列表

當(dāng)然,還有很多,這里就不再一一列舉。

以上的幾種方案有所差異,但設(shè)計(jì)理念基本類似。在實(shí)際的業(yè)務(wù)場景中,當(dāng)容器內(nèi)的每個(gè) item 高度是動(dòng)態(tài)的(等高的計(jì)算邏輯相對沒那么復(fù)雜,這里不討論),在虛擬列表頁面節(jié)點(diǎn)數(shù)量增多的過程,背后存在大量的js邏輯計(jì)算:

  • 在計(jì)算可視范圍內(nèi)的 item 內(nèi)容時(shí),必須需要循環(huán)遍歷每個(gè) item,獲得其相對于可視窗口的偏移量,進(jìn)而計(jì)算出需要展示的 item,以完成虛擬列表布局的需要。
  • 容器的外部高度是需要在滾動(dòng)過程中,不停的進(jìn)行動(dòng)態(tài)計(jì)算并進(jìn)行重新渲染,也就是整個(gè)列表中內(nèi)部每個(gè)元素,在滾動(dòng)過程中是時(shí)時(shí)刻刻都產(chǎn)生超過可視范圍的區(qū)塊重繪。

由于獲取Dom元素的真實(shí)高度需渲染完成后才能獲得(相對Native或Flutter可以在元素layout的過程,通過layoutBuilder的回調(diào)就可以獲取其高度,無需等待元素渲染上屏),導(dǎo)致js計(jì)算列表元素高度需要等待Dom渲染,進(jìn)而到帶來不可避免的時(shí)間差。

因此,在頁面快速滾動(dòng)的過程中,虛擬長列表在回收節(jié)點(diǎn)計(jì)算的過程,由于高度計(jì)算的處理邏輯需要等到Dom上屏之后,如果頁面滾動(dòng)速度越快,計(jì)算量也就越大,等待Dom上屏的時(shí)間間隔就越大,一旦頁面的滾動(dòng)速度超過一定閾值,必然出現(xiàn)可視區(qū)域內(nèi)UI的變化速度 > 渲染速度的問題,就會(huì)表現(xiàn)為快速滾動(dòng)的頁面閃白。

3. 閃白無法量化

實(shí)際上,滾動(dòng)的白屏問題是虛擬列表的節(jié)點(diǎn)被回收后引入的新問題,是一個(gè)用戶的體感問題。在這里筆者用可視區(qū)域內(nèi)的UI變化速度 > 渲染速度只是技術(shù)用語上的表述,尷尬的是從純技術(shù)的角度這是 一個(gè)很難用數(shù)據(jù)進(jìn)行量化的問題 。why?

首先,這是一個(gè)新問題。

如果我們沒有對頁面節(jié)點(diǎn)進(jìn)行回收,那么就不存在滾動(dòng)路徑上頁面沒內(nèi)容的情況,也就沒有所謂的閃白問題。但不做節(jié)點(diǎn)回收就意味著在一個(gè)超長或無限下拉的列表中,DOM 節(jié)點(diǎn)會(huì)線性增大,必然導(dǎo)致頁面占用越來越多的內(nèi)存,增加更多的排版耗時(shí),進(jìn)而影響頁面性能和用戶操控體感。

其次,為何無法數(shù)據(jù)量化?

因?yàn)樵?Webview 內(nèi),前端并不知道當(dāng)前頁面滾動(dòng)速度是多少(或者在前端不能準(zhǔn)確地用數(shù)據(jù)的方式表達(dá)),滾動(dòng)曲線和滾動(dòng)加速度在不同的手機(jī)和平臺(tái)上也是不盡相同的,因此在不同手機(jī)上發(fā)生白屏的滾動(dòng)速度閾值是不一樣的。

4. 規(guī)避快滑閃白

那么,為了平衡快速滾動(dòng)的閃白問題,可以讓容器可以對頁面在滾動(dòng)速度的上限進(jìn)行限制,這個(gè)需要客戶端容器側(cè)來處理。

很多前端開發(fā)者應(yīng)該都知道,在老舊 iOS 系統(tǒng)上,如果 WebView 采用的 UIView 架構(gòu),由于 UIView 和 js 運(yùn)行在同一個(gè)線程,導(dǎo)致在 UIView 滾動(dòng)時(shí)會(huì)阻塞 js 執(zhí)行,因此在 UIView 的容器內(nèi)虛擬長列表快速滾動(dòng)帶來的白屏問題是不可避免的,好在現(xiàn)在的 iOS 系統(tǒng)基本上已升級為異步線程模式的 WKWebView 了。

目前,WKWebView 容器滾動(dòng)的慣性速度和加速度的上限默認(rèn)是比安卓的要低一些的(這也只是筆者對雙平臺(tái)的滾動(dòng)對比的體感,沒有量化的數(shù)據(jù)),而且iPhone手機(jī)性能通常比較好,因此虛擬長列表頁面在快速滾動(dòng)中,iOS閃白體感不那么明顯。

由于安卓的 WebView 容器在快速滾動(dòng)情況下,頁面會(huì)擁有很高的慣性速度和加速度。在極端滾動(dòng)操控下,比如直接觸控拖拽滾動(dòng)條(參考以上的視頻)或通過window.scrollTo 快速定位到某個(gè)位置,JS 邏輯還來不及計(jì)算當(dāng)前滾動(dòng)到的可視區(qū)域所需展示的 item 內(nèi)容時(shí),頁面就已滾過了該區(qū)域,閃白問題幾乎是不可避免的。

而針對極端操控的閃白問題,可以在安卓的Web容器側(cè)禁用滾動(dòng)條的拖拽功能來規(guī)避,這并沒有在根本上解決問題,但是webview這種機(jī)制不一定全是缺點(diǎn),在大多數(shù)場景下,普通速度滑動(dòng)h5的列表滑動(dòng)也是很順暢的,基本也感覺不到白屏,而技術(shù)角度看webview內(nèi)存占用會(huì)比flutter低,這其實(shí)也是一種優(yōu)勢。

5. 長列表的優(yōu)化思路

如果業(yè)務(wù)上,不得不使用長列表,在前端的優(yōu)化技巧層也是有一些方式方法的。

比如,讓列表渲染的 item 不只是可視范圍內(nèi)的 item,而是會(huì)在上下邊界部分預(yù)留足夠的buffer,這樣可以緩解問題。在雙端的具體優(yōu)化策略上,雙端冗余buffer也可以做差異處理。在上下邊界的冗余 item 數(shù)量,iOS 可以冗余少一些(性能好,但內(nèi)存少),而安卓則多一些(設(shè)備內(nèi)存大,就多占內(nèi)存)。

或者,在需要?jiǎng)討B(tài)計(jì)算列表高度的時(shí)候?qū)⑦^程簡化,比如原來需要每一個(gè)參與布局的列表item都需要計(jì)算一次,是否可以采用“分組計(jì)算”的策略,例如10個(gè)item分為1組,回收節(jié)點(diǎn)也是按組進(jìn)行,這樣回收算法的復(fù)雜度就可能只有原來的1/10。

6. 邊界的選擇

不管對長列表采用怎樣的dom節(jié)點(diǎn)回收技術(shù),都必定會(huì)面臨在用戶極端操控下 UI 的變化速度 > 渲染速度問題,在現(xiàn)有的瀏覽器JS執(zhí)行必然阻塞Dom渲染的模型下,而且Webview內(nèi)核層面定義沒有透露更多的動(dòng)態(tài)渲染處理API之前,此問題暫時(shí)沒有徹底的解法。在對用戶體驗(yàn)較高的長列表場景,我們傾向于選擇Flutter,如果是一級核心場景,主流方案還是Native。

當(dāng)然,問題雖如此,這并不意味在h5長列表中對非可視區(qū)域的節(jié)點(diǎn)進(jìn)行回收是個(gè)不必要的設(shè)計(jì),畢竟極速滾動(dòng)的閃白還是一個(gè)比較極端場景,很多時(shí)候產(chǎn)品對于用戶的體驗(yàn)并不沒有那么特別苛刻?;蛟S也不應(yīng)該那么苛刻,特別是人力有限的情況下,畢竟也要綜合考慮ROI,但開發(fā)者最好要知道技術(shù)邊界在哪里,避免掉坑里。

三、復(fù)雜的視差互動(dòng)

視差互動(dòng)(Parallax Effect)或滾動(dòng)(Parallax Scrolling)指操控網(wǎng)頁滾動(dòng)過程中,同時(shí)實(shí)現(xiàn)多個(gè)元素以不同的速度移動(dòng),形成立體的運(yùn)動(dòng)效果以提供出色的視覺體驗(yàn)。

1. 視差互動(dòng)的案例分析

先來看看兩個(gè)真實(shí)業(yè)務(wù)場景的栗子(視頻):

以上視頻的栗子是Flutter實(shí)現(xiàn)的視差效果,含有兩種視差:

  • 往上推,logo需要根據(jù)上推手勢同步縮??;
  • 切換tab,當(dāng)前高亮的tab背景和top橫線需要同步跟隨手勢變換。

如果用H5的方式來做這個(gè)需求,這兩個(gè)效果是做不到滑動(dòng)操控和UI變換的那種順滑體感。這個(gè)本質(zhì)原因是js是單線程的,當(dāng)js在執(zhí)行時(shí)DOM渲染會(huì)被阻塞,一幀內(nèi)要做多件事情就可能會(huì)出現(xiàn)掉幀,所以做不到絲滑體感。

以上的栗子是基于Flutter實(shí)現(xiàn)的視差,是目前比較常見的視頻播控落地頁的交互模式。在這個(gè)業(yè)務(wù)場景中是一個(gè)可以橫向切換的多頁容器,同時(shí)每個(gè)播放頁面又是一個(gè)可上下滾動(dòng)的嵌套容器:

  • 頁面整體可以上下滾動(dòng),而下方的評論區(qū)塊則在視頻縮放到最小后可以繼續(xù)局部滾動(dòng);
  • 視差效果則是上推視頻容器區(qū)塊同步縮小,播放器也隨著可播區(qū)塊的縮小而跟隨縮??;下拉,則反之。

這個(gè)栗子里面包含的邊界問題是復(fù)雜嵌套滾動(dòng)的順滑切換,目前業(yè)界實(shí)現(xiàn)類似效果的技術(shù)方案主要是Nativa或Flutter,沒有見過H5實(shí)現(xiàn)的效果。

再看一個(gè)相同業(yè)務(wù)的Flutter與H5差異對比栗子。

以上是相同頁面的兩種技術(shù)實(shí)現(xiàn)對比,頭部的視差互動(dòng)在滑動(dòng)操控時(shí),H5有明顯的UI抖動(dòng),F(xiàn)lutter則不會(huì)??梢钥吹?,在我們的業(yè)務(wù)中,F(xiàn)lutter實(shí)現(xiàn)了title隨著容器上推漸顯和下拉而漸隱,H5做不到順滑的漸隱漸顯過渡,降級的分享頁只能取消效果。

2. 為什么Web實(shí)現(xiàn)視差有邊界

當(dāng)我們用Webview來實(shí)現(xiàn)復(fù)雜的視差交互時(shí),為何會(huì)觸及Web的邊界?

究其原因是復(fù)雜的視差互動(dòng)大多需要通過js計(jì)算受控目標(biāo)的Dom實(shí)時(shí)位置,不斷循環(huán)“讀取dom位置→計(jì)算dom位置→改變dom位置”,如果受控目標(biāo)過多(視差效果通常是2個(gè)或以上受控目標(biāo),且每個(gè)目標(biāo)采用不同的運(yùn)動(dòng)曲線),必然會(huì)帶來js計(jì)算耗時(shí)>16.67ms進(jìn)而導(dǎo)致UI的抖動(dòng),就會(huì)給人一種互動(dòng)動(dòng)畫不順暢的體感。

在前端的業(yè)務(wù)場景中,復(fù)雜一些的動(dòng)畫可以采用css動(dòng)畫來實(shí)現(xiàn),順暢度會(huì)比js實(shí)現(xiàn)好很多。這是因?yàn)閏ss動(dòng)畫本質(zhì)是由渲染內(nèi)核提供的動(dòng)畫組件能力,它和js是異步的,不會(huì)因?yàn)閖s運(yùn)行而阻塞。但有一個(gè)問題,css動(dòng)畫的運(yùn)行狀態(tài)在js側(cè)沒有感知的機(jī)制,如果用js和css混合來處理視差、動(dòng)畫會(huì)存在兩者銜接不順的問題,這就違背了采用視差效果的初衷。

四、復(fù)雜的多tab頁面

在現(xiàn)在App業(yè)務(wù)場景中,多tab的頁面是非常常見的UI交互設(shè)計(jì),多tab頁面設(shè)計(jì)將相同類型的信息聚合到相同的tab內(nèi),不同的分類則按tab橫向拓展,這樣可以在有限的屏幕范圍內(nèi)盡可能多的容納更多信息。

1. 多Tab頁面的技術(shù)難點(diǎn)

圖片轉(zhuǎn)自https://developer.aliyun.com/article/791254

可以看到很多大型App的首頁都是類似的設(shè)計(jì),實(shí)現(xiàn)的技術(shù)棧是客戶端,用Web實(shí)現(xiàn)案例會(huì)比較少見。當(dāng)然,在某些App極速版中確實(shí)有基于H5實(shí)現(xiàn)的,但也會(huì)在用戶安裝App后通過動(dòng)態(tài)加載等方式將Native版本下載回來。為什么Web實(shí)現(xiàn)類似的多tab長列表存在困難呢?

其實(shí)在上述的邊界問題中也談到了其中的原因,在這個(gè)場景中用web實(shí)現(xiàn)的話,有以下的難點(diǎn):

  • 嵌套滾動(dòng):上下可以滑動(dòng),部分局部內(nèi)容滾動(dòng),外層滾動(dòng)容器與tab容器滾動(dòng)是一體化,滾動(dòng)過渡要自然;
  • 長列表:不同tab容器可以承載著無限列表內(nèi)容,長列表的信息比較多,需要對于非可視內(nèi)容做好節(jié)點(diǎn)回收;
  • tab吸頂:列表在滾動(dòng)至頂時(shí),tab欄目菜單需自動(dòng)吸頂,吸頂過渡自然(通常是某種視差特效);
  • 左右滑動(dòng):手勢的左右橫滑,避免頁面邊緣退出,相鄰tab的內(nèi)容要保留可切換預(yù)覽,tab切換可預(yù)加載;
  • 瀏覽記錄:不同tab容器的內(nèi)容是不相同的,在一次瀏覽周期內(nèi)要保留已瀏覽的位置記錄;

2. 多Tab的容器拓展

從技術(shù)方案上有很多實(shí)現(xiàn)的方法和思路,在UC的業(yè)務(wù)場景中也有很多類似的業(yè)務(wù),在這個(gè)場景是包含了長列表、視差滾動(dòng)等邊界問題的綜合,由于Web容器對于這邊邊界問題缺少原生組件能力支持,業(yè)務(wù)落地的技術(shù)成本往往比較高,而且對比效果native或flutter的效果差別也比較明顯。

因此,針對多Tab列表的場景,在業(yè)界的技術(shù)選型中往往以native或flutter技術(shù)為主。在部分業(yè)務(wù)場景則通過native拓展多Tab容器的方式,每個(gè)tab則是內(nèi)嵌Webview,而native處理tab與tab之間的頁面切換效果和事件派發(fā),這樣通過容器封裝也可以實(shí)現(xiàn)Web的場景拓展,這就是Web容器的多page模式(也叫swiper容器)。

五、App的局部彈窗

在同一個(gè)套業(yè)務(wù)代碼里面提供一個(gè)局部彈窗,在技術(shù)上應(yīng)該是比較簡單的。那么,彈窗在什么情況下會(huì)存在邊界問題呢?讓我們先來看看幾個(gè)業(yè)務(wù)場景的訴求。

1. 局部彈窗的場景

  • 場景1:

上面是相機(jī)萬物識別的結(jié)果呈現(xiàn)的頁面流程。當(dāng)拍照完成后,在拍照結(jié)果的等待頁面中再從彈出一個(gè)局部彈窗,用于展示云端的搜索結(jié)果內(nèi)容,承載內(nèi)容是一個(gè)第三方頁面(不是當(dāng)前相機(jī)業(yè)務(wù)負(fù)責(zé),而是另外的業(yè)務(wù)團(tuán)隊(duì))。頁面的容器頂部bar拖拽放大結(jié)果內(nèi)容頁面,支持分段式觸控,也就是彈窗容器高度是可變的,內(nèi)部支持局部滾動(dòng)。

  • 場景2:

以上兩個(gè)視頻是分別在兩個(gè)不同的內(nèi)容消費(fèi)場景打開用評論或評論詳情,其中一個(gè)是圖文H5打開一個(gè)子彈窗,另一個(gè)是沉浸式視頻播放流中打開一個(gè)半屏彈窗。

因?yàn)槎际窃u論是通用的功能,會(huì)在很多業(yè)務(wù)場景中被調(diào)用,在技術(shù)上我們采用的是H5實(shí)現(xiàn),同行大多采用Native,例如今日頭條、騰訊新聞、網(wǎng)易新聞等均如此,它在代碼上不屬于當(dāng)前的業(yè)務(wù),是一個(gè)獨(dú)立演進(jìn)的業(yè)務(wù)模塊。

  • 場景3:

這是UC帶貨直播的業(yè)務(wù)。在我們的直播容器中,上層可見的UI是由Webview實(shí)現(xiàn)的互動(dòng)層來承載,它包含很多功能實(shí)現(xiàn),例如點(diǎn)贊、禮物互動(dòng)、彈幕列表、商品卡片、福利活動(dòng)、作者關(guān)注等,所有動(dòng)態(tài)運(yùn)營能力基本都基于互動(dòng)層來實(shí)現(xiàn),行業(yè)的主要方案是native為主,而采用Webview來實(shí)現(xiàn)在技術(shù)上是一種新的嘗試。

在底部的購物車按鈕打開的是當(dāng)前直播中的商品列表,在原有的產(chǎn)品設(shè)計(jì)中不屬于當(dāng)前互動(dòng)業(yè)務(wù)團(tuán)隊(duì),而是由直播電商團(tuán)隊(duì)負(fù)責(zé),所以是一個(gè)二方頁面的局部頁面。后來改成了我們通過接口獲取,但考慮到互動(dòng)層的復(fù)雜度,我們沿用了獨(dú)立頁面的技術(shù)實(shí)現(xiàn)。

2. 局部彈窗的邊界問題

以上,所有的彈窗功能有一個(gè)共同特點(diǎn),就是不屬于當(dāng)前業(yè)務(wù),也就是由A業(yè)務(wù)調(diào)用B業(yè)務(wù),實(shí)現(xiàn)一個(gè)局部的功能界面效果。在業(yè)務(wù)劃分上,可能是不同的業(yè)務(wù)團(tuán)隊(duì)負(fù)責(zé),都是H5技術(shù)棧的話,業(yè)務(wù)實(shí)現(xiàn)所采用的的前端框架大概率是不一樣的。

那么,這里的邊界問題是——在兩個(gè)相互隔離的js代碼倉庫中,如何實(shí)現(xiàn)一個(gè)局部的彈窗,而且該彈窗是一個(gè)二方提供的具體實(shí)現(xiàn)?

技術(shù)上,被調(diào)用的局部彈窗可以采用js-sdk的方式提供對外服務(wù),業(yè)務(wù)調(diào)用方通過動(dòng)態(tài)注入JS到當(dāng)前頁面的頁面中來實(shí)現(xiàn)。但這就會(huì)帶來以下的問題:

  • 業(yè)務(wù)耦合:需要兩個(gè)業(yè)務(wù)是相互解耦的,兩個(gè)的代碼不能產(chǎn)生相互干擾;
  • 版本迭代:被注入到業(yè)務(wù)中的二方j(luò)s-sdk需要考慮版本更新問題,是加載具體的js-sdk前調(diào)用一個(gè)api來決定最新版本,還是提供一個(gè)覆蓋式發(fā)布的js-sdk(不管什么版本都是同一個(gè)url,想想就知道有很大的坑)呢?
  • 加載性能:將一個(gè)第三方j(luò)s注入到業(yè)務(wù)中,本質(zhì)是一個(gè)異步j(luò)s模塊注入的問題,業(yè)務(wù)方需要解決好性能的問題。

以上這些問題其實(shí)純前端的方式都是不好解決的,因此,這樣的局部彈窗更合理的設(shè)計(jì)是一個(gè)獨(dú)立Web頁面,獨(dú)立頁面的好處是避免了業(yè)務(wù)耦合和版本迭代兩個(gè)問題,只需要解決加載性能問題就可以了。但在具體的技術(shù)實(shí)現(xiàn)上,難道用iframe的方式設(shè)計(jì)這個(gè)彈窗嗎?

很顯然,大多數(shù)前端開發(fā)者都不太愿意采用這樣的設(shè)計(jì),因?yàn)閕frame不好用。因此,這樣的局部彈窗頁面需要從客戶端角度提供定制化的擴(kuò)展,這就是Web容器的半屏模式,也叫局部容器模式。

六、Web 容器邊界的本質(zhì)

以上舉例了5個(gè)典型的Web邊界問題,哪些是可以在容器范圍內(nèi)進(jìn)行突破的呢?當(dāng)然這里所說的邊界突破,指的是原來做不了或做得不夠好的,通過對容器的封裝而獲得解決的。

實(shí)際上,容器邊界能力的突破還是需要Native同學(xué)通過容器進(jìn)行組件/API定制,給前端提供私有組件的方式來解決標(biāo)準(zhǔn)Web容器的能力局限。從Web瀏覽器的渲染流程上,只要不涉及需要挑戰(zhàn)瀏覽器渲染線程模型的,從原理上可以通過容器封裝來解決。

例如媒體播控、局部彈窗,通過Web容器擴(kuò)展私有組件或API能力是可以比較好的實(shí)現(xiàn)邊界拓展的,但長列表、視差和復(fù)雜多tab等場景所面臨的本質(zhì)問題都是一致的,都需要在足夠小的時(shí)間片段內(nèi)完成“讀取Dom位置(大小)→計(jì)算Dom位置(大小)→改變Dom位置(大小)”,如果這個(gè)時(shí)間片段超過16.67ms(一幀)都會(huì)面臨體驗(yàn)不夠好的問題。

如果想將時(shí)間耗時(shí)壓縮在足夠小的范圍內(nèi),而 JS作為動(dòng)態(tài)解析型語言的執(zhí)行效率在計(jì)算下一幀Dom位置的耗時(shí)就可能會(huì)成為瓶頸,而Web標(biāo)準(zhǔn)沒有在layou階段提供獲取Dom位置大小信息的能力,則進(jìn)一步加劇了需要?jiǎng)討B(tài)計(jì)算目標(biāo)Dom位置的等待時(shí)長 。

因此,此類問題在現(xiàn)有的Web范圍內(nèi)是不太好解決的,而解決它可能需要調(diào)整瀏覽器的渲染流程和架構(gòu),這樣的技術(shù)成本還不如用其他技術(shù)來得更加實(shí)在,技術(shù)方案又不是只有Web一種選擇,不是嗎?

七、Web 容器設(shè)計(jì)的目標(biāo)

以上筆者列舉了許多Web的邊界問題,好像都是說動(dòng)態(tài)方案做不好的或做不了的,對前端而言是不是太過悲觀了呢?顯然,這并不是筆者的初衷,而是期望通過了解技術(shù)實(shí)現(xiàn)的邊界,才能更好的推動(dòng)Web容器進(jìn)行完善和向前發(fā)展。

筆者認(rèn)為,對于Web容器的封裝目標(biāo)是—— 在容器范圍內(nèi)解決原有Web標(biāo)準(zhǔn)容器解決不了的邊界問題,并通過容器的標(biāo)準(zhǔn)化封裝提升對復(fù)雜問題的解決效率,讓W(xué)eb容器能夠覆蓋更多的業(yè)務(wù)場景,進(jìn)而能夠拓展前端的業(yè)務(wù)空間 。這里的關(guān)鍵點(diǎn)有:

1. 解決Web的邊界問題

這是一個(gè)很重要的出發(fā)點(diǎn),但凡標(biāo)準(zhǔn)能夠解決的問題,其實(shí)就不需要一個(gè)自定義的容器(輪子)來加持。邊界的問題其實(shí)跟業(yè)務(wù)類型和場景有很大關(guān)系,不同的業(yè)務(wù)觸及的邊界是不一樣的,在不同的發(fā)展階段業(yè)務(wù)對于邊界的體感或認(rèn)知也不盡相同。

不過,是不是所有的邊界問題都能通過容器來解決呢?顯然不是,有些邊界可能是在現(xiàn)有Web容器范圍內(nèi)就是無法突破的,該Native的就Native,因此需要開發(fā)者對于邊界問題的有更精準(zhǔn)和更深刻的認(rèn)識。

2. 解決Web不夠標(biāo)準(zhǔn)的問題

很多時(shí)候一個(gè)App應(yīng)用需要在不同的平臺(tái)上提供服務(wù),不同平臺(tái)的實(shí)現(xiàn)或UI展現(xiàn)本來就存在差異,而這種差異對產(chǎn)品而言可能是不可接受的,那么可以將這種不一致的問題在容器層面進(jìn)行封裝或拓展。

這樣的能力差異挺多的,例如輸入面板、分享面板、日夜間適配、web容器樣式(如前進(jìn)、后退、關(guān)閉、收藏等)、跨頁通訊、容器push/pop的動(dòng)畫、worker調(diào)度和通訊,等等……這些應(yīng)該是容器封裝要解決的基本內(nèi)容,有一部分是web標(biāo)準(zhǔn)的延伸或拓展(漸進(jìn)增強(qiáng)),也有部分是針對私域業(yè)務(wù)的定制優(yōu)化。

3. 提升復(fù)雜問題的解決效率

復(fù)雜問題有很多,舉個(gè)通俗易懂的栗子。例如性能優(yōu)化,這對于每個(gè)業(yè)務(wù)都是一個(gè)復(fù)雜的問題。

做過移動(dòng)H5性能優(yōu)化的同學(xué)都應(yīng)該知道,純前端視角是很難將性能優(yōu)化到極致的,最多就是通過服務(wù)端實(shí)現(xiàn)SSR、ER邊緣渲染,但這并不是最極致的性能優(yōu)化手段。在App里面做性能優(yōu)化,極致的優(yōu)化手段還包括離線包、數(shù)據(jù)預(yù)取、圖片預(yù)取、NSR預(yù)渲染、頁面預(yù)執(zhí)行、端智能調(diào)度等優(yōu)化手段。

當(dāng)然,復(fù)雜問題的解決往往也是一個(gè)技術(shù)成本高的事情,如何將復(fù)雜的、成本高的事情簡單化、標(biāo)準(zhǔn)化、動(dòng)態(tài)化,這也是容器設(shè)計(jì)的重要目的。

4. 拓展前端的業(yè)務(wù)空間

這應(yīng)該是Web容器封裝的最終目標(biāo)。當(dāng)然,一個(gè)新的Web容器方案,除了性能、交互體驗(yàn)?zāi)軌驖M足業(yè)務(wù)需求外,前端的開發(fā)體驗(yàn)也需要得到保障,配套的工程效率工具方案也應(yīng)該是一個(gè)Web容器建設(shè)的重要內(nèi)容,而這往往容易被容器封裝的Owner所忽略的。

因此,Web容器框架應(yīng)該以業(yè)務(wù)為起點(diǎn),前端開發(fā)者需要深度參與其中,這樣才能提出和推動(dòng)更符合前端視角的訴求落地,而不只是被動(dòng)接受客戶端的封裝實(shí)現(xiàn)。


標(biāo)題名稱:淺談Web容器設(shè)計(jì)的邊界和目標(biāo)
標(biāo)題路徑:http://www.dlmjj.cn/article/cdgpdjo.html