欧美三级国产三级日韩三级_亚洲熟妇丰满大屁股熟妇_欧美亚洲成人一区二区三区_国产精品久久久久久模特

在 2020 年,談小程序框架該如何選擇 - 新聞資訊 - 云南小程序開發(fā)|云南軟件開發(fā)|云南網(wǎng)站建設(shè)-昆明葵宇信息科技有限公司

159-8711-8523

云南網(wǎng)建設(shè)/小程序開發(fā)/軟件開發(fā)

知識

不管是網(wǎng)站,軟件還是小程序,都要直接或間接能為您產(chǎn)生價值,我們在追求其視覺表現(xiàn)的同時,更側(cè)重于功能的便捷,營銷的便利,運營的高效,讓網(wǎng)站成為營銷工具,讓軟件能切實提升企業(yè)內(nèi)部管理水平和效率。優(yōu)秀的程序為后期升級提供便捷的支持!

您當(dāng)前位置>首頁 » 新聞資訊 » 小程序相關(guān) >

在 2020 年,談小程序框架該如何選擇

發(fā)表時間:2021-1-11

發(fā)布人:葵宇科技

瀏覽次數(shù):51

微信并不是第一個做小程序的 App,而是做小程序最有優(yōu)勢的 App,比如高流量、用戶較長的停留時間等等。站在微信的視角,小程序從業(yè)務(wù)形式上更像是公眾號開發(fā)的演變產(chǎn)物。在更早的時候,微信通過 sdk 的形式,增強(qiáng)了開發(fā)者開發(fā)公眾號網(wǎng)頁的能力。小程序的誕生是微信本身邁向平臺化超級 App 的 業(yè)務(wù) 行為,并且?guī)椭脩舾玫膶崿F(xiàn)了「輕量級 Web App」。

微信小程序誕生之初就自己定義了一套”標(biāo)準(zhǔn)“,與前端已有的生態(tài)格格不入,最開始的框架甚至沒有組件、沒有 npm,和 Web 生態(tài)嚴(yán)重脫節(jié)。由于特殊的雙線程模型與四不像的語法,開發(fā)者苦不堪言。小程序的 開放 只是對三方業(yè)務(wù)的開放而已。

蜂擁而至的效仿

其它廠商看到了小程序業(yè)務(wù)的開放性,試圖也能夠做成平臺型 App。支付寶小程序、百度小程序、淘寶小程序、360小程序、快應(yīng)用......它們中的大多數(shù)都不約而同的選擇了和微信類似的架構(gòu)、框架,而這更多的不是從技術(shù)角度去做的決定,而是想盡可能蹭微信小程序的福利,讓開發(fā)者可以更快的投放到自己的平臺。當(dāng)然,其中有兩個稍顯不同。一個是早期的淘寶小程序,它不僅支持 axml 的寫法,同時還支持 sfc -- 用 Vue 來開發(fā),這個架構(gòu)更大程度上讓開發(fā)者有了選擇的權(quán)利,并且能夠更好地連接已有的前端生態(tài)。另一個是快應(yīng)用,也是用類似 Vue 的語法來開發(fā),但是略顯畸形的是它自己又造了一套標(biāo)準(zhǔn),更像是對 Vue 進(jìn)行了魔改,開發(fā)者的開發(fā)成本并沒有得到有效的提升。

小程序框架選擇

小程序原生語法 and 增強(qiáng)型框架

小程序原生語法

是不是原生語法一定是被唾棄的。站在 2020 年這個時間節(jié)點上來說, 并不是這樣 。單純就微信小程序 or 支付寶小程序而言,目前的小程序生態(tài)是完完全全足夠開發(fā)者利用前端已有的部分生態(tài)來開發(fā)出符合預(yù)期的應(yīng)用的。

與早期 npm 能力的缺失、只能通過模板渲染實現(xiàn)組件化相比而言。現(xiàn)在的小程序已經(jīng)能夠做到前端工程化,并且植入前端生態(tài)中已有的一些理念,例如狀態(tài)管理、CLI 工程化等等。

也就是說,當(dāng)業(yè)務(wù)的需求只有投放到微信小程序或者支付寶小程序的時候,原生語法完完全全可以成為前端程序員們的一個選擇。你可以組件化你的項目,你可以手寫一個或者使用社區(qū)已有的狀態(tài)管理庫來顆粒化管理組件狀態(tài),你甚至還可以直接用 TypeScript 來編寫你的應(yīng)用??傊?,你幾乎可以把你所習(xí)慣的東西都帶到小程序這個域里。

漸進(jìn)增強(qiáng)型框架

所謂漸進(jìn)增強(qiáng)型框架,更多的還是在小程序引入 npm 之后,有了更加開放的能力所帶來的收益。這類框架一般依然是以小程序原生語法為主,只是在邏輯層引入了增強(qiáng)語法來優(yōu)化應(yīng)用性能或者提供更便捷的使用方法,

以騰訊開源的 omix 框架為例,先簡單看一下它的用法:

邏輯層

create.Page(store, {
  // 聲明依賴
  use: ['logs'],
  computed: {
    logsLength() {
      return this.logs.length
    }
  },
  onLoad: function () {
    //響應(yīng)式,自動更新視圖
    this.store.data.logs = (wx.getStorageSync('logs') || []).map(log => {
      return util.formatTime(new Date(log))
    })
    setTimeout(() => {
      //響應(yīng)式,自動更新視圖
      this.store.data.logs[0] = 'Changed!'
    }, 1000)
  }
})
復(fù)制代碼

視圖層

<view class="container log-list">
  <block wx:for="{{logs}}" wx:for-item="log">
    <text class="log-item">{{index + 1}}. {{log}}</text>
  </block>
</view>
復(fù)制代碼

先不談它的語法是否符合直覺或者好用。簡單來說,它整體 保留小程序已有的語法 。但是在此基礎(chǔ)之上,對它進(jìn)行了擴(kuò)充和增強(qiáng),比如引入了 Vue 中比較有代表性的 computed ,比如能夠直接通過 this.store.data.logs[0] = 'Changed' 修改狀態(tài)??梢哉f是在小程序原生半 Vue 半 React 的語法(此處  只是數(shù)量詞)背景下,徹底將其 Vue 化的一種方案。

使用增強(qiáng)型框架最大的好處是,你可以在只引入極少依賴,并且保留對小程序認(rèn)知的情況下,用更加 舒爽 的語法來寫代碼。這類框架對于目標(biāo)只投放到特定平臺小程序的開發(fā)者或者非專業(yè)前端而言是比較好的選擇之一。因為你只需要關(guān)注很少的新增文檔和小程序自身的文檔就足夠了。畢竟在推動某項技術(shù)的過程中,團(tuán)隊的學(xué)習(xí)成本也是需要考慮的。

轉(zhuǎn)換類框架

相比于漸進(jìn)增強(qiáng)型框架,轉(zhuǎn)換類框架的使命是完全不同的。轉(zhuǎn)換類框架的使命是讓開發(fā)者 幾乎不用感受 小程序原生語法,更大程度對接前端已有生態(tài),并且可以實現(xiàn)**「一碼多端」 的業(yè)務(wù)訴求,只是最后的 構(gòu)建產(chǎn)物**為小程序代碼。隨著這幾年的發(fā)展,轉(zhuǎn)換類框架大的方面分為兩種 -- 編譯時/運行時。下文會分別針對兩種方案進(jìn)行分析。

Rax 編譯時/Taro 2.0

顧名思義,編譯時方案的核心是通過編譯分析的方式,將開發(fā)者寫的代碼轉(zhuǎn)換成小程序原生語法。這里以 Rax 編譯時和 Taro 2.0 為例,面向開發(fā)者的語法是類 React 語法,開發(fā)者通過寫有一定語法限制的 React 代碼,最后轉(zhuǎn)換產(chǎn)物 1:1 轉(zhuǎn)換成對應(yīng)的小程序代碼。

以一段簡單的代碼為例:

Rax:

import { createElement, useEffect, useState } from 'rax';
import View from 'rax-view';

export default function Home() {
  const [name, setName] = useState('world');
  useEffect(() => {
    console.log('Here is effect.');
  }, [])
  return <View>Hello {name}</View>;
}
復(fù)制代碼

轉(zhuǎn)換之后的小程序代碼:

邏輯層

import { __create_component__, useEffect, useState } from 'jsx2mp-runtime/dist/ali.esm.js'

function Home() {
  const [name, setName] = useState('world');
  useEffect(() => {
    console.log('Here is effect.');
  }, []);
  
  this._updateData({
    _d0: name
  });
}

Component(__create_component__(Home));
復(fù)制代碼

視圖層

<block a:if="{{$ready}}">
  <view class="__rax-view">{{_d0}}</view>
</block>
復(fù)制代碼

編譯時方案最大的特點就是,開發(fā)者雖然寫的是類 React 語法,但是轉(zhuǎn)換后的代碼和漸進(jìn)增強(qiáng)型框架非常類似。開發(fā)者可以比較清晰的看出編譯前后代碼的 對應(yīng)關(guān)系 。

簡單來說,編譯時方案會通過 AST 分析,將開發(fā)者寫的 JSX 中 return 的模板部分構(gòu)建到視圖層,剩余部分代碼保留,然后通過運行時墊片模擬 React 接口的表現(xiàn)。

以一個簡單的 return <View>Hello world</View> 為例,如果想要提取到 <View>Hello world</View> ,你可以寫這段解析代碼:

// 省略定義 babel parser 和包裝 traverse 的部分
const code = fs.readFileSync(FILE_PATH);
const ast = parser(code);
traverse(ast, {
  ReturnStatement(path) {
    const targetNodePath = path.get('argument');
    if (targetNodePath.isJSXElement()) {
      // 如果 return 的子元素是一個 JSX Element 就收集 or 處理一下
    }
  }
})
復(fù)制代碼

targetNodePath 就是 <View>Hello world</View> 的節(jié)點路徑,關(guān)于 AST 相關(guān)的文章可以自行搜索一下,babel 的 handle book 已經(jīng)比較詳細(xì)了,再加上這個 輔助網(wǎng)站 基本是沒有什么門檻的。

但是這個方案其實是存在明顯的優(yōu)勢和劣勢的。

優(yōu)勢

  • 運行時性能損耗低
  • 目標(biāo)代碼明確,開發(fā)者所寫即所得
  • 運行時、編譯時優(yōu)化

在這個方案中,你可以輕易的做到和漸進(jìn)增強(qiáng)型框架一樣的效果,即給予開發(fā)者 更多的語法支持 以及 默認(rèn)的性能優(yōu)化處理 ,比如避免多次 setData ,亦或是長列表優(yōu)化等等。

劣勢

  • 語法限制高

由于需要完全命中開發(fā)者在模板部分所用到的所有語法,這就對編譯時框架的實現(xiàn)者有相當(dāng)高的要求。因為大部分前端開發(fā)者們其實已經(jīng)對靈活的語法有一定的依賴性,比如會使用高階組件,比如在條件判斷的時候?qū)懞芏?nbsp;return 等等。進(jìn)一步的,由于是 1:1 編譯轉(zhuǎn)換,開發(fā)者在開發(fā)的時候還是不得不去遵循小程序的開發(fā)規(guī)范,比如一個文件中定義只能定義一個組件之類的。

目前在阿里巴巴集團(tuán)內(nèi)部,Rax 的這套編譯時方案 已經(jīng)落地了很多業(yè)務(wù) ,包括「電影演出」小程序等,從開發(fā)者的實踐來看,如果能夠掌握編譯時開發(fā)的技巧,即保證最終 return 的模板的簡潔性,語法限制其實還是在可以接受的范圍內(nèi)的。

Rax 運行時/Remax/Taro Next

運行時方案相比于上面的編譯時方案,最大的優(yōu)勢是可以 幾乎沒有任何語法約束 的去完成代碼編寫。這對于開發(fā)者而言,無疑是最大的吸引力,高階組件用起來! createProtal 用起來!但是在小程序領(lǐng)域上暫時還不可能存在這么好的事情,這也是小程序原生語法最后的 執(zhí)拗 。沒有語法限制帶來的更多的性能上的犧牲,這個與運行時方案的實現(xiàn)方式有很大的關(guān)系,接下來我詳細(xì)介紹一下。

從渲染的角度來看,這套方案更貼近于 富文本 渲染。邏輯層將一個和節(jié)點渲染信息相關(guān)的 組件樹 傳遞給視圖層,視圖層通過節(jié)點類型判斷然后進(jìn)行視圖渲染。下面這個圖簡要的描述了一下整個過程:

雖然只用了 維護(hù) 兩個字,但是邏輯層做的事情其實比較復(fù)雜。首先要做的是,去處理節(jié)點間的關(guān)系,去模擬 appendChild / removeChild / updateNode 等各個行為來操作 VDOM 樹。其次比較重要的是去模擬事件,在邏輯層每一個節(jié)點類會繼承自 EventTarget 基類,這個和 W3C 是一樣的,然后通過 nodeId 作為標(biāo)識去收集需要監(jiān)聽的事件,當(dāng)視圖層通過 action 觸發(fā)了某個節(jié)點的事件之后,再通過原生小程序事件中的 event.currentTarget.dataset.nodeId 獲取到目標(biāo)節(jié)點的 id,最終觸發(fā)目標(biāo)回調(diào)。

由于本文篇幅問題,不會更加詳細(xì)的介紹其中的各個部分更加具體的實現(xiàn),感興趣的同學(xué)可以通過 Rax 的源碼或者 npm init rax demo 起一個項目通過最終的產(chǎn)物來研究整個原理。

在目前這個階段,即使是運行時方案,也有不同的實現(xiàn)思路。以 Kbone (Rax 運行時方案是從 Kbone 改造而來) 和 Taro Next 都是通過模擬 Web 環(huán)境來徹底對接前端生態(tài),而 Remax 只是簡單的通過 react reconciler 連接 React 和小程序。

從業(yè)務(wù)訴求來看,筆者認(rèn)為,Rax 和 Taro Next 可能會比 Remax 更加開放。首先,需要考慮是三部分的訴求,(1)毫無語法限制,既然已經(jīng)沒有了語法限制,為什么不能用前端更加熟悉的方式來開發(fā),即擁有操作 DOM 的權(quán)利;(2)不和 DSL 耦合,盡管在阿里巴巴集團(tuán)內(nèi),對 React 的認(rèn)可度更高,但是從實現(xiàn)原理上來看,和某個框架進(jìn)行強(qiáng)綁定一定不是最優(yōu)解;(3)舊有的 Web 業(yè)務(wù)遷移,今天我們所面對的開發(fā)者,很多都是因為業(yè)務(wù)壓力或者其他情況需要將原有的 Web 頁面遷移到小程序上,那么用模擬 Web 環(huán)境這套方案是最好不過了,根據(jù)我們的測試,大部分業(yè)務(wù)幾乎可以無縫遷移過來。

害!說了這么多漂亮話,運行時方案 真的很香 ,但這 并不是救世主 ,我來說說它的劣勢。**劣勢 1:**數(shù)據(jù)傳輸量大,我們需要將完整的組件樹在邏輯層傳輸?shù)揭晥D層;**劣勢 2:**頁面上存在大量的監(jiān)聽器,每一個組件都需要無時無刻監(jiān)聽所有的事件,在事件不斷觸發(fā)的過程中,通過 nodeId 篩選出真正需要觸發(fā)的事件;**劣勢 3:**模板遞歸渲染,如果使用原生語法,原生框架可以在渲染前就知道頁面大概的結(jié)構(gòu),來對渲染進(jìn)行優(yōu)化,但是如果僅僅只是通過類似 <view a:if="{{node.tagName === 'view'}}"></view> 這樣的信息,是很難判斷頁面的真實結(jié)構(gòu)的。

組合

魚和熊掌雖然不能兼得,但是可以各要一半~再次強(qiáng)調(diào),本文 不是廣告文 。如果編譯時和運行時方案共存呢?基于淘系前端 高度現(xiàn)代的工程化 積累,開發(fā)者已經(jīng)習(xí)慣通過區(qū)塊來組建項目。更得益于,Rax 在編譯時和運行時方案都有所積累,我們希望能夠?qū)⑦\行時方案和編譯時方案組合使用。對于基礎(chǔ)復(fù)雜或者對于性能有要求的模塊通過編譯時實現(xiàn)。然后再通過 npm 包的形式,引入到運行時的項目中去,從而有效降低了運行時方案的性能損耗,并且能保證絕大部分的業(yè)務(wù)場景可以用 無限制 的語法完成,而開發(fā)者所面對的都是 Rax DSL。

用一個 Demo 來看下:

// 這是一個倒計時組件,通過編譯時實現(xiàn),然后發(fā)布為 rax-taobao-countdown
import { createElement } from 'rax';
import View from 'rax-view';

function CountDown(props) {
  // 省略各種邏輯...
  return <View>{day}:{hours}:{minutes}:{seconds}</View>
}

export default CountDown;
復(fù)制代碼
// 運行時項目
import { createElement } from 'rax';
import CountDown from 'rax-taobao-countdown';

function Home() {
  return <CountDown now={Date.now()} />
}
復(fù)制代碼

假設(shè),我們這個倒計時組件結(jié)構(gòu)非常復(fù)雜,并且要求極高的交互性。那么,開發(fā)者可以通過編譯時方案開發(fā)一個高性能 CountDown 組件,然后在運行時項目中引入使用。此時,視圖層所得到的節(jié)點樹信息大致如下:

{
  "tagName": "custom-component",
  "type": "element",
  "behavior": "CountDown",
  "children": []
}
復(fù)制代碼

而不會有更多更深層結(jié)構(gòu)的節(jié)點信息,有效避免剛剛說的運行時方案中存在的劣勢。

Web 才是未來

小程序原生語法 絕對不是 小程序 or 下一代的渲染方案。通過微信小程序現(xiàn)有的語法規(guī)范來對開發(fā)者進(jìn)行 綁架 ,只會讓更多的人想突破圍城。微信小程序似乎已經(jīng)意識到了這一點,從目前的迭代來看,微信小程序引入了越來越多 Web 已有的東西,包括通過 wxs 在視圖層就可以一定程度上操作 DOM,甚至獲取到邏輯層組件實例等等,這個可以給現(xiàn)有的轉(zhuǎn)換類框架提供更多的可能性。但是,如果小程序如果一開始設(shè)計的不這么糟糕呢,我們可能會失業(yè)(開個玩笑)?

對于業(yè)務(wù)的開發(fā)者而言,「一碼多端」才是效率最大化的。今天的業(yè)務(wù)需求可能只是投放到小程序容器,明天的需求可能就是投放到 Web,未來甚至 是 Flutter。Web 是最貼近前端開發(fā)者的,有組織保障(W3C)的規(guī)范。所以,站在 2020 年這個時間點,無論是框架提供者,還是業(yè)務(wù)開發(fā)者都應(yīng)該更多的從標(biāo)準(zhǔn)的角度思考問題,這樣才能讓業(yè)務(wù)代碼有更多的可能性。

總結(jié)

距離小程序誕生已經(jīng)過去很多年,2020 年應(yīng)該如何選擇業(yè)務(wù)合適的小程序框架,這個需要開發(fā)者衡量利弊之后再做出選擇。因為每個業(yè)務(wù)的形式不同,應(yīng)用的存活時間也不相同,根據(jù)自己的需要選擇可能才是最好的,本文只是從一個全局的視角對所有類型的框架進(jìn)行分析,希望能夠讓正在看文章的你,不那么糾結(jié)~

相關(guān)案例查看更多