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

當然,要想準確把握Webview的能力范圍并不是件容易的事,而不同人或團隊對于Webview能力邊界的理解也是不太一樣的。當我們在討論一項技術(shù)的邊界時,關(guān)鍵的不是了解該技術(shù)能做好什么,而是知道它做不好什么。
注意,說的是做不好,不是做不了。很多時候,我們所說的“做不好”指的是,達不到最優(yōu)秀的用戶體驗,通常與使用Native并經(jīng)過優(yōu)化后的效果進行對比。在用戶體驗競爭越來越激烈的情況下,每個產(chǎn)品都期望能用最好的天花板最高的技術(shù)來落地。
但在現(xiàn)實的技術(shù)方案設(shè)計中,除了考慮技術(shù)所能達到的最優(yōu)效果外,還需要綜合考慮開發(fā)成本、開發(fā)周期、維護效率、線上風險等因素,以及根據(jù)業(yè)務發(fā)展、人力資源配置情況,綜合考慮后最終選擇一個ROI最高的方案。
好了,方案選擇的路徑不是這里討論的重點,還是來聊聊動態(tài)容器吧。下面筆者將列舉一些典型的用Webview技術(shù)的Cover起來有難度的場景。
Web 容器的邊界場景
一、復雜的媒體播控
1. 視頻播控
并不是說Webview(H5)、小程序處理不了視頻,而是對于視頻的細節(jié)處理不夠好。我們都知道web原生的video播放控件功能單一,沒有快進/退、倍速、音量調(diào)節(jié)、亮度調(diào)節(jié)、對緩沖無感知等問題。此外,動態(tài)容器處理視頻還有以下常見問題:
- 自動播放控制:主要是iOS的限制,在webview內(nèi)的video標簽需要用戶的許可,因此雙端自動播放邏輯是不一致的。在iOS上為了解決自動播放的問題,通常在body上綁一個video的play事件,用戶觸碰一下頁面就代表授權(quán)了,但這解法其實挺雞賊的,并不能代表用戶的真實意愿。
- 播放時長統(tǒng)計:video播放時長統(tǒng)計是業(yè)務和算法的需要,如果前端業(yè)務開發(fā)者來做video播放時間統(tǒng)計會存在,在點擊播放時視頻資源才開始下載,什么時候視頻開始起播基本完全靠估算,播放過程中網(wǎng)絡緩沖時間也可能被統(tǒng)計到播放時長內(nèi),因此時長統(tǒng)計由前端業(yè)務來完成非常容易帶來統(tǒng)計誤差,業(yè)務往往是不可接受的。
- 封面無縫切視頻:由于video真正的播放視頻時間(起播時間)不精確,也帶來視頻的封面圖片替換為視頻播放畫面的過渡體感會比較生硬,如果點擊播放后立刻將封面圖片替換掉,而這時視頻還在加載就會出現(xiàn)黑屏效果,體感不ok。
- 播控面板UI定制:在webview內(nèi)對video的UI調(diào)整也是有難度的事情,常見的實現(xiàn)是先隱藏原生video的控制條,然后在video上覆蓋一層自定義UI,接著在自定UI上通過事件的方式來控制底下的video。這樣的封裝有很多開源的方案,但整體體驗與Native定制的播放器有很大落差,在自有App內(nèi)幾乎不會用,站外分享才會考慮這類方案,實際也是一個不得已的選擇。
- 多視頻播控:如果在一個頁面中存在多個視頻,在播放其中視頻時,需要對其他視頻進行暫?;蜾N毀處理;如果這是一個視頻長列表,產(chǎn)品期望根據(jù)用戶滾動的位置實現(xiàn)視頻的自動播控,那么多視頻問題會更復雜,因此很少看到有業(yè)務使用動態(tài)技術(shù)構(gòu)建包含視頻自動播控的長列表業(yè)務。在這個場景,技術(shù)要么native,要么flutter。
包含多視頻的長列表滾動到可視范圍內(nèi)自動播放,技術(shù)以native/flutter為主
當然,webview處理video帶來的細節(jié)體驗問題還有不少,有一些問題通過native托管可以有效解決。在各大App自有業(yè)務內(nèi),對Webview的video播放器的優(yōu)化基本都走native托管的模式,在技術(shù)實現(xiàn)上叫混合渲染或同層渲染。
2. 音頻播控
音頻媒體資源的播控問題與video是類似的,webview內(nèi)的audio標簽也存在功能單一,沒有快進/退、倍速、音量調(diào)節(jié)、對緩沖無感知等問題。
在我們的業(yè)務中涉及的音頻播控場景比較少,目前為止包含音頻播控的場景主要是圖文的語音播報功能,由于需要對音頻播控在App?;钇陂g全局生效,音頻播控的落地頁面自然不能使用h5的audio標簽來處理TTS音頻,而是對接Native自定義的語音控制事件體系,頁面則繪制一個播控音頻的UI面板。
目前,針對音頻播控的訴求行業(yè)主要方案是Native base,F(xiàn)lutter實現(xiàn)應該也沒問題,Web的實現(xiàn)相對較少。目前,我們已完成了此場景Web化,這里需要解決的邊界問題是在后臺模式下的頁面?;詈蜕芷谕卣埂?/p>
3. 動圖播控
動圖包括gif、apng、webp等,在動態(tài)容器只有img標簽一種圖片處理方式,在一些動圖很多的場景,就很難實現(xiàn)對動圖的播放有效控制。例如:
- 多宮格圖片的順序播放:由于不知道動圖什么時候播放完成,在多宮格的動圖列表中需要等待上一個動圖播完再接著播下一個的需求是無法用現(xiàn)有img標簽來實現(xiàn)的。在業(yè)界碰到類似的問題,如果非要用web的方式解決,往往將動圖轉(zhuǎn)化為video來處理,或者就直接標記為“動圖”讓用戶自己點擊播放。
實際上,業(yè)務需要動圖播放可控的功能,要解決的實際問題是動圖可以逐幀暫停/播放、播放開始和結(jié)束都有對應的事件,也就是需要一個功能完備的動圖播放器,而不只是用封面替換動圖來模擬實現(xiàn)暫停而又不知道最后一幀啥時候完成的半成品。
目前針對動圖進行有序播控的訴求,我們采用的是Flutter方案,本質(zhì)是Native的實現(xiàn),而在Webview容器內(nèi)可以通過類似視頻播放器一樣,通過同層渲染技術(shù)實現(xiàn)對動圖的逐幀播控。
二、高性能的長列表
1. 長列表的性能問題
在Web容器下,性能是長列表面臨的最棘手問題。問題會表現(xiàn)為:
- 在不停下拉滾動的過程中,當列表插入的頁面節(jié)點越來越多,則會導致滑動越來越卡頓(掉幀);
- 如果列表內(nèi)容過多而不做 DOM 節(jié)點回收或分頁處理,頁面的內(nèi)存可能占用過大,進而導致頁面或 App 崩潰;
- 在做了頁面節(jié)點回收后會導致在快速滑動的過程中,頁面節(jié)點回收而Dom渲染速度跟不上滾動的速度,而導致用戶有明顯的白屏體感。
2. 行業(yè)方案分析
對于這些問題,前端業(yè)界有很多解決方案,解決思路大致兩個方向:
- 針對圖片過多
圖片過多,這是引起性能問題的最常見因素,因此在有大量圖片的頁面中,我們都會使用 lazyload 的方式按需加載圖片,長列表的場景也是一樣的。
- 針對節(jié)點過多
業(yè)界普遍的解決方案是虛擬長列表,根據(jù)列表容器的可視范圍,動態(tài)計算出在可視范圍內(nèi)的列表節(jié)點 item,然后只渲染視野邊界內(nèi)容的 item,通過控制頁面節(jié)點數(shù)避免內(nèi)存線性增加。
在具體的實現(xiàn)方案中,目前行業(yè)方案有:
- 給列表容器設(shè)置 height 或 padding 值撐開容器: react-virtualized& vue-virtual-scroll-list
- 通過 transform 對列表 item 進行位置偏移,同時用一個影子容器來實現(xiàn)滾動條的模擬:ngx-virtual-scroller
- 小程序方案:微信小程序recycle-view、taro虛擬列表
當然,還有很多,這里就不再一一列舉。
以上的幾種方案有所差異,但設(shè)計理念基本類似。在實際的業(yè)務場景中,當容器內(nèi)的每個 item 高度是動態(tài)的(等高的計算邏輯相對沒那么復雜,這里不討論),在虛擬列表頁面節(jié)點數(shù)量增多的過程,背后存在大量的js邏輯計算:
- 在計算可視范圍內(nèi)的 item 內(nèi)容時,必須需要循環(huán)遍歷每個 item,獲得其相對于可視窗口的偏移量,進而計算出需要展示的 item,以完成虛擬列表布局的需要。
- 容器的外部高度是需要在滾動過程中,不停的進行動態(tài)計算并進行重新渲染,也就是整個列表中內(nèi)部每個元素,在滾動過程中是時時刻刻都產(chǎn)生超過可視范圍的區(qū)塊重繪。
由于獲取Dom元素的真實高度需渲染完成后才能獲得(相對Native或Flutter可以在元素layout的過程,通過layoutBuilder的回調(diào)就可以獲取其高度,無需等待元素渲染上屏),導致js計算列表元素高度需要等待Dom渲染,進而到帶來不可避免的時間差。
因此,在頁面快速滾動的過程中,虛擬長列表在回收節(jié)點計算的過程,由于高度計算的處理邏輯需要等到Dom上屏之后,如果頁面滾動速度越快,計算量也就越大,等待Dom上屏的時間間隔就越大,一旦頁面的滾動速度超過一定閾值,必然出現(xiàn)可視區(qū)域內(nèi)UI的變化速度 > 渲染速度的問題,就會表現(xiàn)為快速滾動的頁面閃白。
3. 閃白無法量化
實際上,滾動的白屏問題是虛擬列表的節(jié)點被回收后引入的新問題,是一個用戶的體感問題。在這里筆者用可視區(qū)域內(nèi)的UI變化速度 > 渲染速度只是技術(shù)用語上的表述,尷尬的是從純技術(shù)的角度這是 一個很難用數(shù)據(jù)進行量化的問題 。why?
首先,這是一個新問題。
如果我們沒有對頁面節(jié)點進行回收,那么就不存在滾動路徑上頁面沒內(nèi)容的情況,也就沒有所謂的閃白問題。但不做節(jié)點回收就意味著在一個超長或無限下拉的列表中,DOM 節(jié)點會線性增大,必然導致頁面占用越來越多的內(nèi)存,增加更多的排版耗時,進而影響頁面性能和用戶操控體感。
其次,為何無法數(shù)據(jù)量化?
因為在 Webview 內(nèi),前端并不知道當前頁面滾動速度是多少(或者在前端不能準確地用數(shù)據(jù)的方式表達),滾動曲線和滾動加速度在不同的手機和平臺上也是不盡相同的,因此在不同手機上發(fā)生白屏的滾動速度閾值是不一樣的。
4. 規(guī)避快滑閃白
那么,為了平衡快速滾動的閃白問題,可以讓容器可以對頁面在滾動速度的上限進行限制,這個需要客戶端容器側(cè)來處理。
很多前端開發(fā)者應該都知道,在老舊 iOS 系統(tǒng)上,如果 WebView 采用的 UIView 架構(gòu),由于 UIView 和 js 運行在同一個線程,導致在 UIView 滾動時會阻塞 js 執(zhí)行,因此在 UIView 的容器內(nèi)虛擬長列表快速滾動帶來的白屏問題是不可避免的,好在現(xiàn)在的 iOS 系統(tǒng)基本上已升級為異步線程模式的 WKWebView 了。
目前,WKWebView 容器滾動的慣性速度和加速度的上限默認是比安卓的要低一些的(這也只是筆者對雙平臺的滾動對比的體感,沒有量化的數(shù)據(jù)),而且iPhone手機性能通常比較好,因此虛擬長列表頁面在快速滾動中,iOS閃白體感不那么明顯。
由于安卓的 WebView 容器在快速滾動情況下,頁面會擁有很高的慣性速度和加速度。在極端滾動操控下,比如直接觸控拖拽滾動條(參考以上的視頻)或通過window.scrollTo 快速定位到某個位置,JS 邏輯還來不及計算當前滾動到的可視區(qū)域所需展示的 item 內(nèi)容時,頁面就已滾過了該區(qū)域,閃白問題幾乎是不可避免的。
而針對極端操控的閃白問題,可以在安卓的Web容器側(cè)禁用滾動條的拖拽功能來規(guī)避,這并沒有在根本上解決問題,但是webview這種機制不一定全是缺點,在大多數(shù)場景下,普通速度滑動h5的列表滑動也是很順暢的,基本也感覺不到白屏,而技術(shù)角度看webview內(nèi)存占用會比flutter低,這其實也是一種優(yōu)勢。
5. 長列表的優(yōu)化思路
如果業(yè)務上,不得不使用長列表,在前端的優(yōu)化技巧層也是有一些方式方法的。
比如,讓列表渲染的 item 不只是可視范圍內(nèi)的 item,而是會在上下邊界部分預留足夠的buffer,這樣可以緩解問題。在雙端的具體優(yōu)化策略上,雙端冗余buffer也可以做差異處理。在上下邊界的冗余 item 數(shù)量,iOS 可以冗余少一些(性能好,但內(nèi)存少),而安卓則多一些(設(shè)備內(nèi)存大,就多占內(nèi)存)。
或者,在需要動態(tài)計算列表高度的時候?qū)⑦^程簡化,比如原來需要每一個參與布局的列表item都需要計算一次,是否可以采用“分組計算”的策略,例如10個item分為1組,回收節(jié)點也是按組進行,這樣回收算法的復雜度就可能只有原來的1/10。
6. 邊界的選擇
不管對長列表采用怎樣的dom節(jié)點回收技術(shù),都必定會面臨在用戶極端操控下 UI 的變化速度 > 渲染速度問題,在現(xiàn)有的瀏覽器JS執(zhí)行必然阻塞Dom渲染的模型下,而且Webview內(nèi)核層面定義沒有透露更多的動態(tài)渲染處理API之前,此問題暫時沒有徹底的解法。在對用戶體驗較高的長列表場景,我們傾向于選擇Flutter,如果是一級核心場景,主流方案還是Native。
當然,問題雖如此,這并不意味在h5長列表中對非可視區(qū)域的節(jié)點進行回收是個不必要的設(shè)計,畢竟極速滾動的閃白還是一個比較極端場景,很多時候產(chǎn)品對于用戶的體驗并不沒有那么特別苛刻?;蛟S也不應該那么苛刻,特別是人力有限的情況下,畢竟也要綜合考慮ROI,但開發(fā)者最好要知道技術(shù)邊界在哪里,避免掉坑里。
三、復雜的視差互動
視差互動(Parallax Effect)或滾動(Parallax Scrolling)指操控網(wǎng)頁滾動過程中,同時實現(xiàn)多個元素以不同的速度移動,形成立體的運動效果以提供出色的視覺體驗。
1. 視差互動的案例分析
先來看看兩個真實業(yè)務場景的栗子(視頻):
以上視頻的栗子是Flutter實現(xiàn)的視差效果,含有兩種視差:
- 往上推,logo需要根據(jù)上推手勢同步縮?。?/li>
- 切換tab,當前高亮的tab背景和top橫線需要同步跟隨手勢變換。
如果用H5的方式來做這個需求,這兩個效果是做不到滑動操控和UI變換的那種順滑體感。這個本質(zhì)原因是js是單線程的,當js在執(zhí)行時DOM渲染會被阻塞,一幀內(nèi)要做多件事情就可能會出現(xiàn)掉幀,所以做不到絲滑體感。
以上的栗子是基于Flutter實現(xiàn)的視差,是目前比較常見的視頻播控落地頁的交互模式。在這個業(yè)務場景中是一個可以橫向切換的多頁容器,同時每個播放頁面又是一個可上下滾動的嵌套容器:
- 頁面整體可以上下滾動,而下方的評論區(qū)塊則在視頻縮放到最小后可以繼續(xù)局部滾動;
- 視差效果則是上推視頻容器區(qū)塊同步縮小,播放器也隨著可播區(qū)塊的縮小而跟隨縮??;下拉,則反之。
這個栗子里面包含的邊界問題是復雜嵌套滾動的順滑切換,目前業(yè)界實現(xiàn)類似效果的技術(shù)方案主要是Nativa或Flutter,沒有見過H5實現(xiàn)的效果。
再看一個相同業(yè)務的Flutter與H5差異對比栗子。
以上是相同頁面的兩種技術(shù)實現(xiàn)對比,頭部的視差互動在滑動操控時,H5有明顯的UI抖動,F(xiàn)lutter則不會??梢钥吹?,在我們的業(yè)務中,F(xiàn)lutter實現(xiàn)了title隨著容器上推漸顯和下拉而漸隱,H5做不到順滑的漸隱漸顯過渡,降級的分享頁只能取消效果。
2. 為什么Web實現(xiàn)視差有邊界
當我們用Webview來實現(xiàn)復雜的視差交互時,為何會觸及Web的邊界?
究其原因是復雜的視差互動大多需要通過js計算受控目標的Dom實時位置,不斷循環(huán)“讀取dom位置→計算dom位置→改變dom位置”,如果受控目標過多(視差效果通常是2個或以上受控目標,且每個目標采用不同的運動曲線),必然會帶來js計算耗時>16.67ms進而導致UI的抖動,就會給人一種互動動畫不順暢的體感。
在前端的業(yè)務場景中,復雜一些的動畫可以采用css動畫來實現(xiàn),順暢度會比js實現(xiàn)好很多。這是因為css動畫本質(zhì)是由渲染內(nèi)核提供的動畫組件能力,它和js是異步的,不會因為js運行而阻塞。但有一個問題,css動畫的運行狀態(tài)在js側(cè)沒有感知的機制,如果用js和css混合來處理視差、動畫會存在兩者銜接不順的問題,這就違背了采用視差效果的初衷。
四、復雜的多tab頁面
在現(xiàn)在App業(yè)務場景中,多tab的頁面是非常常見的UI交互設(shè)計,多tab頁面設(shè)計將相同類型的信息聚合到相同的tab內(nèi),不同的分類則按tab橫向拓展,這樣可以在有限的屏幕范圍內(nèi)盡可能多的容納更多信息。
1. 多Tab頁面的技術(shù)難點
圖片轉(zhuǎn)自https://developer.aliyun.com/article/791254
可以看到很多大型App的首頁都是類似的設(shè)計,實現(xiàn)的技術(shù)棧是客戶端,用Web實現(xiàn)案例會比較少見。當然,在某些App極速版中確實有基于H5實現(xiàn)的,但也會在用戶安裝App后通過動態(tài)加載等方式將Native版本下載回來。為什么Web實現(xiàn)類似的多tab長列表存在困難呢?
其實在上述的邊界問題中也談到了其中的原因,在這個場景中用web實現(xiàn)的話,有以下的難點:
- 嵌套滾動:上下可以滑動,部分局部內(nèi)容滾動,外層滾動容器與tab容器滾動是一體化,滾動過渡要自然;
- 長列表:不同tab容器可以承載著無限列表內(nèi)容,長列表的信息比較多,需要對于非可視內(nèi)容做好節(jié)點回收;
- tab吸頂:列表在滾動至頂時,tab欄目菜單需自動吸頂,吸頂過渡自然(通常是某種視差特效);
- 左右滑動:手勢的左右橫滑,避免頁面邊緣退出,相鄰tab的內(nèi)容要保留可切換預覽,tab切換可預加載;
- 瀏覽記錄:不同tab容器的內(nèi)容是不相同的,在一次瀏覽周期內(nèi)要保留已瀏覽的位置記錄;
2. 多Tab的容器拓展
從技術(shù)方案上有很多實現(xiàn)的方法和思路,在UC的業(yè)務場景中也有很多類似的業(yè)務,在這個場景是包含了長列表、視差滾動等邊界問題的綜合,由于Web容器對于這邊邊界問題缺少原生組件能力支持,業(yè)務落地的技術(shù)成本往往比較高,而且對比效果native或flutter的效果差別也比較明顯。
因此,針對多Tab列表的場景,在業(yè)界的技術(shù)選型中往往以native或flutter技術(shù)為主。在部分業(yè)務場景則通過native拓展多Tab容器的方式,每個tab則是內(nèi)嵌Webview,而native處理tab與tab之間的頁面切換效果和事件派發(fā),這樣通過容器封裝也可以實現(xiàn)Web的場景拓展,這就是Web容器的多page模式(也叫swiper容器)。
五、App的局部彈窗
在同一個套業(yè)務代碼里面提供一個局部彈窗,在技術(shù)上應該是比較簡單的。那么,彈窗在什么情況下會存在邊界問題呢?讓我們先來看看幾個業(yè)務場景的訴求。
1. 局部彈窗的場景
- 場景1:
上面是相機萬物識別的結(jié)果呈現(xiàn)的頁面流程。當拍照完成后,在拍照結(jié)果的等待頁面中再從彈出一個局部彈窗,用于展示云端的搜索結(jié)果內(nèi)容,承載內(nèi)容是一個第三方頁面(不是當前相機業(yè)務負責,而是另外的業(yè)務團隊)。頁面的容器頂部bar拖拽放大結(jié)果內(nèi)容頁面,支持分段式觸控,也就是彈窗容器高度是可變的,內(nèi)部支持局部滾動。
- 場景2:
以上兩個視頻是分別在兩個不同的內(nèi)容消費場景打開用評論或評論詳情,其中一個是圖文H5打開一個子彈窗,另一個是沉浸式視頻播放流中打開一個半屏彈窗。
因為都是評論是通用的功能,會在很多業(yè)務場景中被調(diào)用,在技術(shù)上我們采用的是H5實現(xiàn),同行大多采用Native,例如今日頭條、騰訊新聞、網(wǎng)易新聞等均如此,它在代碼上不屬于當前的業(yè)務,是一個獨立演進的業(yè)務模塊。
- 場景3:
這是UC帶貨直播的業(yè)務。在我們的直播容器中,上層可見的UI是由Webview實現(xiàn)的互動層來承載,它包含很多功能實現(xiàn),例如點贊、禮物互動、彈幕列表、商品卡片、福利活動、作者關(guān)注等,所有動態(tài)運營能力基本都基于互動層來實現(xiàn),行業(yè)的主要方案是native為主,而采用Webview來實現(xiàn)在技術(shù)上是一種新的嘗試。
在底部的購物車按鈕打開的是當前直播中的商品列表,在原有的產(chǎn)品設(shè)計中不屬于當前互動業(yè)務團隊,而是由直播電商團隊負責,所以是一個二方頁面的局部頁面。后來改成了我們通過接口獲取,但考慮到互動層的復雜度,我們沿用了獨立頁面的技術(shù)實現(xiàn)。
2. 局部彈窗的邊界問題
以上,所有的彈窗功能有一個共同特點,就是不屬于當前業(yè)務,也就是由A業(yè)務調(diào)用B業(yè)務,實現(xiàn)一個局部的功能界面效果。在業(yè)務劃分上,可能是不同的業(yè)務團隊負責,都是H5技術(shù)棧的話,業(yè)務實現(xiàn)所采用的的前端框架大概率是不一樣的。
那么,這里的邊界問題是——在兩個相互隔離的js代碼倉庫中,如何實現(xiàn)一個局部的彈窗,而且該彈窗是一個二方提供的具體實現(xiàn)?
技術(shù)上,被調(diào)用的局部彈窗可以采用js-sdk的方式提供對外服務,業(yè)務調(diào)用方通過動態(tài)注入JS到當前頁面的頁面中來實現(xiàn)。但這就會帶來以下的問題:
- 業(yè)務耦合:需要兩個業(yè)務是相互解耦的,兩個的代碼不能產(chǎn)生相互干擾;
- 版本迭代:被注入到業(yè)務中的二方js-sdk需要考慮版本更新問題,是加載具體的js-sdk前調(diào)用一個api來決定最新版本,還是提供一個覆蓋式發(fā)布的js-sdk(不管什么版本都是同一個url,想想就知道有很大的坑)呢?
- 加載性能:將一個第三方js注入到業(yè)務中,本質(zhì)是一個異步js模塊注入的問題,業(yè)務方需要解決好性能的問題。
以上這些問題其實純前端的方式都是不好解決的,因此,這樣的局部彈窗更合理的設(shè)計是一個獨立Web頁面,獨立頁面的好處是避免了業(yè)務耦合和版本迭代兩個問題,只需要解決加載性能問題就可以了。但在具體的技術(shù)實現(xiàn)上,難道用iframe的方式設(shè)計這個彈窗嗎?
很顯然,大多數(shù)前端開發(fā)者都不太愿意采用這樣的設(shè)計,因為iframe不好用。因此,這樣的局部彈窗頁面需要從客戶端角度提供定制化的擴展,這就是Web容器的半屏模式,也叫局部容器模式。
六、Web 容器邊界的本質(zhì)
以上舉例了5個典型的Web邊界問題,哪些是可以在容器范圍內(nèi)進行突破的呢?當然這里所說的邊界突破,指的是原來做不了或做得不夠好的,通過對容器的封裝而獲得解決的。
實際上,容器邊界能力的突破還是需要Native同學通過容器進行組件/API定制,給前端提供私有組件的方式來解決標準Web容器的能力局限。從Web瀏覽器的渲染流程上,只要不涉及需要挑戰(zhàn)瀏覽器渲染線程模型的,從原理上可以通過容器封裝來解決。
例如媒體播控、局部彈窗,通過Web容器擴展私有組件或API能力是可以比較好的實現(xiàn)邊界拓展的,但長列表、視差和復雜多tab等場景所面臨的本質(zhì)問題都是一致的,都需要在足夠小的時間片段內(nèi)完成“讀取Dom位置(大小)→計算Dom位置(大小)→改變Dom位置(大小)”,如果這個時間片段超過16.67ms(一幀)都會面臨體驗不夠好的問題。
如果想將時間耗時壓縮在足夠小的范圍內(nèi),而 JS作為動態(tài)解析型語言的執(zhí)行效率在計算下一幀Dom位置的耗時就可能會成為瓶頸,而Web標準沒有在layou階段提供獲取Dom位置大小信息的能力,則進一步加劇了需要動態(tài)計算目標Dom位置的等待時長 。
因此,此類問題在現(xiàn)有的Web范圍內(nèi)是不太好解決的,而解決它可能需要調(diào)整瀏覽器的渲染流程和架構(gòu),這樣的技術(shù)成本還不如用其他技術(shù)來得更加實在,技術(shù)方案又不是只有Web一種選擇,不是嗎?
七、Web 容器設(shè)計的目標
以上筆者列舉了許多Web的邊界問題,好像都是說動態(tài)方案做不好的或做不了的,對前端而言是不是太過悲觀了呢?顯然,這并不是筆者的初衷,而是期望通過了解技術(shù)實現(xiàn)的邊界,才能更好的推動Web容器進行完善和向前發(fā)展。
筆者認為,對于Web容器的封裝目標是—— 在容器范圍內(nèi)解決原有Web標準容器解決不了的邊界問題,并通過容器的標準化封裝提升對復雜問題的解決效率,讓Web容器能夠覆蓋更多的業(yè)務場景,進而能夠拓展前端的業(yè)務空間 。這里的關(guān)鍵點有:
1. 解決Web的邊界問題
這是一個很重要的出發(fā)點,但凡標準能夠解決的問題,其實就不需要一個自定義的容器(輪子)來加持。邊界的問題其實跟業(yè)務類型和場景有很大關(guān)系,不同的業(yè)務觸及的邊界是不一樣的,在不同的發(fā)展階段業(yè)務對于邊界的體感或認知也不盡相同。
不過,是不是所有的邊界問題都能通過容器來解決呢?顯然不是,有些邊界可能是在現(xiàn)有Web容器范圍內(nèi)就是無法突破的,該Native的就Native,因此需要開發(fā)者對于邊界問題的有更精準和更深刻的認識。
2. 解決Web不夠標準的問題
很多時候一個App應用需要在不同的平臺上提供服務,不同平臺的實現(xiàn)或UI展現(xiàn)本來就存在差異,而這種差異對產(chǎn)品而言可能是不可接受的,那么可以將這種不一致的問題在容器層面進行封裝或拓展。
這樣的能力差異挺多的,例如輸入面板、分享面板、日夜間適配、web容器樣式(如前進、后退、關(guān)閉、收藏等)、跨頁通訊、容器push/pop的動畫、worker調(diào)度和通訊,等等……這些應該是容器封裝要解決的基本內(nèi)容,有一部分是web標準的延伸或拓展(漸進增強),也有部分是針對私域業(yè)務的定制優(yōu)化。
3. 提升復雜問題的解決效率
復雜問題有很多,舉個通俗易懂的栗子。例如性能優(yōu)化,這對于每個業(yè)務都是一個復雜的問題。
做過移動H5性能優(yōu)化的同學都應該知道,純前端視角是很難將性能優(yōu)化到極致的,最多就是通過服務端實現(xiàn)SSR、ER邊緣渲染,但這并不是最極致的性能優(yōu)化手段。在App里面做性能優(yōu)化,極致的優(yōu)化手段還包括離線包、數(shù)據(jù)預取、圖片預取、NSR預渲染、頁面預執(zhí)行、端智能調(diào)度等優(yōu)化手段。
當然,復雜問題的解決往往也是一個技術(shù)成本高的事情,如何將復雜的、成本高的事情簡單化、標準化、動態(tài)化,這也是容器設(shè)計的重要目的。
4. 拓展前端的業(yè)務空間
這應該是Web容器封裝的最終目標。當然,一個新的Web容器方案,除了性能、交互體驗能夠滿足業(yè)務需求外,前端的開發(fā)體驗也需要得到保障,配套的工程效率工具方案也應該是一個Web容器建設(shè)的重要內(nèi)容,而這往往容易被容器封裝的Owner所忽略的。
因此,Web容器框架應該以業(yè)務為起點,前端開發(fā)者需要深度參與其中,這樣才能提出和推動更符合前端視角的訴求落地,而不只是被動接受客戶端的封裝實現(xiàn)。
分享標題:淺談Web容器設(shè)計的邊界和目標
當前URL:http://www.5511xx.com/article/cdgpdjo.html


咨詢
建站咨詢
