乡下人产国偷v产偷v自拍,国产午夜片在线观看,婷婷成人亚洲综合国产麻豆,久久综合给合久久狠狠狠9

  • <output id="e9wm2"></output>
    <s id="e9wm2"><nobr id="e9wm2"><ins id="e9wm2"></ins></nobr></s>

    • 分享

      Rax,完美融合編譯時與運行時的雙引擎小程序框架

       西北望msm66g9f 2020-05-06

      作者:阿里巴巴淘系前端工程師 弗申 逆葵

      Rax Github Repo——https://github.com/alibaba/rax[1]

      Rax 小程序官網(wǎng)——https://rax./miniapp[2]

      經(jīng)過持續(xù)的迭代,Rax 小程序迎來了一個大的升級,支持全新的運行時方案。站在 2020 年初這個時間點,我們想從 Rax 小程序的特點出發(fā),進行一次全面的梳理與總結,并且在文末附上了 Rax 與當前主流的小程序開發(fā)框架的對比。本文將從 API 設計與性能雙引擎架構、優(yōu)秀的多端組件協(xié)議設計基于 webpack 的工程架構四個方向展開。

      一、API 設計與性能

      當決定一個產(chǎn)品的技術選型的時候,我們往往會從幾個方面考慮,1)可用生態(tài),即周邊相關的工具是否滿足產(chǎn)品開發(fā)的條件;(2)風險率,即出現(xiàn)問題是否能夠快速定位解決,所使用的技術是否會持續(xù)維護;(3)上手成本,即需不需要很大代價才能達到能夠使用的階段;(4)性能,即能夠滿足產(chǎn)品既定的性能標準以及用戶體驗。

      本節(jié)主要會介紹 Rax 小程序在后面兩點上的優(yōu)勢。

      API 設計

      框架整體的上手成本是比較小的,Rax 小程序鏈路從框架上是繼承自 Rax(構建多端應用的漸進式類 React 框架)。所以只要你會 Rax Web/Weex 開發(fā)或者 React,那么你就會用 Rax 開發(fā)小程序,并且可以同時投放到 Rax 所支持的其它端。

      但是由于小程序端的特殊性,總會存在無法抹平以及需要單獨處理的地方。得益于 Rax 已經(jīng)做了比較久的多端方案,我們認為,每個端獨立的屬性不應該入侵基礎框架本身,保證基礎框架的純凈有利于做更多的擴展。

      以下面的代碼為例:

      Taro:

      import Taro, { Component } from '@tarojs/taro'
      import { View, Text } from '@tarojs/components'

      export default class Index extends Component {
      config = {
      navigationBarTitleText: '首頁'
      }

      componentWillMount () { }

      componentDidMount () { }

      componentWillUnmount () { }

      componentDidShow () { }

      componentDidHide () { }

      render () {
      return (
      <View>
      <Text>1</Text>
      </View>

      )
      }
      }

      Rax

      import { createElement, Component } from 'rax';
      import View from 'rax-view';
      import Text from 'rax-text';
      import { isMiniApp } from 'universal-api';
      import { registerNativeListeners, addNativeEventListener, removeNativeEventListener } from 'rax-app';

      function handlePageShow() {}

      class Index extends Component {
      componentWillMount () { }

      componentDidMount () {
      if (isMiniApp) {
      addNativeEventListener('onShow', handlePageShow);
      }
      }

      componentWillUnmount () {
      if (isMiniApp) {
      removeNativeEventListener('onShow', handlePageShow);
      }
      }

      render () {
      return (
      <View>
      <Text>1</Text>
      </View>

      )
      }
      }

      if (isMiniApp) {
      registerNativeListeners(Index, ['onShow']);
      }

      export default Index;

      在和 Taro 的對比中,可以看出主要是兩點差異:(1)Rax 沒有 componentDidShow componentDidHide 的概念,新增了和 W3C 標準類似的 addNativeEventLisenter removeEventListener 等 API;(2)組件實例上沒有一個叫做 config 的靜態(tài)屬性用來設置頁面的 title 等配置。

      這就是前文所說的不入侵基礎框架本身,React 本身其實是沒有 componentDidShow 這些概念,因為這和組件本身的生命周期其實是無關的。我們更期望引導用戶用標準的 API 來寫業(yè)務代碼。同時,這種寫法的設計帶來的還有性能相關的提升,后文會具體說明。

      當然這種設計本身會導致代碼量一定的膨脹,但是通過工程上的手段,是可以保證最后產(chǎn)物代碼的體積幾乎毫無差異。

      性能

      小程序的性能問題是在業(yè)務開發(fā)中經(jīng)常會遇到的,為此 Rax 小程序現(xiàn)有的編譯時方案也做了很多的努力。通過阿里小程序真機云測的功能,我們對一個無限下拉的列表做了測試。

      頁面結構如下:

      根據(jù)真機測試報告,原生小程序三次平均是 2008 ms,Taro 是 2003ms,Rax 是 1924ms,當然其實相差并不多,但是實際的業(yè)務場景其實遠比上面的頁面結構更加復雜。

      與 Taro 類似的,Rax 小程序側的基礎框架沒有在邏輯層弄一個 VDOM,而是通過數(shù)據(jù)合并、傳統(tǒng)的數(shù)據(jù) diff,來避免用戶更新冗余的數(shù)據(jù)。更多的是,阿里小程序原生提供了私有方法 $spliceData來進行性能優(yōu)化,Rax 底層會去識別用戶需要更新的值是否是數(shù)組,然后自動根據(jù)場景使用 $spliceData 來優(yōu)化渲染。

      另外需要提到的是,前面說的原生事件監(jiān)聽,小程序本身需要預先注冊才能監(jiān)聽事件(這也是為了保障性能),即需要:

      Page({
      onShow() {}
      });

      而不能動態(tài)注冊:

      const config = {}
      Page(config);
      setTimeout(() => {
      config.onShow = () => {};
      }, 1000);

      所以加入 componentDidShow 這類概念真的不是好的做法,這會導致頁面由于不知道是否需要注冊 onShow 屬性而將所有的原生事件全部注冊監(jiān)聽,這不僅會造成開發(fā)者不能靈活擴展,更會導致內存泄漏的風險。

      于是 Rax 小程序引入了 registerNativeListeners ,只給開發(fā)者一種新的認知,就是需要先在頁面上注冊事件才能進行監(jiān)聽。這樣不僅解決了擴展性的問題,還解決了潛在的性能問題。

      當然,Rax 小程序能做的性能優(yōu)化到此為止了么?在可計劃的未來,Rax 小程序編譯時方案已經(jīng)有一些明確的 action,比如進一步減輕框架對 props 更新的管理,更多的利用小程序原生的能力來實現(xiàn)組件更新,從而避免和小程序基礎框架做重復的事情導致性能損耗。

      二、雙引擎架構

      Rax (可能)是業(yè)界首個同時支持編譯時和運行時方案的小程序解決方案。兩種方案之間的切換無比簡單,我們將高性能 or 完整語法的選擇權真正地交給了用戶。雙引擎驅動的 Rax 小程序架構如下:下面我們將分別介紹兩種編譯方案。

      編譯時方案

      Rax 小程序編譯時方案是基于 AST 轉譯的前提下,將 Rax 代碼通過詞法、語法分析轉譯成小程序原生代碼的過程。由于 JavaScript 的動態(tài)能力以及 JSX 本身不是一個傳統(tǒng)模板類型語法,所以在這個方案中引入一個較為輕量的運行時墊片。

      Rax 小程序編譯時架構的核心主要分為兩個部分,AST 轉譯運行時墊片。下文會針對這兩個部分做簡要的介紹。

      AST 轉譯

      AST 轉譯部分的架構相比同類產(chǎn)品 Taro 來說,更加清晰以及可維護性更強。這里不得不提到,它的分語法場景轉譯以及洋蔥模型。我們可以粗略的看一下,分語法場景轉譯部分的代碼結構:

      可以比較清晰的看到,針對需要轉譯的每一個語法場景都有一個模塊專門負責轉譯,這就讓整個轉譯的過程輕松了起來,只要每一部分的轉譯結果符合預期,那么轉譯結果就是符合預期的。這樣的設計可以讓我們能夠充分利用單元測試來對轉譯前后的代碼進行比較。

      而洋蔥模型的設計則是AST 轉譯的另一個主要設計,整個轉譯過程實際上分為 4 個步驟:

      洋蔥模型主要進行的是后面三步,在 parser 層將原有的 AST 樹修改為符合預期的新 AST 樹,然后在 generate 層將新的 AST 樹轉譯成小程序代碼。

      運行時墊片

      由于 JSX 的動態(tài)能力以及 Rax 原本提供的一些例如 hooks 之類的特性。所以,Rax 小程序編譯時方案提供了一個運行時墊片,用來對齊模擬 Rax core API 。

      既然引入了運行時,自然可以基于這套機制對數(shù)據(jù)流做更多的管理,以及提供 Rax 工程在其他端上的 API,比如路由相關的 history location 等。

      運行時方案

      Rax 小程序的運行時方案沒有自研,而是『站在了巨人的肩膀上』,復用了 kbone[3] 的架構并對其作了一定程度的改造以接入 Rax 小程序的工程體系。關于運行時方案的實現(xiàn)原理可以點擊這里[4]查看,此處不再詳細介紹。首先需要介紹的是 Rax 小程序同時也是 kbone 的優(yōu)點:

      1. 支持更為完整的前端框架特性。相比較 Rax 編譯時方案,現(xiàn)在你可以使用完整的 Rax 語法,并且 Rax 所有的特性都已經(jīng)支持。忘記那些條條框框的語法約束吧;
      2. 可高度復用 Web 端邏輯。如果用戶已有 Web 端的 Rax 程序代碼,可能只需稍作修改,就能將整個應用完整移植到小程序端,大大提升了開發(fā)效率;
      3. 小程序端運行時,仍然可以使用小程序本身的特性,比如小程序內置組件等。

      而在 kbone 的基礎上,Rax 小程序運行時方案還新增了不少特性,概括起來有以下幾點:

      1. 支持支付寶小程序。由于 kbone 的定位,其只支持微信小程序。Rax 基于 kbone,結合支付寶小程序的特點,拓展了對支付寶小程序的支持?,F(xiàn)在,想在開發(fā)支付寶小程序時使用運行時方案,不僅可以使用 Remax,你還有 Rax 可以選擇;
      2. 接入完整的 Rax 工程體系。現(xiàn)在,你可以在使用運行時方案時感受到 Rax 工程的所有特點,比如 Rax 多端 API、多端組件、多端構建器等,享受完整一致的體驗;

      最后,我們也不能回避的是,Rax 小程序運行時方案具有所有運行時方案都存在的問題:性能損耗。事實上,運行時方案就是以一定的性能損耗來換取更為全面的 Web 端特性支持。所以,如果你對小程序有一定的性能要求,建議使用編譯時方案;如果對性能要求不高,那么運行時方案就是助你快速開發(fā)小程序的利器。雙引擎驅動的 Rax 小程序,總有一處能夠擊中你的內心。

      三、優(yōu)秀的多端組件協(xié)議設計

      Rax 小程序編譯時方案支持項目級開發(fā)和組件級開發(fā)。與 Taro 將組件統(tǒng)一在項目中進行編譯產(chǎn)出為小程序代碼不同,Rax 在組件工程中即可構建出小程序組件。結合一套優(yōu)秀的多端組件協(xié)議設計,我們做到了在 Rax 小程序項目和原生小程序項目中都能正常使用 Rax 小程序組件,同時保持統(tǒng)一的多端開發(fā)體驗。該協(xié)議定義在 package.json 中的 miniappConfig 字段中,其具體用法設計可以參見文檔 Rax 小程序——多端組件開發(fā)[5]。

      支持漸進式接入 Rax

      對于那些已經(jīng)使用原生語法開發(fā)了完整的小程序的開發(fā)者來說,一個很合理的需求就是漸進地切換到 Rax 開發(fā)鏈路上來,畢竟整個項目遷移可能成本高昂。而 Rax 依托多端組件協(xié)議,能夠幫助開發(fā)者平滑過渡。

      按照設計,Rax 小程序組件工程的構建產(chǎn)物為符合小程序語法的組件,因此其理所當然可以直接在原生小程序項目中使用。這意味著,如果你想漸進式地使用 Rax 來開發(fā)小程序,可以以組件或者頁面為單位將之前使用原生語法開發(fā)的小程序逐漸地遷移到 Rax 上來。而這,也是 Taro 等其他框架不具備的能力。在 Rax 的使用方中,浙江省網(wǎng)上政務平臺『浙里辦』支付寶小程序即采用了漸進式接入 Rax 的方式。

      多端統(tǒng)一的組件使用體驗

      當使用 Rax 組件工程發(fā)布的小程序組件在 Rax 項目中使用時,構建器會自動通過 miniappConfig 規(guī)定的路徑去尋找該組件的小程序實現(xiàn)從而實現(xiàn)替換。用戶在業(yè)務代碼編寫層面無需像傳統(tǒng)引入原生小程序組件的方式一樣寫具體路徑,而是與 Web/Weex 端保持一致即可,示例如下:

      // Wrong
      import CustomComponent from 'custom-component/miniapp/index'

      // Correct
      import CustomComponent from 'custom-component'

      除此之外,多端組件協(xié)議還可以擴展成多端組件庫協(xié)議,支持更靈活的類似 import { Button } from 'fusion-mobile' 的寫法。以 Rax 多端組件協(xié)議為基礎,你可以快速為你的多端項目開發(fā)通用組件或者組件庫。比如,Rax 基礎組件[6]就都是以該方式開發(fā)的。

      四、基于 webpack 的工程架構

      Rax 工程以阿里巴巴集團前端統(tǒng)一的 CLI 工具 @alib/build-script[7] 為基礎,其依賴 webpack,通過插件體系支持各個場景,同時基于 webpack-chain 提供了靈活的 webpack 配置能力,用戶可以通過組合各種插件實現(xiàn)工程需求。Rax 小程序的編譯時方案通過 webpack loader 來處理自身邏輯。以 app/page/component 等文件角色分類的 webpack loader 會調用 jsx-compiler 進行代碼的 AST 分析及處理,再將處理完的代碼交由 loader 生成對應的小程序文件;運行時方案直接復用 Web 端的編譯配置,再通過額外的 webpack 插件生成具體的小程序代碼。

      相比其他自研的工程體系,整套架構具有如下優(yōu)點:

      • 基于 webpack,靈活且可擴展型強
      • 插件體系,可復用性強
      • 命令簡潔,體驗統(tǒng)一

      總結

      最后,附上 Rax 和現(xiàn)有主流小程序框架的對比。以上是我們對 Rax 小程序的核心競爭力的階段性總結與思考。小程序已經(jīng)不是初生牛犢,小程序的解決方案也早已汗牛充棟,但我們相信,Rax 的入局,會讓你的小程序開發(fā)有那么一些不一樣。

      更多關于 Rax 小程序的內容,歡迎訪問 https://rax./miniapp 了解!

      參考資料

      [1]

      https://github.com/alibaba/rax: https://link.zhihu.com/?target=https%3A//github.com/alibaba/rax

      [2]

      https://rax./miniapp: https://link.zhihu.com/?target=https%3A//rax./miniapp

      [3]

      kbone: https://github.com/wechat-miniprogram/kbone

      [4]

      這里: https://wechat-miniprogram./kbone/docs/guide/principle.html

      [5]

      Rax 小程序——多端組件開發(fā): https://rax./docs/guide/multiple-ends-component-development

      [6]

      Rax 基礎組件: https://rax./docs/components/introduce

      [7]

      @alib/build-script: https://www./package/@alib/build-scripts

      關注我們

        本站是提供個人知識管理的網(wǎng)絡存儲空間,所有內容均由用戶發(fā)布,不代表本站觀點。請注意甄別內容中的聯(lián)系方式、誘導購買等信息,謹防詐騙。如發(fā)現(xiàn)有害或侵權內容,請點擊一鍵舉報。
        轉藏 分享 獻花(0

        0條評論

        發(fā)表

        請遵守用戶 評論公約

        類似文章 更多