基于JS引擎的移动跨端技术

2020-11-16  本文已影响0人  Just____

背景

跨端开发逐渐成为移动互联网领域一个绕不开的话题,原生Android+IOS开发模式存在资源投入大、发布周期长、线上问题无法实时修复等诸多痛点。跨端技术的原因大致可分三大类:Hybird模式(WebView)、基于JS引擎的原生渲染模式(RN、Weex)、自实现渲染引擎(Flutter)
这里重点讨论基于JS引擎的原生渲染模式(RN、Weex)的实现方式

JS引擎(JSCore)

JS引擎的作用,简单讲就是一句话:解释执行JS脚本
JS引擎的两大代表是Google的V8(运行在Android系统和Chrome浏览器里)和apple的JSCore(运行在iOS系统和Safari浏览器里)

浏览器中的页面想要有交互效果,就需要JS脚本的配合,所以JS有一个最主要的功能就是操作DOM树,并与之交互。
JS引擎可分成三大功能模块:词法分析Lexer、语法分析Parser 、解释执行LLInt和JIT
工作流程如下:

js引擎.png
  1. 词法分析:就是把一段我们写的源代码分解成Token序列的过程,这一过程也叫分词。在JSCore,词法分析是由Lexer来完成,举例:
    比如一句赋值语句:sum = 1+1; Lexer对它的处理如下:
元素 标记类型
sum 标识符
= 赋值操作符
1 数值
+ 加法操作符
1 数值
; 语句结束
  1. 语法分析:Parser会把Lexer分析之后生成的token序列进行语法分析,并生成对应的一棵抽象语法树(AST)。之后,ByteCodeGenerator会根据AST来生成JSCore的字节码,完成整个语法解析步骤。
  2. 解释执行:词法分析和语法分析两个步骤,其实就是完成编译的过程,生成字节码。只是不同于JAVA等其他语言,JS并没有生成类似class的可执行文件,生成的字节码(ByteCode)会立刻被JSCore逐行解释和执行。
    BytecodeGenerator在生成字节码后,需要LLInt和JIT来运行字节码,这是JS引擎很核心的地方,也是各大JS引擎集中优化的地方,核心目的是提升字节码解释执行的效率

单线程

JS所有代码都在单线程中执行,不具备多线程处理任务的能力,JS的多线程异步能力依靠的是事件驱动机制,JS的事件驱动机制和Android的Handler机制很像。JS线程将耗时操作交给了外部的工作线程(WebWorker)去处理,工作线程由JS的宿主提供,它和JS线程不在一个运行环境,不共享作用域,所以工作线程也无法操作Window和Dom,工作线程处理完后会将消息推送到一个消息队列,JS线程会不停的从这个队列中获取事件去执行。

JSVirtualMachine

JSVM:一个抽象的虚拟机:包含了一整套JS的运行环境,核心两个作用:支持并发的JS调用、管理JS与native桥对象的内存
JSVM特征:单线程、有独立堆空间、与JSContext是1对多的关系、JSVM之间无法传值

JSContext

一个JSContext表示了一次JS的执行环境。我们可以通过创建一个JSContext去调用JS脚本,访问一些JS定义的值和函数,同时也提供了让JS访问Native对象,方法的接口。
JSContext特征:所有JS代码必须运行在一个JSContext环境中、所有的读取操作其实都是与一个JSValue类型的globalObject在做交互

JSValue

JSValue实例是一个指向JS值的引用指针。我们可以使用JSValue类,在JAVA和JS的基础数据类型之间相互转换。同时我们也可以使用这个类,去创建包装了Native自定义类的JS对象,或者是那些由Native方法或者Block提供实现JS方法的JS对象。

JSExport

实现JSExport协议可以开放JAVA类和它们的实例方法,类方法,以及属性给JS调用

RN与Weex对比之 - 启动流程

RN与Weex对比之 - 渲染原理

RN与Weex对比之 - 通信机制

参考文章:https://www.jianshu.com/p/3181e9cc99d7

上一篇下一篇

猜你喜欢

热点阅读