<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          寫給前端的跨平臺方案、跨端引擎的本質(zhì)

          共 3855字,需瀏覽 8分鐘

           ·

          2021-05-29 08:20

          近些年來,前端領(lǐng)域的跨端技術(shù)越來越多了:react native、weex、flutter、electron、kraken 等等。

          那么多跨端方案,他們有沒有通用的思路?我們能不能從這么多方案中找出本質(zhì)的原理?

          本文會嘗試探究探究以下問題:

          • 什么是跨平臺
          • 有哪些方案是跨平臺的
          • 跨端和跨平臺的區(qū)別是什么
          • 前端領(lǐng)域有哪些跨端方案
          • 跨平臺、跨端的通用原理是什么

          什么是跨平臺

          我們知道,cpu 有不同的架構(gòu)和指令集,上層也有不同的操作系統(tǒng),一個系統(tǒng)的可執(zhí)行文件在另一個系統(tǒng)上就是不可執(zhí)行的,比如 windows 的 exe 文件在 mac 上就不能直接執(zhí)行。不同的系統(tǒng)就是不同的運行平臺。可執(zhí)行文件是不跨平臺的。

          不同平臺提供的 api 不同,所以代碼邏輯可能也不同,需要不同平臺單獨維護(hù)代碼。這樣就帶來了幾個問題:

          • 多平臺各自開發(fā),怎么保證功能是一致的
          • 多平臺各自開發(fā),那是不是得各自測試,開發(fā)和測試的人力都是多份的

          所以出現(xiàn)了跨平臺的一些技術(shù),目標(biāo)是一份代碼跑在任意平臺。

          我們先來看一些各領(lǐng)域的跨平臺方案:

          瀏覽器

          操作系統(tǒng)不同,瀏覽器上跑的網(wǎng)頁的代碼確實同一份。瀏覽器就是一種歷史悠久的跨平臺方案。

          網(wǎng)頁跨平臺不意味著瀏覽器也是跨平臺的,瀏覽器的可執(zhí)行文件還是每個平臺單獨開發(fā)和編譯的,但是他們支持的網(wǎng)頁解析邏輯一樣,這樣上面跑的網(wǎng)頁就是跨平臺的。

          瀏覽器提供了一個容器,屏蔽了底層差異,提供了統(tǒng)一的 api(dom api),這樣就可以實現(xiàn)同一份代碼跑在不同平臺的統(tǒng)一的容器里。這個容器叫做瀏覽器引擎,由 js 引擎、渲染引擎等構(gòu)成。

          docker

          docker 是一種虛擬化技術(shù),可以在操作系統(tǒng)之上加一個虛擬層,在這層之上劃分一到多個容器,容器里再去跑系統(tǒng)、app,這樣可以實現(xiàn)硬件和軟件的分離,動態(tài)分配硬件資源給容器,并且方便 app 運行環(huán)境的整體遷移(保存成鏡像)。

          docker 很明顯也是一種跨平臺技術(shù),同一個鏡像可以跑在任何操作系統(tǒng)的 docker 上。只要不同操作系統(tǒng)實現(xiàn)同樣的容器即可。

          jvm

          java 是一門編譯 + 解釋的語言,java 源碼編譯成字節(jié)碼,然后字節(jié)碼直接在 vm 上解釋執(zhí)行。

          java 為什么這么火呢?主要是因為跨平臺。

          c、c++ 這種語言寫的代碼需要編譯成不同操作系統(tǒng)上的可執(zhí)行文件來跑,而且每個平臺的代碼可能還不一樣,需要寫多份。

          java 因為提供了 jvm 容器,只要把源碼編譯成 jvm 能解釋的字節(jié)碼就行了,而且 jdk 提供了統(tǒng)一的 api,分別由不同操作系統(tǒng)的底層 api 來實現(xiàn),這樣對于 java 代碼來說,不同操作系統(tǒng)的代碼是一致的。

          jvm 也是通過容器的技術(shù)實現(xiàn)了一份代碼跑在多個平臺,而且 jre 提供了統(tǒng)一的 api,屏蔽掉了底層的差異。

          node、deno

          node 和 deno 也是跨平臺的技術(shù),通過提供一套一致的 api,讓其上的 js 代碼可以跨平臺。這些 api 也是不同平臺各自實現(xiàn)的。

          electron

          electron 內(nèi)置了 chromium,并為其注入了 node 的 api 和一些 GUI 相關(guān)的 api,是基于兩大跨平臺技術(shù)綜合而成的跨平臺方案。基于這些方案的組合使得 electron 支持用前端技術(shù)開發(fā)桌面端。

          跨平臺方案的優(yōu)缺點

          跨平臺方案的優(yōu)點很明顯,就是一份代碼跑在不同平臺的同樣的容器內(nèi),不用不同平臺單獨開發(fā),節(jié)省成本。

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

          • 因為多了一層容器,所以性能相比直接調(diào)用系統(tǒng) api 會有所下降

          • 為了實現(xiàn)多平臺的一致,需要提供一套統(tǒng)一的 api,這套 api 有兩個難題:

            • api 怎么設(shè)計。要綜合不同平臺的能力,取一個合適的集合來實現(xiàn)。設(shè)計上有一定難度。node、deno、java 都抽象了操作系統(tǒng)的能力,提供了各自的跨平臺 api

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

            • 當(dāng)容器沒有提供的能力需要擴(kuò)展的時候比較麻煩,比如 js 引擎的 bridge、 jvm 的 jni、node 的 c++ addon 等都是為這個容器擴(kuò)展能力的方式

          前端領(lǐng)域的跨端方案

          跨平臺指的是跨操作系統(tǒng),而跨端是指客戶端。

          客戶端的特點就是有界面、有邏輯,所以包含邏輯跨端和渲染跨端。主要的客戶端有 web、安卓、ios、iot 設(shè)備等。

          現(xiàn)在主流的跨端方案有 react native、weex、flutter、kraken 以及各家自研的跨端引擎等。

          react native

          跨端包括邏輯跨端和渲染跨端,rn 的邏輯跨端是基于 js 引擎,通過 bridge 注入一些設(shè)備能力的 api,而渲染跨端則是使用安卓、ios 實現(xiàn) react 的 virtual dom 的渲染。

          其中 native api 和組件(灰色畫出的部分)并沒有做到雙端一致,而且有的時候擴(kuò)展圖中灰色部分需要原生配合,混雜 rn 代碼和自己擴(kuò)展的代碼導(dǎo)致代碼比較難管理。最著名的事件就是 airbnb 從最大的 react native 支持者到棄用 react native。

          weex

          weex 也是類似的思路來實現(xiàn)跨端的,不過他對接的上層 ui 框架是 vue,而且努力做到了雙端的組件 和 api 的一致性(雖然后續(xù)維護(hù)跟不上了)。架構(gòu)和上圖類似。

          flutter

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

          kraken

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

          kraken 就是一個跨端渲染引擎,基于 flutter 的繪圖能力實現(xiàn)了 css 的渲染,實現(xiàn)了渲染的跨端。

          自研渲染引擎

          跨端引擎很依賴底層實現(xiàn)的組件和 api,用開源方案也一樣得擴(kuò)展這部分,所以有一定規(guī)模的團(tuán)隊都會選擇自研。

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

          • 渲染部分不需要實現(xiàn) virtual dom 的渲染,而是直接對接 dom api,上層應(yīng)用基于這些 dom api 實現(xiàn)跨端渲染。這樣理論上可以對接任意前端框架。

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

          自研跨端引擎的好處是組件和 api 可以自己擴(kuò)展,更快的響應(yīng)業(yè)務(wù)的需求。其中組件和 api 的雙端一致性,以及統(tǒng)一的 api 的設(shè)計都是難點。

          跨端的通用原理是什么

          其實跨端和跨平臺的思路類似,都是實現(xiàn)一個容器,給它提供統(tǒng)一的 api,這套 api 由不同的平臺各自實現(xiàn),保證一致的功能。

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

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

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

          但是不管具體實現(xiàn)怎樣,思路都大同小異:跨端引擎需要實現(xiàn)一個渲染引擎、實現(xiàn)一個 vm,基于這套架構(gòu)實現(xiàn)各種組件和 api,跨端容器上層對接一個 ui 框架,再上層的業(yè)務(wù)代碼可以基于容器的 api 實現(xiàn)跨端的渲染和邏輯

          web container

          這兩天 web container 比較火,其實也是一種跨平臺技術(shù),它是在瀏覽器里面實現(xiàn)的容器,通過 wasm 實現(xiàn)了 node 的 api,這樣在這個容器里面可以跑 node 代碼。其實思路比較常見,但是是一個新場景。

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

          總結(jié)

          我們聊了跨平臺和跨端的區(qū)別,跨平臺是指跨操作系統(tǒng),而跨端則是指跨客戶端。

          跨平臺技術(shù)聊了 docker、瀏覽器、jvm、node、deno、electron、web container 等,他們都是跨平臺(操作系統(tǒng))的方案,跨平臺有優(yōu)點也有缺點,缺點就在于 api 的設(shè)計比較難,node、deno、java 等都有自己的一層 api 設(shè)計;api 一致性的保障也比較困難;其次就是擴(kuò)展方式復(fù)雜一些(jvm 的 jni、node 的 c++ addon 等)。

          跨端方案聊了 react native、weex、flutter、kraken 等,有的是綁定了 react、vue 等前端框架,直接從 virtual dom 渲染,有的是實現(xiàn)了 dom api,可以對接任意前端框架。當(dāng)然可以單獨做渲染或邏輯跨端。渲染跨端或者用安卓、ios 提供的方式,或者自己繪制,邏輯跨端或者用 js 引擎(可以對接前端框架)或者用 dart vm。

          希望這篇文章可以讓你理解跨端和跨平臺的容器的思路和優(yōu)缺點,遇到一些新技術(shù)(比如 web container)也能快速的理解。

          瀏覽 38
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  免费无码一区二区三区 | 操丝袜熟女骚逼 | 五月婷综合 | 免费视频91蜜桃 | 亚洲中文字幕影院 |