面試官:你解決過哪些難題-預渲染/SSR/SPA/離線包/Snapshot

關注前端早早聊,跟進第三十屆|前端早早聊大會 BFF 專場(GraphQL、統一網關、API 接入管理、超大規模集羣,協議轉換、安全切面、高併發、可視化編排、統一穩定性建設...)8-14 全天直播,9 位講師,點擊報名看直播👉 ):前端

海報 (1).png

前端早早聊大會,與掘金聯合舉辦。加 codingdreamer 進大會技術羣,贏在新的起跑線, 全部往期都有全程錄播,上手年票一次性解鎖所有web


本文是第十八屆 - 前端早早聊性能優化專場,也是早早聊第 127 場,來自 阿里 飛豬-太吾 的分享。算法

自我介紹

你們好,我是來自飛豬的胡昊,花名是太吾。先不着急開始,由於我剛纔在小助手的朋友圈中看到前幾位導師分享的截圖,同時看到你們的一些問題。有人說我這篇分享在掘金中有對應的文章,相信也有很多小夥伴可能看過那篇文章,我想說的是看到過那篇文章還要不要聽我這邊分享,我以爲仍是要聽的。小程序

文章主要的做用是一個傳播,而一些乾貨確定仍是在 PPT 中,因此你們仍是不要放過前端早早聊 2020 年最後一次分享。前兩位大佬都是比較偏硬核:IDE 和可視化。咱最後又回到了傳統的 H5 上的一個性能優化,可能沒有前兩位那麼硬核,可是但願能夠給你們帶來一些啓發。後端

這個 PPT 也是以前用於咱們集團內的一個分享,因此有點偷懶,其實大部份內容是差很少的,可是有一些對外仍是須要有一些具體的講解。本次分享是《飛豬雙 11 - 基於 Web 的性能優化》,雙 11 我當時的一個職責是性能的 pm,因此對雙 11 總體的 Web 性能優化仍是有必定的理解,但願把這個理解帶給你們。緩存

目錄

C18-7 太吾-如何在雙11大促中實現會場頁面秒開.002.jpeg

整個會分爲三個部分來說解。安全

  • 背景
  • 優化的方向。主要的優化手段就是右邊你看到的這 6 個東西,具體內容後面具體講解。
  • 總結和規劃

背景

首先是背景。從 Weex 到 Web 是基於什麼樣的考慮?性能優化

技術棧演進

C18-7 太吾-如何在雙11大促中實現會場頁面秒開.004.jpeg

咱們飛豬從 2013 年第一個 H5 頁面的落地一直到 2016 年總體切換成 Weex,不管是 Weex 仍是 Rax 總體都是以 Weex 渲染爲主,在飛豬端和手淘端內。一直到 2020 年的 6 月,咱們又總體順應集團的策略又切換回 H5,技術棧也做爲了統一,總體使用了 Rax1.0 的一個技術棧。微信

以前可能有 Rax 的同窗來前端早早聊分享過。咱們怎樣基於這樣一個考慮從 Weex 切換到 H5,咱們對於Weex 性能的可信度仍是比 H5 要好的。但爲何要從一個相對來講好一點的 Weex 技術棧切換到 H5?主要是基於如下幾點考慮:markdown

  • 第一,咱們認爲 H5 的研發體驗必定是最好的,而且在飛豬端內升級 UC 的 U4 內核和 WKWebview 以後,性能咱們認爲和 Native 的差距是逐漸的縮小,因此咱們能夠嘗試去進行 H5 的渲染;
  • 第二,針對以前支付寶小程序的策略,對於小程序的開發場景愈來愈多,而小程序的開發動態性它是不足的,由於它傳統的開發意義和 H5 的體系是比較割裂的,是須要開發兩套代碼。若是一個頁面要分別投小程序和 H5 的話,須要雙倍的開發成本,咱們是比較沒法接受的,畢竟人力那麼寶貴;
  • 第三,咱們仍是但願去統一端技術的方案,但願有一套代碼能夠多端投放,支持 H五、小程序,以及將來的 Flutter。其實已是如今的 Flutter;
  • 第四,Rax1.0 也是能夠支持 Weex,爲何沒有編譯成 Weex?由於 Weex 和小程序都有其須要開發兼容的地方,它都是一個對於傳統 API 的子集以及一些單獨的 API。因此咱們若是同時要適配 Weex 和小程序,對於開發來講是災難性的。底下有一個開發難度的簡單對比,單純的開發 H5是沒有限制的,相信不少小夥伴很樂意去開發,可是小程序它是有必定的限制。若是同時開發 Weex 加小程序,兩端的同時兼容,那將是沒法接受的。而若是是 H5 加小程序,也只須要去單純的適配一個小程序就能夠完成。這樣是相對能夠接受的。

這是一個總體的背景。

面臨的困難

C18-7 太吾-如何在雙11大促中實現會場頁面秒開.005.jpeg

在基於這個背景下,H5 性能確定是比 Weex 性能相對來講要差一點。以前剛切換的 H5 以後,兩次大促(618 大促和國慶),飛豬的會場性能 IOS 大概在 1.5 秒,安卓大概在 2 秒左右。相對比淘系 618 會場的性能 1.4 秒和 2.1 秒,相對來講是差很少的。你們基本上都是把通用的優化手段都用盡了,須要進入一個深水區。對於飛豬雙11 的目標是 IOS 1.2 秒,安卓 1.6 秒,總體是要提高大概 20% 這樣一個水平。在通用手段已經用盡的狀況下,還要提高 20%,這樣也是一個很是大的挑戰。

還有在飛豬這個場景下:

  • 飛豬會場的模塊複雜。運營業務方都針對於旅遊場景有不少的想法,好比頭圖這邊必定是要有視頻的,去吸引別人去玩。以及飛豬這邊互動動畫模塊。還有飛豬榜單類型,也有一些榜單的聚合模塊,這些模塊都是比較複雜的。有些是前端耗時、有些算法耗時。
  • 接口 RT 比較高。而且服務端是沒有辦法優化的。相似榜單這種場景,它是多榜單聚合,有榜單的個性化,而且算法那邊想要去加多種模型,去更加的拉高它的 RT,理論能夠爲點擊率帶來必定的提高,你也沒辦法反駁別人。因此你只能讓它任由的把 RT 升高,而你毫無辦法。
  • 旅行行業的一些特色特徵。咱們的一些個性化或者是一些模塊,都比較依賴於定位信息以及用戶信息來給你們推相應的一些商品,定位信息和用戶信息會更加的拖慢一個首屏的時間,因此這就是整個優化所面臨的一些困難。

優化方向

針對這些困難,視野要從前端這邊就是脫離開來,站在是多職能協同的一個方向,主要藉助於客戶端以及服務端的一些能力,來進行一個總體的優化。

優化思路

C18-7 太吾-如何在雙11大促中實現會場頁面秒開.007.jpeg

總體的一個優化思路,先說一個通用的優化思路:

  • 第一階段白屏。整個好比說相似一個頁面,它的打開的這樣一個進度,從一開始的白屏,主要就是進行一個 Webview 初始化以及主文檔下載,基礎 JS 下載。前幾位講師基本上提到這些過程,前端優化手段確定是依賴於客戶端的緩存,以及減小資源包的大小這些通用手段;
  • 第二階段 Loading 狀況。這邊基本上就是發生數據請求的這樣一個階段,在這個階段可使用的通用手段,就相似服務端優化,請求拆分,把一個頁面的數據能夠分解成首屏和非首屏這樣一個思路。首屏渲染,儘可能少的 DOM,儘可能少的模塊以及一些數據預加載。以前說的數據並行以及客戶端那邊並行發起數據請求方式。以前幾位講師也有提到這裏就不細說了;
  • 最後階段模塊上屏。慢慢的有元素能夠往屏上進行加載。這段時間它主要發生的就是模塊 JS 加載以及模塊渲染。這裏的通用手段基本上也就是對於模塊 JS 精簡以及就是對於模塊的緩存。這裏提一點,咱們會場基本上是搭建的場景,搭建是一個什麼概念?就是一個底部的頁面的 Layout 上面能夠把它想象成根據參數從服務端獲取須要某個頁面須要哪些模塊,再異步的去拉那些模塊下來,把數據灌入那些模塊再進行展現,是這樣一個思路。相似於你如今把你的一個通用型頁面,把它拆分紅不少個模塊去進行渲染,渲染哪些模塊是由服務端的數據來決定的,比較相似搭建這樣的一個場景。

基於這些通用手段你們都想到了,你們都確定必定都會用完的,而用完以後的效果就好比以前提到的像 61八、國慶大促已是一個頂峯,而以後想再進行優化,就要脫離這些進行更進一步的優化。增進式手段就有如下這些:

  • 預渲染。這個是重點保障一個主會場的打開效果。具體的實現以後會提到;
  • SSR。前幾個講師也有提到,咱們如今在 C 端場景可能 SSR 提的就比較少了,用的比較少了。但如今又重提SSR 這是爲何?也是爲了提升秒開率。以前 Weex 的狀況下,其實一直都是提秒開率的,可是切換到 H5 以後,可能確實沒有 Weex 當時這麼好,因此咱們須要藉助一些 SSR 這樣的東西去提高咱們的頁面秒開率;
  • Snapshot。相似前幾位講師說的頁面快照,把頁面的一些數據或者是頁面 HTML 直接儲存下來。在真實數據到來以前,提早展現一個頁面結構,能夠大大提早用戶的可視時間,讓用戶不這麼焦急等待;
  • SPA。單頁應用這樣一個東西。把多個頁面聚合,保障頁面間的跳轉順滑,來提高用戶的體感。

主要就是這 4 點來進行一個雙 11 大促的場景的保障。

C18-7 太吾-如何在雙11大促中實現會場頁面秒開.008.jpeg

總體思路用渲染流程來看,塊條對應上面的渲染流程能夠精簡的部分。能夠看到從上到下 SSR、Snapshop 和預渲染效果會愈來愈好,可是它適用的場景確定也是愈來愈少的。這個以後具體會提到。相似一些客戶端預加載、資源的離線緩存、數據的變形請求和模塊的緩存,這都是一些通用的手段,是跟客戶端集成已經用了好久了。

總體的主要思路,以前也說到的就是壓力轉移,把客戶端的壓力轉化到服務端上去。一些緩存、依賴於客戶端的能力、階段的變形以及最後在對用戶進行一些體感上的優化,給用戶最優秀的體驗。

預渲染

C18-7 太吾-如何在雙11大促中實現會場頁面秒開.009.jpeg

首先說一下預渲染。以前講師也提到預加載,可能飛豬這邊作的更激進一點,能夠先看一下右邊這個效果。左邊開啓預渲染以後,點擊就相似主會場這樣一個膠囊,跳轉過去基本上秒開,沒有任何渲染的過程那種感受。而右邊未開啓預渲染就會有白屏、Loading 以及模塊的加載這樣一個過程,很明顯的一個對比。

什麼是預渲染?客戶端以「離屏」的方式來初始化好容器並 LoadUrl,在上屏以前就完成了頁面的 Rasterization(光柵化)。即客戶端直接把 URL 經過 Webview 在後臺 Load 好,等咱們須要的時候,它直接把 Webview 進行一個上屏的操做就行了,因此作的是比較激進一點。可是爲了是對於主會場這種重點保障,仍是在端側這邊作了這樣一個能力,體驗是比較好。

預渲染它有什麼特色?

  • 無感直出。很明顯的一個體驗;
  • 端側定製。這多是由於是跟端側比較耦合,可能如今只有飛豬端內可使用這樣一個能力;
  • 少許頁面。目前是隻給主會場用了,由於你想一想一個 APP 後臺去一直啓動這樣一個 Webview,它確定比較耗內存,而且是可能會引發一些 crash 風險的。因此只能配少許的頁面,多了確定是 crash 率可能會愈來愈高。

可是這樣一個預渲染方案上了以後,FCP(首屏首次渲染時間)就從 1~2 秒,一直到了前端這邊的 100 毫秒,在客戶端那邊的打點基本上在 50~60 毫秒,就能夠完成一個頁面的展現,至關之快。

方案設計

C18-7 太吾-如何在雙11大促中實現會場頁面秒開.010.jpeg

總體的一個方案的設計,咱們會有一個相似 Orange 這樣一個動態下發的平臺,去配置一些咱們想要預渲染的一個URL,它就會動態下發到一個用戶的 APP 上,APP 獲取到這些配置以後,就會在後臺這邊去加載這樣一個 URL,而且解析頁面,完成頁面的光柵化以後,置入緩存池,咱們還會啓動一個內存預警的監控,保障 APP 的運行穩定,若是有 crash 風險,咱們會自動釋放緩存池中頁面,咱們確定仍是保穩定性爲主,設計了這樣一個內存管控。

當用戶真實的去訪問 H5 頁面的時候,咱們會檢測用戶 是否命中了預渲染的 URL 配置。咱們會有一個 URL域名,以及 URL query 的一些特殊化的參數,進行 key 的對比。若是命中了以後,就會經過 URL 做爲 key,在緩存池中找到 Webview,直接進行一個上屏的操做,GPU 直接進行上屏的顯示。由於用客戶端在後臺已經渲染好這個頁面確定跟前端的一些邏輯不相符合,因此咱們須要在真實的上屏以後,客戶端會派發一個 document 事件來通知 H5 頁面渲染完成以後,前端監聽這個事件以後,咱們會進行一些對於性能埋點的處理、頁面埋點的處理以及最後那些動態投放的一些事件的處理,這些都是在前端須要進行兼容的地方。

作完這些以後,這一個頁面的總體展現邏輯就完成了。在用戶退出這個頁面以後,咱們會清除對應的 Webview 緩存,而且在 300 毫秒後馬上又在後臺從新去啓動這樣一個新的 Webview 去加載這個頁面,從新的去進行下一次的這樣一個總體流程。

預渲染這樣一個方案比預加載只加載一個 Webview 容器,不去請求真實的數據,可能會更加激進一點。可是效果也會相對來講更好一點。

SSR

C18-7 太吾-如何在雙11大促中實現會場頁面秒開.011.jpeg

第二個方案就是 SSR。重啓 SSR 是爲了什麼?通常如今在集團內基本上 SSR 它的定義,從本來的 Server-side-render 慢慢轉移到 Serverless-side-render,順應 Serverless 這樣一個大潮,反正慢慢的發現 SSR 可用武之地。咱們這種不是傳統意義上的 SSR,跟傳統意義上 SSR 就是相似 PC 時代這種主文檔,就直接返回HTML主文檔的那種 SSR。

咱們不一樣的點是看底下這樣兩個渲染流程的對比,上面就是傳統的 CSR 的渲染流程,在藉助客戶端的文檔緩存以及數據的預加載,以後就進行模塊的 JS 和渲染模塊。而咱們這邊,經過這個圖你們能夠看到咱們的 SSR 是在接口中返回的 HTML,在接口返回 HTML 後,咱們去把 HTML 再異步 hydrate 到頁面上去,咱們至關因而省掉了後面加載模塊 JS 和渲染模塊這樣一個流程,由於把 HTML 放在接口中返回,因此接口多是會比日常會更慢一點。咱們認爲把 HTML 直接塞到頁面中去,大概會花 10 毫秒左右的時間。這樣,總體在減掉後面模塊JS 加載和渲染模塊的時間,咱們這邊大概會節省 700 毫秒~800 毫秒的時間,SSR 相對於 CSR 這樣一個對比。

方案設計

C18-7 太吾-如何在雙11大促中實現會場頁面秒開.012.jpeg

整個渲染流程的改變,爲何是基於這樣一個考慮,而不是把在傳統意義上在主文當中直接返回整個頁面的結構,而是在接口返回的時候,返回這樣一個 HTML 來再進行一個渲染。

這背後的思考主要是基於這樣一個考慮:以前手淘那邊也作了這樣一個方案,他們當時作了同步 SSR 放在主文檔中返回。他們當時就發現有同步 SSR 後,一個是白屏時間會變得長,由於它沒法使用客戶端的一些能力,例如離線包以及數據預加載這樣兩個客戶端提供了很好的一個能力。咱們就跟進了異步 SSR方案,也就是放在接口中返回一個 HTML 這樣一個方式。

它有幾個優勢:

  • 減小渲染前的模塊 Load 的時間消耗。就是模塊那邊基本上數據返回回來以後,咱們就能夠進行一個頁面的展現,而不用等模塊在進行一個拉取以及模塊的渲染;
  • 渲染就放在了服務端上,能夠規避高低端機容器的影響。在高端機上可能就是渲染以及模塊拉取這種均可能影響還不大。但對於低端機來講,對於一些模塊的拉取和渲染,這是很是耗時的。而若是把渲染放在服務端上,就能夠規避掉這樣一個高低端機容器的影響;
  • 能夠複用客戶端的一個性能優化的能力。這樣咱們可使用客戶端提供的離線包以及數據預加載的這樣一個能力,就不會浪費客戶端的一些能力。

咱們基於改形成本最小化的這樣一個原則:

  • 基於現有的搭建的鏈路,僅僅增長一個 SSR render 的鏈路;
  • 能夠作到 CSR 到 SSR 的平滑的切換;
  • 僅須要判斷 HTML 是否返回,就能夠切換到不一樣的鏈路去進行渲染,而且模塊能夠基本複用,這樣就造成一個改形成本很是小的SSR 效果。

遇到的困難

C18-7 太吾-如何在雙11大促中實現會場頁面秒開.013.jpeg

  • 一個就是如何進行平滑的切換,就是 SSR 若是出現了問題怎麼辦?怎麼降級回去?基於考慮,因此咱們只須要在前端這邊判斷接口有沒有返回 HTML,就能夠走到不一樣的鏈路上去,這是一個比較直接就能夠解決問題的方法;
  • 前端穩定性的一些考慮。由於 SSR 確定有不少模塊,它可能就是用的一些變量,或者是用的一些異步,可能在服務端那邊拿不到模塊的具體的一個數據,這樣返回的時候可能會出現相似報錯或者相似一開始這個模塊沒有展現出來,以後在 Web 端在 Hydrate 的時候再展現出來,像一個頁面閃動這樣一個狀況。這樣對業務模塊進行一個總體的就是升級,一個是在 SSR 層作一些變量的兜底,以及對模塊進行一些相似佔位這樣的一個處理,保證頁面初始化跟 hydrate 最小更新;
  • 對於沉浸式 titlebar 的一個支持。沉浸式 titltbar 確定是要依賴客戶端的一些變量,就客戶端的 navbar 的高度是沉浸式 titltbar 的一個必要的參數,而 SSR 確定是獲取不到客戶端參數的。因此咱們後來發如今 innerHTML 的時候,是有間隙能夠獲取到這樣一個 titlebar 高度的,咱們在這個時候再經過 style 去動態設置這樣一個高度就能夠實現沉浸式 titlebar 的一個支持;
  • 最後一點,由於咱們如今搭建這邊都是經過統一渲染頁。不管是離線、數據預加載以及一些模塊緩存都是有一個統一渲染頁這樣一個東西。而相似這樣一個統一渲染頁,它進行離線了以後,它裏面的就是 SSR 的配置,就會固定在那裏,就沒法針對於單頁面,就是至關於你全部的頁面要開 SSR 就全開 SSR。咱們有些頁面確定不必定適配好了,或者是基於流量的考慮,不可能全部頁面都開 SSR 的。因此咱們得再加一層攔截去肯定 是走SSR 鏈路仍是普通的 CSR 鏈路。咱們就去進行一個域名的攔截,經過判斷後面的 query 來判斷它是否在白名單中。在白名單中就走 SSR 鏈路,不然就走 CSR 鏈路。

完成這些考慮以後,咱們就成功地上了 SSR 方案,也獲得了不錯的效果,基本上是從以前的 1~2 秒用了 SSR 以後基本上平均耗時能夠降到 1 秒如下。

Snapshot

C18-7 太吾-如何在雙11大促中實現會場頁面秒開.014.jpeg

頁面快照。先看右邊的效果,開啓了 Snapshot 以後,就沒有 Loading 的環節,直接點開頁面,頁面就直接進行一個相似直出的效果。Snapshot 實際上的效果確定是比 SSR 要好的,可是咱們有了 Snapshot 爲何還要 SSR?

  • 首先咱們在營銷頁面這樣一個場景下,回訪率是比較低的。一個頁面用戶第二次去打開這個頁面的機率僅爲10%~30%。因此 Snapshot 它緩存那些數據,它的命中率也就只有 10%~30% 這樣一個運動率;
  • 其次就是 Snapshot 適合的是一種非千人千面的場景。有些東西相似前幾位講師也有說到,就是一個商品的時效性的問題,因此有些場景就不適合用 Snapshot。

針對這個頁面快照,咱們這邊是設計了兩種方案。一種方案是接口緩存,一種方案是傳統意義上的 HTML 緩存。爲何會有這兩種方案的並存?

一種會場天天都會變陣,其實你看雙11或者雙12,你去逛會場,天天模塊的順序以及模塊的數據展現邏輯,運營天天都會去進行修改的。因此天天都會變的狀況下,若是是採用了 HTML 緩存,就不可避免的帶來一些閃動的問題。例如你昨天訪問了這個頁面,今天再訪問這個頁面,它可能中間有幾個模塊沒有了,或者有幾個商品,它的坑位從 4 個變成了 6 個,這樣你進去以後,它整個頁面都會啪啪啪亂閃一氣,而且就這種閃動過程,它其實會可能會帶來不少毛病,一些不可預知的問題。例如就是模塊可能會重複的渲染,而且有些模塊它可能就會錯位這樣一個特別玄學的一些問題。

因此咱們又設計了第二個接口緩存的一個方式,接口緩存配合上模塊緩存,基本上也能夠作到性能和直接 HTML 緩存這樣性能保持基本一致。由於接口緩存配合模塊緩存數據相對來講固定,就避免了閃動,而且咱們爲什麼有並存這樣一個東西,咱們會發現 HTML 緩存也並不是毫無用武之地,就相似右邊這種場景,所有會場這種場景,他在整個大促期間基本上是不會變更的。因此就採用 HTML 緩存帶來更高更快的一個加載效率,是可使用 HTML 緩存。

方案設計

C18-7 太吾-如何在雙11大促中實現會場頁面秒開.015.jpeg

整個的方案設計以下:

  • **HTML 緩存。**它的優勢就是展示的速度快,操做簡單,而且它的劣勢就是在模塊不肯定的環狀況下,頁面可能會閃,可是它適用場景就相似所有會場這種。HTML 緩存就相似你們能夠理解成你在全部的頁面展現完成以後,你去存一個首屏的一個 DOM 到緩存中去,等下次你進入這個頁面,你首先去緩存中取這樣一個 HTML,先把它給塞到屏幕上去,先給它作上屏的操做。等真實的數據回來以後,在對這樣一個界面進行一個 hydrate 操做;
  • **接口緩存。**爲何接口緩存跟頁面快照有關係。由於剛纔說到搭建這樣一個場景,有哪些模塊其實都是接口去進行返回的,數據也是接口返回的。因此咱們只要把接口緩存下來,咱們就知道這個頁面它有哪些模塊,而且那些模塊的數據是什麼,只要把這個接口緩存下來,咱們就能夠經過這個接口直接把頁面進行一個展現。它的優勢就是頁面的展現很穩定,可是劣勢就是相較於 HTML 緩存,它的展現會相對來講較慢一點,而且接口緩存它把整個頁面的一個JS,就是整個接口都給緩存下來,相較於緩存 HTML,它緩存的佔用空間會很大,但它適用的場景就更多了。咱們的一些主要的會場,例如超級寶貝、榜單會場以及特點會場,這些都是使用了這樣一個接口緩存的頁面快照方式。

再提兩點,一些設計上的思路:

  1. 第一個就是 HTML 緩存中,相似咱們有一些時效性的那些商品坑位,咱們不想進行一個 HTML 的保存,DOM 的保存,咱們就能夠自定義一些 class name。去給那些模塊設置上,到保存的時候,咱們會識別這些 class name,去把它進行一個剔除,或者是隻保存父節點這樣一個方式,來進行一個時效性的問題解決。還有你們能夠基於這樣一個 class name 的設計,咱們能夠設計一些相似橫滑列表,咱們只保存前幾項,或者是相似頭圖 banner,咱們只保存第一項就行了。這樣一個減小 HTML 緩存的大小以及效率設計;
  2. 第二個緩存總控。若是緩存無限制的去塞,那確定是不行的。咱們確定是要設計一個緩存的總控來控制緩存的數量。咱們用 LRU (算法)慢慢的去剔除掉使用的最少以及最遠進行訪問的一些緩存的數據,把新的給緩存進來,總體控制一個最大數,咱們當時應該是當時應該是有緩存最多 8 個。超過 8 個以後就會進行一些剔除的一些判斷,這樣就保證一個緩存的穩定性。

SPA

C18-7 太吾-如何在雙11大促中實現會場頁面秒開.016.jpeg

最後一點就是 SPA。咱們慢慢的在頁面中的一些優化,給用戶的體驗也很好了。可是頁面間的一個切換的體驗還不是很好。由於以前其實你看到底下是有 Tabbar。可是它實際上是多個頁面,你若是像以前那種方式去切換底部的 Tab,其實它整個是一個頁面的跳轉,是 replace 方式,整個頁面都會進行一個刷新,這樣體驗是很是很差的。

在雙 11 的時候,咱們對它進行了一個改進。底部 bar 是總體一個包框,咱們經過點擊底部 bar 切換的時候,咱們僅須要去獲取數據。仍是剛纔提到那個點,咱們的頁面是經過數據進行獲取到模塊,經過模塊拼裝組成的。因此咱們只須要知道模塊有哪些,咱們就能夠把頁面組成起來。因此咱們切換 tab 的時候,咱們只須要去獲取數據,去獲取到模塊,把頁面的 DOM 替換一下,咱們就能夠完成到頁面的這樣一個切換,而不用整個的 replace。

爲何基於 SPA 實現,仍是剛纔說到那個點。

  • 搭建頁面已經造成比較成熟的體系,就是咱們的頁面框架,它是共用一套 solution/core-render 的,它不會關聯頁面,就是業務的模塊,它背後的 Layout 它全部的頁面都是一個,只是上面的模塊不一樣,你因此看到的頁面不一樣,其他的後面的 Layout 永遠都是同樣的;
  • 第二點每一個頁面業務模塊它都是經過數據獲取的,這兩個都是必要條件才能夠進行這樣一個 SPA 的切換。它經過數據獲取模塊,咱們只須要進行一個 DOM 的切換,就能夠進行一個頁面間的一個跳轉,跳轉回去的時候,咱們只須要緩存模塊,就能夠造成無感的切換效果。

優化演進

image.png

咱們初版設計開啓了 SPA 以後,咱們就獲取那個模塊的數據,替換當前 tab 對應的模塊,進行頁面的更新。可是咱們發現這樣有一個問題:若是總體去不停的去替換模塊,仍是比較卡頓的。相對於直接傳統意義上咱們心目中那種單頁應用仍是有一點鴻溝,因此咱們就對它進行了升級。

咱們只緩存首屏的 DOM,減小數據獲取的過程。而且在高端機上咱們會請求首個 tab 數據渲染完成以後,咱們會去預加載其餘幾個 tab 的數據。這樣下次切換過去的時候就沒有數據獲取過程,咱們能夠直接取用它。就至關於把多頁面之間的數據同時都拿到以後,咱們切 tab 就能夠造成絲滑般的切換效果。咱們只須要隱藏其餘 Tab 容器內 DOM。把該展現的那些 DOM 給 display 出來就行了。

資源&數據預緩存

C18-7 太吾-如何在雙11大促中實現會場頁面秒開.018.jpeg

最後再提兩個小點,以前講師他們也說到。基本上每一個優化都要藉助客戶端離線能力,離線包和數據的並行請求,我看基本上是 H5 這邊是每次都會用到的。

可是就說一點小的設計,咱們對於會場頁面是設計了一個 **URL + package **方式,咱們會在信鴿,就是咱們一個後臺去輸入須要進行離線的頁面,在會場這種場景下。咱們信鴿就會在後臺跑一個 puppetter,把頁面的資源給獲取到,而且再經過一些滾屏的操做,把一些懶加載的資源也給獲取到。就把整個資源打成一個資源包,最後經過一個hash的方式,在去真實頁面訪問的時候,進行匹配。

第二點,數據並行請求的這樣一個部分,咱們設計了相對於正常的 Memory 命中Miss 不命中這樣一個狀態下,咱們還設計了一個 Ongoing 這樣一個狀態。咱們認爲只要客戶端發起請求,那必定是比前端真實發起請求要快的要提早的,由於實際它確定是要提早的,因此咱們就會等待就是客戶端真實的請求返回以後,咱們再會拿客戶端的那樣一個數據,而不是從新發起一次請求。

總結和規劃

整個這邊就不那麼細說了,反正最終達成了咱們當時這樣一個目標,基於咱們以前說到的不管是通用手段也好,仍是一些增進手段也好。通用手段可能也是提供了很大的一個幫助,增進手段在它的基礎上有個更高的一個提高。反正最終是達成這樣一個目標,而且有了這些東西以後,咱們會有一些將來可期的這樣一種感受。

總結

C18-7 太吾-如何在雙11大促中實現會場頁面秒開.020.jpeg

性能優化,慢慢的就會發現它從前端的這樣一個職能慢慢的上升到多職能協同的這樣一種方式。慢慢你若是去優化,你確定就慢慢不能站在前端的這樣一個視角,慢慢的就會依賴於就相似前面說的 NSR 還有服務端這種 SSR 以及咱們如今還有那種 ESR 就是 CDN 邊緣計算這樣去的一些就是東西,就慢慢你會發現性能優化慢慢是超脫了前端這樣一個單純的職能這樣一個方面,你要站在多智能協同方式進行性能優化的嘗試。

規劃

規劃就不那麼細說提幾點:

  • SSR 同步的方案。咱們以前剛纔說異步在接口中返回 HTML 的方式,異步的方案。同步的方案就是主文檔的那種方式,異步的方案在端內效果是確定很好的,由於它直接離線包以後,經過數據的 prefetch 並行請求以後直接拿到 HTML,直接渲染到屏幕上去,這樣確定是效果很好的。可是在端外,咱們會有不少,好比相似支付寶、手淘這種場景它就用不了端內的一些離線包和 prefetch 這種方式,因此咱們仍是須要進行一些直接主文檔返回的方式;
  • 頁面的 Abtest;
  • 客戶端那邊,要考量接入一下 NativeTab 這樣切換多 Tab 的方式;
  • 喚端狀況下的一些性能優化,這麼多新的優化點,確定須要統一的狀態管理。

這樣等等一系列的內功提高,以及咱們飛豬這邊目標是前端的兩秒達標率要達到 90%。因此單純的單業務,咱們端內的單業務固然就須要去拓展到多業務。咱們就想法是有一個優化手段及如今在集團內咱們是有跨端性能小組是有白皮書這樣一個方式,去記錄一些優化手段,慢慢去 push 各個業務,進行落地,而且去收集各個業務的一些好的優化的手段,來進行沉澱反哺,慢慢去把總體的性能給提升起來。

C18-7 太吾-如何在雙11大促中實現會場頁面秒開.021.jpeg

推薦一本書

C18-7 太吾-如何在雙11大促中實現會場頁面秒開.022.jpeg

最後慣例推薦一本書,這邊推薦的就是《金字塔原理》,它是講一個相似寫 PPT 或者是思考表達和解決方式的這樣一種邏輯。寫 PPT、寫文章之類的這樣一種邏輯,是一套就是邏輯清晰、重點突出、井井有條,簡單易懂的思考表達方式和規範動做。這本書我以爲是挺好的。看了以後對於作 PPT 或者是寫文章,都是由很多的幫助的。你們有興趣的能夠去看一下。

團隊宣傳

最後慣例中的慣例,確定是須要招人的。咱們團隊關因而飛豬的用戶前端和數字化經營團隊,咱們的業務是關於旅遊的一切咱們均可以去嘗試。咱們團隊的基礎事項。以前有咱們團隊的南路,也來分享過 Web Flutter 這樣一個方案,咱們團隊的有 Flutter,那麼以及在咱們如今 SSR 也是咱們團隊基於 Serverless 這樣一個大潮去作的。還有一些中後臺的微前端,以及一體化的開發以及端線互動,以及智能搭建這樣一個東西,咱們團隊技術思想都是包括的。 因此基本上各個方面你們都有包括,因此你們有興趣就等你了,就能夠經過郵箱,P六、P7 多多益善。

你們也能夠關注一下咱們飛豬技術的公衆號,Fliggy F2E 以及掘金,有些以前看到我這篇文章有在掘金上發,也是被咱們飛豬前端這邊專欄去收藏。若是對跨端這邊性能這邊有想法的,也能夠加我微信瞭解一下。


關注前端早早聊,跟進學習更多 BFF/GraphQL,請關注第三十屆|前端早早聊大會 BFF 專場 - 玩轉先後端接口(GraphQL、統一網關、API 接入、API 管理、協議轉換、統一安全切面、高併發處理、可視化編排、統一穩定性建設...)8-14 全天直播,9 位講師,報名上車看直播👉 ):

相關文章
相關標籤/搜索