跨平臺方案哪家強?帶你領略 React Native 大法

摘要:

目前流行的兩個智能手機操作系統 iOS 和 Android,各自爲營,互不相通。一般情況下,開發一款APP需要兩支隊伍,分別針對 iOS 和 Android 平臺進行開發。爲了節約人力成本,有人就想到了跨平臺開發解決方案。最近幾年有多種跨平臺開發方案相繼出現,其中由 Facebook 推出的 React Native 框架是目前最完善、最受歡迎的一個。本文主要從 React Native 的實現原理、優缺點剖析、技術選型的思考這三個方面進行闡述。

 

一、 React Native簡介

 

1. React Native 誕生背景

Android 和 iOS 兩大陣營共存,同一款 APP,企業需要兩支開發隊伍。由於企業要考慮開發成本和迭代速度,那麼就有人想過跨平臺開發方案。在移動開發流行五六年後,2015年4月,FaceBook 開源了自己的跨平臺開發框架 React Native,很快就吸引了全球開發者的眼球,衆多公司紛紛嚐鮮。它的口號是 “Learn once, write anywhere”,聽起來很誘人嗷。

可以看出,跨平臺開發是民心所向,未來趨勢。關鍵還有熱更新功能。

 

2. React Native 架構設計

RN使用Javascript語言,和類似於HTML的JSX、以及CSS的頁面佈局來開發移動應用,類似React網頁開發。而實際調用的是兩個平臺的原生控件。所以用戶體驗很好,可以媲美原生APP。

整體分爲三大塊:

1)Native, 管理UI更新及交互。界面上顯示的所有元素,都是原生控件。安卓平臺上就是安卓的控件,iOS上就是iOS的控件。

2)JavaScript,實現業務功能。這裏是和開發者直接打交道的部分,我們寫的JS代碼就在這一部分。

3)Bridge, 在二者之間傳遞消息(通過JSON消息相互通信)。這個是 React Native 的靈魂所在,它不僅承擔了傳遞消息的角色,而且還有其他重要的工作要做,例如計算圖渲染層(由 Shadow Tree 來完成)。

下圖可以表示這三個模塊的結構:

 

再來看看這三個模塊之間是怎麼配合工作的:

 

舉個栗子,屏幕上有個藍色按鈕,點擊以下讓它變成紅色,這個動作在 React Native 程序中是這樣完成的:

  • 屏幕上的原生按鈕接收到點擊事件;
  • 告訴 Bridge 層,“嘿,我被點擊了一下”;
  • Bridge 層接收到這個消息,把消息打包成 JSON 數據,扔給 JavaScript 層;
  • JavaScript 層知曉後,執行我們寫的代碼,“把按鈕的顏色改成紅色”;(這個時候按鈕的顏色還沒真正改變)
  • JavaScript 層“把按鈕顏色改成紅色”的這個動作發給 Bridge 層;
  • Bridge 層把這個動作(命令)打包成 JSON 數據,發給 Native 層;
  • Native 層把按鈕的顏色改成紅色。

3. React Native 線程模型

React Native 主要有三個線程,分別是:

1)UI Thread: 應用中的主線程;爲了保證界面的流暢性,所有 UI 執行都是在這個線程。

2)JS Thread: JavaScript 代碼在這個線程執行;

3)Shadow Thread: 進行佈局計算和構造UI界面的線程。

 

二、JavaScript (ES6)

React Native 用JavaScript開發,其中ES6 目前基本成爲業界標準。(以下是一些ES6特性的介紹,只關心 RN 的可以直接跳過這一節

一些常用的ES6特性:

1. let + const 塊級作用域和常量;

var x = '全局變量';
{
    let x = '局部變量';
    console.log(x); // 局部變量
}
console.log(x); // 全局變量

// let表示聲明變量,而const表示聲明常量

const a = 1
a = 0 //報錯
const student = { name: 'cc' }
student.name = 'yy';// 不報錯  (就是對象所指向的地址沒有變就行)

2. 模板字符串

$("body").html(`This demonstrates the output of HTML content to the page, including student's ${name}, ${seatNumber}, ${sex} and so on.`);

3. 箭頭函數

var add = (a, b) => a + b;

4. 函數的參數默認值

function printText(text = 'default') { 
    console.log(text); 
}

5. Spread / Rest 操作符

let aaa = [1, 2, 3, 4];
console.log(...aaa); // 1 2 3 4

6. 對象和數組解構

const student = {
    name: 'Sam',
    age: 22,
    sex: '男'
}
// ES6
const { name, age, sex } = student;
console.log(name + ' --- ' + age + ' --- ' + sex);

7. 類中的繼承和超集

8. Promise

usePromise(1000).then(() => {
    console.log("use promise 1");
    return usePromise(1000);
}).then(() => {
    console.log("use promise 2");
    return usePromise(1000);
}).then(() => {
    console.log("use promise 3");
    return usePromise(1000);
}).then(() => {
    console.log("use promise 4");
})

9. Modules

import:

export var firstName = 'Michael';
export default function () {
    console.log('foo');
}

export:

import { firstName, lastName, year } from './profile';
import React, { Component, PropTypes } from 'react';
import * as React from 'react';

以上幾個點是 ES6 新特性中的一部分,也是最常用的幾條。篇幅原因,寫的比較簡單。更詳細的內容可以參考 https://babeljs.io/docs/en/learn

 

三、開發體驗,優缺點總結

優點:

1. 跨平臺-最大的優點,代碼複用率95%以上;

2.熱更新-避免每次迭代提交APP商店審覈,和漫長等待;

3. UI調試方便-不用像原生開發那樣每次編譯;

4. css-layout佈局-方便;

5. 有個好爹,Facebook,會越來越完善;

6. 節約公司成本,是‘小而快’團隊的最佳選擇。

 

缺點:

1. 整體開發體驗不如iOS原生開發;

2. 功能相比原生還不夠完善,部分控件缺失,第三方控件不如原生豐富;

3. 兩個平臺還沒完全統一,部分控件平臺專屬,表現有平臺差異;

4. 文檔相對粗略,有滯後性,一些細節性問題在官方文檔上找不到答案;

5. 升級RN版本或需要大動干戈,向下兼容不好;

6. 增加IPA和APK包大小。

PS:缺點寫的比較狠,別被嚇住了哈。

 

四、選用新技術我們是這樣思考的:

 

1. 怎麼實現的跨平臺?

簡而言之,用JS封裝兩個平臺的控件,開發者只需要編寫JS代碼,基本不用考慮平臺特性。是用JS把兩個風馬牛不相及的平臺統一了起來了。

 

2. 性能如何?

既然是封裝了原生控件,那性能應該不會差,無非就是多了一個JS解釋器和幾個線程,對於手機設備來說幾乎可以忽略不計。(但低端安卓手機上動畫表現不佳) (項目性質。對我們的項目無影響)

 

3. 是否可持續?

a. 他爸是Facebook

b. 社區很活躍

c. 有很多企業在用

 

4. 適合我們嗎?

a. 跨平臺需求的緊迫性

b. 技術成本和人力成本

c. 熱更新需求

d. 項目複雜度

 

五、話題延展

 

1. 是否可以和原生混合開發?

可以,現有原生裏嵌套RN頁面。JS和原生可以通過橋接相互調用。

 

2. 和flutter比如何?

沒有深入研究過flutter,道聽途說得知:

1)有團隊專門做過性能測試,各有利弊,基本不相上下;

2)flutter用Dart語言,有一定學習成本,開源時間不長,成熟度不如RN;

3)可以作爲興趣研究一下

 

3. 爲什麼沒有選擇用Flutter?

a. flutter 當時處於初級階段,我們應該避免成爲早期喫螃蟹的人;

b. 有經驗的開發者少,Dart 語言較爲陌生。RN開發者相對較多。JavaScript 語言已經被廣泛使用;

c. 性能方面和 RN 不分伯仲,沒有明顯優勢。

 

六、總結

以上從 React Native 的誕生背景、實現原理、使用體驗、優缺點分析和技術選型的策略進行了闡述,中間還植入了 ES6 的一些新特性。希望能從宏觀上帶你瞭解 React Native, 爲你在技術選型上提供一些參考。

技術選型是項非常需要謹慎的事情,選好了會給團隊和項目帶來很大的便捷,選錯了有可能會造成災難。這其中有很多因素的考慮,以及技術調研和驗證。

我是2017年在項目中使用過一年 React Native,那個時候後的版本是0.41。那個時候遇見了很多坑,填了很多坑。時隔兩年之後,在新公司又開始使用 React Native,目前的版本是0.62,比起兩年前的情況好了很多。再加上 expo 助力,現在的開發體驗還是不錯的。

 

 

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章