Hybrid简介

现在的中大型app中,为了满足快速迭代以及动态更新的需求,就往往需要使用混合架构,来达到动态更新的目的。这里就来简单介绍下目前比较主流的混合框架及其优劣。

目前的框架我大致将他归为为3种:

  • X-native
  • web-native
  • template / DSL

X-native

这个目前最具有代表性的就是js-native了,还有一些像lua-native等,由于很久没有人维护了,就不做介绍了。

自从前端框架出现了virtual dom这个技术,就给我们的native化创造了先决条件,下面的技术都是根据virtual dom来驱动的。

react-native

这是一个非常热门的项目了,贡献者就达到了1.4k,是其他项目无法比拟的,可以说是目前世界上最热门的项目之一了。

功能强大,可以说项目本身就基本包含了所有app功能。你可以不用写一行native代码,就能写一整个应用。也可以单独去渲染部分页面,非常灵活。作为一个需要快速迭代和动态更新的页面,往往也不需要特别高的交互性,所以单纯的展示已经足够了,react-native本身所提供的功能其实已经远大于渲染一个页面了。目前我尝试下来也没遇到什么坑。

正因为热门,所以社区支持非常完善,遇到什么问题,google、Stack Overflow上都有答案。所以不用担心遇到什么无法解决的问题。文档和例子也非常完善,有大量优秀的开源组件支持,很多功能都被封装为单独的组件,不需要自己去重新写了。

debug功能非常强大,而且非常好用。而且有非常多第三方的debug tools。比如专门对redux的react-dev-tools。

但是react本身就是一个非常大的话题,需要一定的学习成本。同时react-native的目标并不是统一多平台实现,而是把多平台实现转化到react,所以难以只写一份代码就能兼容所有平台,所以还是需要很多的兼容代码。这样就需要写代码的人对多平台都有所了解,同时又要理解前端技术,可以说这样的人才其实还是很少的。当然,如果只是写比较简单的页面,使用各平台通用的一些组件,还是比较简单的。

这里就有一个例子,之后也会用这个列子来验证:

react-1.png
react-2.png

这里的图片是动态显示的,有才会显示。布局如下

 ------------------
| Title    |       |
| SubTitle | Image |
 ------------------
| name             |
 ------------------

实现如下:

import React from 'react'
import {
  View, Text, Image, StyleSheet
} from 'react-native'
import Sep from './seperator'

export default class Answer extends React.Component {
  render() {
    let {data} = this.props
    return (
      <View style={style.container}>
        <View style={style.content}>
          <View style={style.textContent}>
            <Text style={style.title} numberOfLines={2}>{data.question.title}</Text>
            <Text style={style.subTitle} numberOfLines={3}>{data.description}</Text>
          </View>
          {
            data.images && data.images.length &&
            <Image style={style.image} source={{uri: data.images[0]}} />
          }
        </View>
        <View style={style.textSep}></View>
        <Text style={style.nickName}>{data.author.nickname}</Text>
        <Sep style={style.sep}/>
      </View>
    )
  }
}

let style = StyleSheet.create({
  container: {
    marginLeft: 20,
    marginRight: 20,
    alignItems: 'stretch'
  },
  content: {
    marginTop: 20,
    width: '100%',
    flexDirection: 'row'
  },
  textContent: {
    flexDirection: 'column',
    flexShrink: 1
  },
  image: {
    marginLeft: 10,
    width: 100,
    borderRadius: 2,
    aspectRatio: 1
  },
  textSep: {
    height: 1,
    width: 20,
    backgroundColor: '#ccc',
    marginTop: 10
  },
  title:{
    fontSize: 16,
    lineHeight: 20,
    fontWeight: '600',
    marginTop: 0
  },
  subTitle: {
    marginTop: 8,
    fontSize: 13,
    lineHeight: 17,
    color: '#999'
  },
  nickName: {
    marginTop: 14,
    fontSize: 12,
    color: '#999'
  },
  sep: {
    marginTop: 20
  }
})

在使用下来,没有任何的问题,不论布局还是元素内容。由于使用的是js和jsx,和前端的编码非常类似,所以如果从前端转过来的学习成本会非常低。同时css布局使用的是flex,几乎完全兼容web端的布局方式。

官方的debug工具:

ReactDevToolsInspector.gif

weex

现在来看下非常相似的weex,由阿里出品。号称能多平台使用一份代码。那么真实情况是怎么样的呢?我也去尝试了下。

weex使用的是vue框架,所以更像web的编码方式,所以学习成本会低一些。

weex的文档也比较完整,但是开源组件显然就少了很多。

虽然weex号称能够统一多平台,但是能够使用的特性只有多平台共有的特性,这一点其实react-native也能做到。这样就导致weex被限定在一个比较小的方面了。

同时weex说能够无缝降级为h5实现,然而我实践下来发现其实并不能做到完全的无缝,因为两者之间有些东西并不能等价。react-native降级会更为麻烦一些,还要考虑多平台的原生组件。所以实际上weex的降级方案并没有他说的那么好用。

布局系统,虽然三方(h5,weex,react-native)都可以使用flex布局来实现,但还是有部分出入。react-native和web的flex兼容的最好,上面就是按照web的方式来写的,但是有部分是web没有的。weex比较奇怪,他实现了部分flex功能,同时又自己自创了几个,所以说降级并没有那么好用。下面的例子就是就可以看出来,如果按照web的写法会有一些错乱。

可以这么认为:

react-native flex (Yoga) > web flex > weex flex

weex的社区支持比较小,也就国内的几个厂家在使用,所以能获得的帮助也会少一些。

下面就是使用weex来实现的例子,css和上面的保持一致,发现有些布局已经发生错乱:

weex.png
<template>
  <div class='container'>
    <div class='content'>
      <div class='textContent'>
        <text class='title'>{{answer.question.title}}</text>
        <text class='subTitle'>{{answer.description}}</text>
      </div>
      <image v-show="cover" class='image' :src='cover' ></image>
    </div>
    <div class='textSep'></div>
    <text class='nickName'>{{answer.author.nickname}}</text>
    <div class='sep'/>
  </div>
</template>

<script>
export default {
  props: {
    answer: Object
  },
  computed: {
    cover() {
      return this.answer.images && this.answer.images.length && this.answer.images[0]
    }
  }
}
</script>

<style>
  .container {
    margin-left: 40;
    margin-right: 40;
    align-items: stretch;
  }
  .content {
    margin-top: 40;
    flex-direction: row;
  }
  .textContent {
    flex-direction: column;
    flex-shrink: 1;
    flex-grow: 1;
  }
  .image {
    margin-left: 20;
    width: 200;
    height: 200;
    border-radius: 4;
    flex-shrink: 0;
    /* aspect-ratio: 1; */
  }
  .textSep {
    height: 2;
    width: 40;
    background-color: #ccc;
    margin-top: 20;
  }
  .title {
    lines: 2;
    font-size: 32;
    line-height: 40;
    font-weight: 600;
    margin-top: 0
  }
  .subTitle {
    lines: 3;
    margin-top: 16;
    font-size: 26;
    line-height: 34;
    color: #999;
  }
  .nickName {
    margin-top: 28;
    font-size: 24;
    color: #999;
  }
  .sep {
    margin-top: 40;
    height: 2;
    background-color: #ccc;
  }
</style>

官方的debug工具:

weex-dev-tools1.png
weex-dev-tools2.png
weex-dev-tools3.png

js-native

如果你要问我选用哪个框架,根据上面的两个例子,心里应该就有选择了。react-native是一个非常大型的完善的项目,如果你不想折腾,那么就选择react-native吧。如果你想要极致的选择,你可以尝试下weex。而多平台支持并不是你选择的理由,react-native的子集完全可以做到多平台支持。

H5

这是一个非常古老,但是非常有效的策略了。而且不需要更多的学习成本。缺点当然就是没有native那么的高效。

最有名的当然就是cordova这个开源项目了。他把很多native的功能通过module的方式暴露给web,让web能够使用很多的原生功能。而事实上很多情况下web只是作为一个app的附加功能,并不会给web如此多的权限。所以如果整个app是架构在web的基础上的话,可以尝试下cordova这类的项目。而仅仅是内嵌web,则需要考虑到控制不同的web需要拥有不同的权限。

cordova.png

另外一个非常有名的项目是JSWebviewBridge,他可以让我们定制化的注入几个功能,提供web端调用。这种定制比较简单,也没有module的概念,不能够构建复杂的功能。

h5最为常用和成熟,而且和原生系统关系不大,所以这里就简单介绍下。

Template / DSL

剩下的基本就可以概括为模板技术和DSL技术了。这两者的应用面更加狭窄,往往作为并不要求那么灵活多变的场景。但是这种方式更为稳定和搞笑。

Tangram

淘宝首页的模块化技术。可以想到,淘宝首页对动态化的要求没有那么高,首页的运营都是非常稳定的,样式也是非常稳定的,只有内容变化非常大,那么模板技术就是最适合的了。

其实很多app都在用这种方案,只是做的更加的简单些,比如:

[
    {
      "type": 1,
      "data": {}
    },
    {
      "type": 2,
      "data": {}
    }
]

这种数据结构,type所对应的就是模板的代号。只是Tangram将这个更加的泛化了而已,并且增加了很多后台配置和管理的功能。

官方的例子:

tangram-example1.gif
tangram-example2.gif

Jasonette

这是一个依赖于JSON的DSL,包括布局、事件处理都可以在JSON中配置完成。

布局使用UITableViewUICollectionViewUIStackView来实现,所以也有部分的兼容问题。

同时对于新的DSL,学习成本比较大,也缺乏debug和开发工具,手写JSON太不友好了。

这是我用Jasonette写的例子:

json.png

基本的布局可以实现,但有些布局还是不能很好的完成。

官方的例子:

json-example1.gif
json-example2.gif

samurai-native / BeeFramework

这是利用xml或者html来布局的框架,虽然可以做到绑定事件,但并不能处理事件,所以局限非常大。这两者已经很久没人维护了。

总结

可以看到目前这类想法除了模板技术,其他的都已经被X-native所替代了,因为这种技术的局限性实在是太大了。所以也建议大家慎重考虑这种局限比较大的方案。

最后

以上介绍了目前比较热门的几种hybrid方案,就目前的情况来说,除了h5,其他都在向javascript-native方向发展,可能因为javascript这门语言的火热,同时又有大量前端开发。可见一个方案的优劣还是需要从更大的方面来看待,而不是从功能的实现上来看待,易用和学习成本还是非常重要的。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,723评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,485评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,998评论 0 344
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,323评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,355评论 5 374
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,079评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,389评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,019评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,519评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,971评论 2 325
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,100评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,738评论 4 324
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,293评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,289评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,517评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,547评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,834评论 2 345

推荐阅读更多精彩内容