在万物互联(Internet of Things,简称IoT)时代,JS(JavaScript)语言越来越重要了,并且受到了很多开发者小伙伴的关注。HarmonyOS也选择JS作为其应用开发的一种语言,肯定有不少好奇的小伙伴想知道:JS语言有什么优势呢?JS被应用在了HarmonyOS的哪些方面呢?下面就为各位好奇的小伙伴们一一揭晓。
一、IoT时代的应用开发挑战
随着技术的进步发展,各种消费电子产品开始遍布人们生活的方方面面,为人们的生活带来前所未有的便利快捷。同时,一个万物互联的时代也若隐若现。在IoT时代,消费电子产品将通过有线/无线网络互联,以软硬件资源共享和协同的方式,为人们的生活提供丰富多彩的服务。应用程序作为服务的载体,软件开发者开发适合IoT时代的应用程序需要面对以下严峻挑战:
挑战1:如何实现一次开发,多端部署?
IoT时代的终端电子设备差异较大(从KB级内存的耳机到GB级内存的手机)、形态各异(有屏幕和无屏幕)、尺寸各异(小到耳机大到汽车)、交互方式各异(触屏控制和声音控制等),对每种设备都开发一个应用是不可接受的,所以如何实现一次开发,多端部署是需要面对的第一个挑战。
挑战2:如何利用业界已有的生态资源,避免大规模重复造轮子?
因为软件的模块化的特点,应用程序开发可以通过模块重用来大大降低开发的复杂性和缩短开发周期。在IoT时代,这样的需求更为强烈,因为开发者要面对更多终端设备,就更需要利用好业界已有的开发生态资源,避免大规模重复造轮子。
挑战3:如何提高应用开发效率和支持快速升级?
IoT时代多种终端运行的需求,会使得软件开发更为复杂,也带来了更大的开发和维护成本。特别是IoT时代要求更快速的软件迭代和升级,大的软件安装包会增加应用快速迭代升级的困难。如何减少软件复杂性(比如代码规模)和提升开发升级效率是非常有挑战的问题。
上述IoT时代的挑战需要从操作系统到编程语言一整套的解决方案,比如需要统一的操作系统对终端设备进行管理和协同,提升全场景用户体验等。本文主要从编程语言的角度来讨论如何应对这些挑战。
二、JS语言的优势
针对上述IoT时代的应用开发挑战,我们考察了目前业界常见的移动端编程语言(比如Java、JS、Swift、Dart和C++)后发现,JS在以下方面可以较好地应对这些挑战:
1. 多端分发和运行
JS执行引擎有许多业界的高性能实现和应用框架解决方案,比如:
- 应用在各种物联网设备上支持KB级内存的JerryScript
- 应用在多种移动操作系统的UI框架上的高性能JS引擎,比如ReactNative中的hermes引擎
- 广泛使用在浏览器(Chrome和Safari)的高性能引擎V8和JSC
- 应用在服务端(或者云端)的优秀编程框架Node.js
- 应用在桌面端的Progress-Web Application和Electron-based Application等优秀解决方案
可见JS语言很适合开发各种形态的终端设备上的应用,而且具有很好的跨平台、跨设备、全栈的特点。
2. 生态和开放性
JS有非常强大的生态社区,并且在业界享有非常高的声誉。
- 在TIOBE的排名报告中,JS一直连续几年被评为排名前五的编程语言。
- 在著名网站StackOverflow的2020年调查中,JS是开发人员中最受欢迎的语言。
- 在GitHub的2020年度报告中,JS是使用GitHub的5600万开发者中最流行的编程语言。
- 有大量使用JS的业界知名公司,包括Google、Microsoft、Alibaba、Facebook等。
而且JS社区有大量的成熟高性能第三方代码和模块,可以非常方便地用于搭建JS应用和服务。这样可以极大降低JS应用开发的复杂性和技术门槛。特别是,目前蓬勃发展的小程序生态(比如微信小程序、淘宝小程序、支付宝小程序、字节跳动小程序和快应用)也选择了JS作为应用开发语言。
此外,JS的标准Ecmascript由TC39标准委员会制定,不属于任何一家公司,是属于业界开放标准。在业界有各种各样的高性能JS语言开源实现,同时整个JS社区也积极地吸纳最新的特性提案,比如各种object-oriented programming(面向对象的程序设计,简称OOP)语言特性,来快速迭代JS的语言规范。
3. 开发效率和性能
相比静态类型开发语言,JS因为动态类型和类脚本语言的特点,开发类似功能的应用时,JS代码一般行数更少。在经过ES2015版本迭代之后,JS原生支持了大型应用开发需要的OOP编程范式和完善的异步编程模型,使得 JS开发大型复杂OOP应用更为高效。另外,随着JS各种方言(比如TypeScript)的出现,通过添加静态类型标注,IDE自动导航和代码查找补齐功能得到极大提升,从而有效地提升了JS开发大型工程的便利性和可维护性。
在性能方面,随着Just-in-time-compiler(即时编译器,简称JITC)的引入,JS的性能也得到了质的提升,特别是当JS程序的动态类型在执行过程中趋于稳定时,JITC够生成非常高效的机器码,从而提升大型JS应用的性能。不过对于移动应用来说,JITC也会带来一定的响应性能的开销,所以未来JS也需要类似Ahead-of-time-compilation(简称AOTC)这样的静态编译解决方案。
三、JS在HarmonyOS中的典型应用
HarmonyOS分布式操作系统定位为万物互联时代的操作系统,全面覆盖平板、电视、手表、手机、穿戴设备、智能汽车和智能家居等终端,在操作系统层面将这些多终端硬件融为一体,形成超级终端。如图1所示,各种生活中用到的电子设备,音响、电视、笔记本电脑、冰箱、打字机等,通过HarmonyOS分布式操作系统相互连接协同,为家庭生活提供全场景的服务体验。
图1 全场景服务体验
因为JS语言的以上优势和HarmonyOS的分布式特点,HarmonyOS选择采用JS作为其分布式应用开发的一种语言。下面让我们从开发语言的角度,看看JS在HarmonyOS分布式操作系统中的三个典型应用。
1. 在轻量化UI框架中的应用
在IoT时代,各种设备的能力差异非常大,从KB级到GB级的内存设备等,所以HarmonyOS的UI框架需要能覆盖各种终端设备。
为了实现这样的设计目标,HarmonyOS的轻量级UI框架采用如图2所示的设计,使用JS作为其应用开发的一种语言,并提供主流的类Web开发范式和数据模型(MVVM即Model-View-ViewModel),即用户通过编写JS、CSS、HTML标签和数据绑定的方式开发UI代码和业务逻辑。HarmonyOS的轻量级UI框架采用轻量级JS引擎,来运行JS框架层业务逻辑,同时把渲染框架的核心采用C++编写,搭配轻量级图形引擎,来达到内存非常轻量的设计目标。
另外,因为JS引擎可以有效适配各种内存大小的设备,同时结合覆盖多终端的JSAPI设计,于是可以实现通过一套UI代码来多端部署和分发。
图2 轻量化UI框架
2. 在超级终端中的应用
面对多样化终端硬件,HarmonyOS提出了面向万物互联时代的创新尝试——“超级终端”。超级终端通过分布式软总线技术,来连接不同设备来构成超级终端的形态。这些被连接的各种终端设备被调度了不同的分布式任务,这些任务相互协同给用户提供全场景服务的体验。
图3 多个终端形成超级“虚拟终端”
如图3所示,超级终端中的各种硬件设备通过分布式软总线技术进行高效互联和协同工作,于是可以把这些设备看成一个一个独立的状态机,他们通过交换状态和数据进行任务协同来提供服务。这样的分布式工作模式可以自然地应用到JS的异步编程能力。各个终端设备之间的状态数据交换和协同可以天然地建模为JS的异步事件模型。利用JS语言本身内置的异步事件处理能力(比如async和promise等),可以描述多状态机之间的异步事件发送和响应。同时, JS直接在语言级别支持异步事件模型,不需要引入各种巨大的异步编程库,从而极大地降低了编写JS异步逻辑代码的复杂度,并简化了超级终端应用的整体异步架构逻辑。
3. 在原子化服务中的应用
为了提供IoT时代的应用服务,HarmonyOS提出了一种轻量化应用程序——原子化服务。原子化服务具有可分可合可流转的特点,它的基本构成单元是Ability。一个原子化服务可以包含一个或多个Ability。根据是否有用户交互界面,Ability分为FA(Feature Ability)和PA(Partical Ability)两种,如下图所示:
图4 原子化服务
通过Ability,可以更好地实现应用服务的跨设备迁移和多设备协同。JS在如下几个方面为实现Ability设计目标提供了支持:
- 一个Ability对应一个任务(线程)单元,JS语言的线程模型是数据隔离的Actor模型,适合于Ability的可分可合的设计特点。Actor模型保证了JS线程之间不能直接共享对象,从而避免了使用锁等复杂同步原语,提高了任务单元的并行度和降低了应用开发复杂度。同时JS并发模型也提供transfer对象的能力,支持实现并发ability之间的高效通信。
- Ability是通过JS引擎来执行,Ability需要自由高效地跨设备迁移和分发。当一个ability从一个设备动态地迁移到另外一个设备(比如从手机迁移到电视上)时,因为JS引擎实例是单线程安全的特点,可以通过虚拟机快照之类的方式,把JS执行线程的状态快速迁移到另外一个设备上,从而提升迁移效率。
- JS的动态语言的特点有利于原子化服务升级和更新。因为语言的动态类型,分布式应用很方便解耦成不同的模块,于是可以提供高效的模块动态更新。同时因为JS支持模块的单独编译执行,所以也不需要对整个应用包进行重新编译打包,从而简化了应用的升级流程。
四、HarmonyOS对JS技术的探索
尽管JS作为万物互联时代的应用开发语言有许多的优势,但是跟静态类型编程语言(如C++和Rust)相比,还有进一步提升的空间。比如业界著名的JS引擎V8,通过引入内联缓存(Inline Caching)技术和动态编译JITC技术,极大地提升了JS的执行性能,在一些典型的benchmark的跑分,甚至和静态类型语言(比如Java)相差无几。经过深入分析,我们发现影响JS运行性能有以下三点:
- 即时编译器JITC为了生成高性能的内联缓存和优化机器码,需要在程序执行过程中先不断进行类型收集和动态优化编译,这样就必然地影响了JS代码的执行性能(特别是对于冷启动和即时响应的场景)。
- 跨语言调用(比如JS调用C++ 或者Java开发的各种第三方库)时,因为对象模型和编译器不统一的原因,JS的对象传递到C++或者java的代码中,需要进行“开箱装箱”的耗时过程,这样的频繁跨语言操作影响了程序的运行效率。
- 标准JS通过Worker来实现Actor并发编程模型,但是一个worker对应一个JS引擎实例,导致比较大的内存开销。同时,因为要初始化整个JS引擎,影响了Worker的启动性能。
针对这三个问题, HarmonyOS在应用执行运行时(方舟运行时)中对如下方向进行了技术研发:
- 通过TypeScript(一种JS的超集)提供的静态类型描述和静态类型检查来规范JS过于随意的动态写法,同时静态地(Ahead-of-time)生成内联缓存和优化机器码。这样就可以减少运行时的预热、类型收集和动态编译的开销,提升JS应用性能。
- 实现多语言运行时来支持跨语言调用和对象互操作,通过运行时沟通不同语言的对象模型,可以加速对象的跨语言访问。另外,通过统一的编译中间表示(Intermediate Representation),可以对多语言混合开发的JS应用翻译为统一的编译中间表示和进行统一的优化编译,生成高性能的机器码,进一步提升JS的跨语言调用和交互性能。
- 更轻量级的并发Actor实现。通过共享JS引擎实例的不可变数据结构,比如字节码和字符串等,可以有效降低内存开销。同时通过实现JS引擎快照(snapshot)的方式,可以有效提升Actor的启动性能。
五、未来展望
在万物互联(IoT)时代,应用的形态将发生新的变化,分布式应用和原子化服务等新形态将可能成为主流。面对差异巨大、五花八门的终端硬件,如何降低开发者开发门槛、更好地利用业界已有代码和资源、帮助开发者快速开发出面向消费者的创新全场景应用,需要编程语言和操作系统的持续不断演进,而JS开发语言将在这个过程中发挥越来越重要的作用。
HarmonyOS期待更多JS开发者走进我们、加入我们,共同迎接万物互联的新时代!