跳到主要內容
黯羽輕揚每天積累一點點

2020 SSR 落地開花的三大機遇

免費2020-10-17#Mind#SSR#SSR CDN#服务端渲染#搭建+SSR#ssr 2020

時機已到,SSR 落地開花

寫在前面

上篇 SSR 的利與弊 列舉了 SSR 渲染模式的 6 大難題:

  • 難題 1:如何利用存量 CSR 代碼實現同構
  • 難題 2:服務的穩定性和性能要求
  • 難題 3:配套設施的建設
  • 難題 4:錢的問題
  • 難題 5:hydration 的性能損耗
  • 難題 6:數據請求

這些問題是 SSR 一直以來遠不如 CSR 應用廣泛的主要原因,但時至今日,Serverless、low-code、4G/5G 網絡環境三大機遇讓 SSR 出現了新的轉機,落地開花正當時

第一大機遇:Serverless

無服務器計算(serverless computing)將服務器相關的配置管理工作統統交給雲供應商去做,以減輕用戶管理雲資源的負擔

對雲計算用戶而言,Serverless 服務能夠(自動)彈性伸縮而無需顯式預配資源,不僅免去了雲資源的管理負擔,還能夠按使用情況計費,這一特點在很大程度上解決了「難題 4:錢的問題」:

引入 SSR 渲染服務,實際上是在網絡結構上加了一層節點,而大流量所過之處,每一層都是錢

將組件渲染邏輯從客戶端改到服務器執行,勢必會增加成本,但有望通過 Serverless 將個中成本降到最低

另一方面,Serverless Computing 的關鍵是 FaaS(Function as a Service),由雲函數提供常規計算能力

直接運行後端代碼,而無需考慮服務器等計算資源以及服務的擴展性、穩定性等問題,連日誌、監控、報警等配套設施也都開箱即用

也就是說,餵給 FaaS 一個 JavaScript 函數,就能上線一個高可用的服務,無需操心如何承載大流量(幾萬 QPS)、如何保障服務穩定可靠……聽起來有些跨時代是麼,實際上,AWS Lambda、阿里雲 FC、騰訊雲 SCF 都已經是成熟的商業產品了,甚至能夠 免費試用

無狀態的模板渲染工作尤其適合用雲函數(輸入 React/Vue 組件,輸出 HTML)來完成,「難題 2:服務的穩定性和性能要求」最關鍵的後端專業性問題迎刃而解,SSR 面臨的技術難題從一個高可用的組件渲染服務縮小到了一個 JavaScript 函數中

與客戶端程序相比,服務端程序對穩定性和性能的要求嚴苛得多,例如:

  • 穩定性:異常崩潰、死循環(由前端人員自行解決)
  • 性能:內存/CPU 資源佔用(由 FaaS 基礎設施解決)、響應速度(網絡傳輸距離等都要考慮在內)

如何應對大流量/高並發,如何識別故障,如何降級/快速恢復(由 FaaS 基礎設施解決),哪些環節需要加緩存,緩存如何更新……

FaaS 基礎設施解決了大部分的性能問題和可用性問題,函數內的穩定性問題可通過純前端手段解決,至於剩下的響應速度、緩存/緩存更新問題,則需要引入另一個雲計算概念——邊緣計算

邊緣計算

所謂的邊緣計算,就是將計算和數據存儲分佈到離用戶更近的(CDN)節點(或者叫邊緣服務器,Edge server)上,節省帶寬的同時更快響應用戶請求:

Edge computing is a distributed computing paradigm that brings computation and data storage closer to the location where it is needed, to improve response times and save bandwidth.

(摘自 Edge computing

像傳統 CDN 通過縮短靜態內容與最終用戶之間的物理距離來加速資源訪問,同時減少了應用服務器的負載一樣,支持邊緣計算的 CDN 允許將雲函數部署到邊緣節點中,加速服務響應,同時依託 CDN 輕鬆控制緩存策略,甚至能夠實現動靜分離的邊緣流式渲染(ESR)

P.S. 基於邊緣計算的 SSR 的更多信息,見 前端性能優化:當頁面渲染遇上邊緣計算

第二大機遇:low-code

如果說 FaaS 解決了 SSR 落地最核心的服務可用性問題,給 SSR 插上了雙翼,那麼**low-code 則是讓 SSR 得以衝向天際的助飛跑道**

因為low-code 幾乎解決了其餘的所有難題

  • 難題 1:如何利用存量 CSR 代碼實現同構
  • 難題 2:服務的穩定性和性能要求
  • 難題 3:配套設施的建設
  • 難題 4:錢的問題
  • 難題 5:hydration 的性能損耗
  • 難題 6:數據請求

源碼開發模式下難以解決的問題,在 low-code 模式下有了不同維度的解法,就像是通過幾何方法來解決代數問題

難題 1:如何利用存量 CSR 代碼實現同構

要让现有的 CSR 代码在服务端跑起来,先要解决诸多问题,例如:

  • 客户端依赖:分为 API 依赖和数据依赖两种,比如 window/document 之类的 JS API、设备相关数据信息(屏幕宽高、字体大小等)
  • 生命周期差异:例如 React 中,componentDidMount 在服务端不执行
  • 异步操作不执行:服务端组件渲染过程是同步的,setTimeoutPromise 之类的都等不了
  • 依赖库的适配:React、Redux、Dva 等等,甚至还有第三方库等不确定能否跑在 universal 环境,是否需要跨环境共享状态,以状态管理层为例,SSR 要求其 store 必须是可序列化的
  • 两边共享状态:每一份需要共享的状态都要考虑(服务端)如何传递、(客户端)如何接收

首先,low-code 模式不同於源碼開發,現有的 CSR 代碼無法直接遷移到 low-code 平台上來,其次,low-code 配置化的開發模式提供了天然的細粒度邏輯拆分和完整的精細控制力,體現在:

  • 細粒度邏輯拆分:各個生命周期函數獨立配置

  • 完整的精細控制力:依賴庫、生命周期、異步操作、共享狀態嚴格受控,low-code 平台全權控制所填代碼的編譯時、運行時環境

客戶端依賴雖無法消除,但能夠像 函數式編程中的副作用 一樣管控起來,比如將其約束到特定的生命周期函數(componentDidMount)中,使之僅在客戶端執行,避免影響服務端。生命周期的差異可通過 low-code 平台讓用戶產生強感知,比如在編輯、預覽等環節強化差異。對於不支持的異步操作,可在編輯階段進行校驗並提示。至於依賴庫和狀態共享方式,low-code 平台能夠全權控制,將其約束到支持範圍內

總之,low-code 輕鬆解決了源碼開發模式下棘手的如何約束寫法、如何管控不確定性的問題

難題 3:配套設施的建設

SSR 最核心的部分是渲染服務,但除此之外還要考慮:

  • 本地開發套件(校驗 + 構建 + 預覽/HMR + 調試)
  • 發佈流程(版本管理)

一整套的工程設施,在 SSR 模式下都需要重新考慮

這些配套設施是 SSR 要解決的問題,low-code 也面臨同樣的問題,因此,SSR 能夠在一定程度上複用 low-code 提供的在線研發鏈路支持,只對其部分環節進行擴展,降低配套設施建設的成本

難題 5:hydration 的性能損耗

組件作為一層抽象,在提供模塊化開發、組件複用等工程價值的同時,也帶來了一些問題。典型的,交互邏輯與組件渲染機制綁定在了一起,這是 SSR 需要 hydration 的根本原因

客戶端接到 SSR 響應之後,為了支持(基於 JavaScript 的)交互功能,仍然需要創建出組件樹,與 SSR 渲染的 HTML 關聯起來,並綁定相關的 DOM 事件,讓頁面變得可交互,這個過程稱為 hydration

也就是說,只要仍然依賴組件這層抽象,hydration 的性能損耗就無可避免。在源碼開發模式下,組件無可替代,因為沒有與之等價的抽象描述形式。然而,在 low-code 模式下,其輸出產物(配置數據)也是一種抽象描述形式,如果能夠具有與組件同等的表達力,就完全有可能去掉組件這層抽象,不必再背負 hydration 的性能損耗

另一方面,對於無交互(純靜態展示)、弱交互(靜態展示帶埋點/跳轉)的偏靜態場景,low-code 平台也能準確地識別出來,避免不必要的 hydration

難題 6:數據請求

服務端同步渲染要求先發請求,拿到數據後才開始渲染組件,那麼面臨 3 個問題:

  • 數據依賴要從業務組件中剝離出來
  • 缺失客戶端公參(包括 cookie 等客戶端會默認帶上的 header 信息)
  • 兩邊數據協議不同:服務端可能有更高效的通信方式,比如 RPC

low-code 開發模式下,數據依賴以配置化的形式錄入,天然剝離,客戶端公參、數據協議等均可通過 low-code 平台來配置,比如配 HTTP、RPC 兩套協議,按環境自動選用

第三大機遇:4G/5G 網絡環境

移動時代早期,離線 H5 是業界最佳實踐,因為在線頁面意味著秒級的加載時間,離線頁面有著巨大的加載速度優勢

但隨著網絡環境的發展,離線頁面的加載速度優勢已經不再是決定性因素(小程序的大爆發足以說明問題),在線頁面的動態化特性備受關注,(SSR 無能為力的)離線場景越來越少,SSR 的用武之地越來越多

參考資料

評論

暫無評論,快來發表你的看法吧

提交評論