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