寫給前端的跨平臺方案、跨端引擎的本質

近些年來,前端領域的跨端技術愈來愈多了:react native、weex、flutter、electron、kraken 等等。css

那麼多跨端方案,他們有沒有通用的思路?咱們能不能從這麼多方案中找出本質的原理?前端

本文會嘗試探究探究如下問題:vue

  • 什麼是跨平臺
  • 有哪些方案是跨平臺的
  • 跨端和跨平臺的區別是什麼
  • 前端領域有哪些跨端方案
  • 跨平臺、跨端的通用原理是什麼

什麼是跨平臺

咱們知道,cpu 有不一樣的架構和指令集,上層也有不一樣的操做系統,一個系統的可執行文件在另外一個系統上就是不可執行的,好比 windows 的 exe 文件在 mac 上就不能直接執行。不一樣的系統就是不一樣的運行平臺。可執行文件是不跨平臺的。java

不一樣平臺提供的 api 不一樣,因此代碼邏輯可能也不一樣,須要不一樣平臺單獨維護代碼。這樣就帶來了幾個問題:node

  • 多平臺各自開發,怎麼保證功能是一致的
  • 多平臺各自開發,那是否是得各自測試,開發和測試的人力都是多份的

因此出現了跨平臺的一些技術,目標是一份代碼跑在任意平臺。react

咱們先來看一些各領域的跨平臺方案:ios

瀏覽器

操做系統不一樣,瀏覽器上跑的網頁的代碼確實同一份。瀏覽器就是一種歷史悠久的跨平臺方案。c++

網頁跨平臺不意味着瀏覽器也是跨平臺的,瀏覽器的可執行文件仍是每一個平臺單獨開發和編譯的,可是他們支持的網頁解析邏輯同樣,這樣上面跑的網頁就是跨平臺的。web

瀏覽器提供了一個容器,屏蔽了底層差別,提供了統一的 api(dom api),這樣就能夠實現同一份代碼跑在不一樣平臺的統一的容器裏。這個容器叫作瀏覽器引擎,由 js 引擎、渲染引擎等構成。docker

docker

docker 是一種虛擬化技術,能夠在操做系統之上加一個虛擬層,在這層之上劃分一到多個容器,容器裏再去跑系統、app,這樣能夠實現硬件和軟件的分離,動態分配硬件資源給容器,而且方便 app 運行環境的總體遷移(保存成鏡像)。

docker 很明顯也是一種跨平臺技術,同一個鏡像能夠跑在任何操做系統的 docker 上。只要不一樣操做系統實現一樣的容器便可。

jvm

java 是一門編譯 + 解釋的語言,java 源碼編譯成字節碼,而後字節碼直接在 vm 上解釋執行。

java 爲何這麼火呢?主要是由於跨平臺。

c、c++ 這種語言寫的代碼須要編譯成不一樣操做系統上的可執行文件來跑,並且每一個平臺的代碼可能還不同,須要寫多份。

java 由於提供了 jvm 容器,只要把源碼編譯成 jvm 能解釋的字節碼就好了,並且 jdk 提供了統一的 api,分別由不一樣操做系統的底層 api 來實現,這樣對於 java 代碼來講,不一樣操做系統的代碼是一致的。

jvm 也是經過容器的技術實現了一份代碼跑在多個平臺,並且 jre 提供了統一的 api,屏蔽掉了底層的差別。

node、deno

node 和 deno 也是跨平臺的技術,經過提供一套一致的 api,讓其上的 js 代碼能夠跨平臺。這些 api 也是不一樣平臺各自實現的。

electron

electron 內置了 chromium,併爲其注入了 node 的 api 和一些 GUI 相關的 api,是基於兩大跨平臺技術綜合而成的跨平臺方案。基於這些方案的組合使得 electron 支持用前端技術開發桌面端。

跨平臺方案的優缺點

跨平臺方案的優勢很明顯,就是一份代碼跑在不一樣平臺的一樣的容器內,不用不一樣平臺單獨開發,節省成本。

可是跨平臺方案也有缺點:

  • 由於多了一層容器,因此性能相比直接調用系統 api 會有所降低

  • 爲了實現多平臺的一致,須要提供一套統一的 api,這套 api 有兩個難題:

    • api 怎麼設計。要綜合不一樣平臺的能力,取一個合適的集合來實現。設計上有必定難度。node、deno、java 都抽象了操做系統的能力,提供了各自的跨平臺 api

    • 部分 api 很難作到多平臺的一致性

    • 當容器沒有提供的能力須要擴展的時候比較麻煩,好比 js 引擎的 bridge、 jvm 的 jni、node 的 c++ addon 等都是爲這個容器擴展能力的方式

前端領域的跨端方案

跨平臺指的是跨操做系統,而跨端是指客戶端。

客戶端的特色就是有界面、有邏輯,因此包含邏輯跨端和渲染跨端。主要的客戶端有 web、安卓、ios、iot 設備等。

如今主流的跨端方案有 react native、weex、flutter、kraken 以及各家自研的跨端引擎等。

react native

跨端包括邏輯跨端和渲染跨端,rn 的邏輯跨端是基於 js 引擎,經過 bridge 注入一些設備能力的 api,而渲染跨端則是使用安卓、ios 實現 react 的 virtual dom 的渲染。

其中 native api 和組件(灰色畫出的部分)並無作到雙端一致,並且有的時候擴展圖中灰色部分須要原生配合,混雜 rn 代碼和本身擴展的代碼致使代碼比較難管理。最著名的事件就是 airbnb 從最大的 react native 支持者到棄用 react native。

weex

weex 也是相似的思路來實現跨端的,不過他對接的上層 ui 框架是 vue,並且努力作到了雙端的組件 和 api 的一致性(雖而後續維護跟不上了)。架構和上圖相似。

flutter

flutter 是近些年流行的跨端方案,跨的端包括安卓、ios、web 等。它最大的特色是渲染不是基於操做系統的組件,而是直接基於繪圖庫(skia)來繪製的,這樣作到了渲染的跨端。邏輯的跨端也不是基於 js 引擎,而是自研的 dart vm 來跨端,經過 dart 語言來寫邏輯,

kraken

跨端包括兩部分,渲染跨端和邏輯跨端。有時候只須要渲染跨端、有時候只須要邏輯跨端,有的時候須要完整的跨端引擎,這 3 種狀況都有各自的適用場景。

kraken 就是一個跨端渲染引擎,基於 flutter 的繪圖能力實現了 css 的渲染,實現了渲染的跨端。

自研渲染引擎

跨端引擎很依賴底層實現的組件和 api,用開源方案也同樣得擴展這部分,因此有必定規模的團隊都會選擇自研。

自研跨端引擎會和 rn、weex 不一樣:

  • 渲染部分不須要實現 virtual dom 的渲染,而是直接對接 dom api,上層應用基於這些 dom api 實現跨端渲染。這樣理論上能夠對接任意前端框架。

  • 邏輯部分也是基於 js 引擎,經過 binding 直接注入一些 c++ 實現的 api,或者運行時經過 bridge 來注入一些安卓、ios 實現的 api。

自研跨端引擎的好處是組件和 api 能夠本身擴展,更快的響應業務的需求。其中組件和 api 的雙端一致性,以及統一的 api 的設計都是難點。

跨端的通用原理是什麼

其實跨端和跨平臺的思路相似,都是實現一個容器,給它提供統一的 api,這套 api 由不一樣的平臺各自實現,保證一致的功能。

具體一些的話,跨端分爲渲染和邏輯跨端,有的時候只須要單獨的渲染跨端方案(好比 karen)和邏輯跨端方案,有的時候須要完整的跨端引擎。

weex、react native 的渲染部分都是經過實現了 virtual dom 的渲染,用安卓、ios 各自的渲染方式實現,邏輯部分使用 js 引擎,經過 bridge 注入一些安卓、ios 的 api。

flutter 則是直接使用 skia 繪圖庫繪製,而且邏輯跨端使用 dart vm。

可是無論具體實現怎樣,思路都大同小異:跨端引擎須要實現一個渲染引擎、實現一個 vm,基於這套架構實現各類組件和 api,跨端容器上層對接一個 ui 框架,再上層的業務代碼能夠基於容器的 api 實現跨端的渲染和邏輯

web container

這兩天 web container 比較火,其實也是一種跨平臺技術,它是在瀏覽器裏面實現的容器,經過 wasm 實現了 node 的 api,這樣在這個容器裏面能夠跑 node 代碼。其實思路比較常見,可是是一個新場景。

瀏覽器容器之上又跑了個容器,容器套娃。

總結

咱們聊了跨平臺和跨端的區別,跨平臺是指跨操做系統,而跨端則是指跨客戶端。

跨平臺技術聊了 docker、瀏覽器、jvm、node、deno、electron、web container 等,他們都是跨平臺(操做系統)的方案,跨平臺有優勢也有缺點,缺點就在於 api 的設計比較難,node、deno、java 等都有本身的一層 api 設計;api 一致性的保障也比較困難;其次就是擴展方式複雜一些(jvm 的 jni、node 的 c++ addon 等)。

跨端方案聊了 react native、weex、flutter、kraken 等,有的是綁定了 react、vue 等前端框架,直接從 virtual dom 渲染,有的是實現了 dom api,能夠對接任意前端框架。固然能夠單獨作渲染或邏輯跨端。渲染跨端或者用安卓、ios 提供的方式,或者本身繪製,邏輯跨端或者用 js 引擎(能夠對接前端框架)或者用 dart vm。

但願這篇文章可讓你理解跨端和跨平臺的容器的思路和優缺點,遇到一些新技術(好比 web container)也能快速的理解。

相關文章
相關標籤/搜索