什么是跨终端(跨尺度)

来源:互联网 知识问答 2026-10-12 01:27:01 18

链接:https://juejin.cn/post/6944289729990885389

鉴于很多人对跨端技术感觉很神秘,虽然我实际上还没有写过一个从0到1的跨端框架,但是我曾经用Yoga(布局引擎Yoga(React-Native)做过一些简单的跨端的事情,后来用了Weex。研究跨端有一段时间了,想科普一下。

科普之前,首先你要知道,为什么需要跨端技术?我们通常会把Weex和React-Native(本文统称为RN)说成是跨端技术吗(Flutter没有单独提到)?

其实不是,好像Android/iOS本来是两个人的,但最终变成了一个人。我的人力减少了一半!

但前提是这个人力需要懂Android,iOS,JavaScript,更懂,不然出了问题,怎么修?

所以在中国的互联网环境下,很难招到这样的人。大家都在研究PPT架构技术,职场生存理论,30岁如何解脱财富。我们如何有时间扩展我们的技术堆栈?

端上开发很惨,总有崩溃(应用崩溃,闪退)而且没有办法远程修复。只能等下一个版本给应用市场推一个修复bug的新版本。

但如果推送新版本,用户可能不会升级。因此,许多公司研究了各种热修复框架,尤其是在Android平台上。有很多热修复框架,主要是由DexClassLoader来完成。

但是,最早的时候,WebView有一个很大的问题,尤其是Android。而且加载网页肯定要花时间,过程中屏幕会一片空白等等。所以很多人围绕这些做了很多优化。我个人觉得最有用的其实是线下套餐。同时,每一代WebView也在更新升级。然后一些有实力的公司开发了自己的所谓浏览器内核,各种黑科技,如何提速,支持各种特性等等。但是好像没有开源:dog:

不算。这只是跨安卓和iOS,不把我的PC当目的?

其实浏览器是跨端的,每个平台都可以用Chrome(其他浏览器主要是想做不做)!但是它也有自己的问题,因为各家都有自己的浏览器,内核不同,划分越来越大。chrome(Blink)/Safari(WebKit)/Firefox(Gecko?)等等,尤其是对css的支持。

Developer.mozilla.org/zh-CN/docs/.这个网站可以检查一些浏览器的兼容性。例如,边框宽度的兼容性如下:

其实也不是不可以,但是这样做相当于直接为OpenGL或者其他图形引擎编程,而且要自下而上的搭建一套渲染机制,打包各种基础UI组件给开发者使用,或者留下很多漏洞让开发者自定义自己的UI,非常复杂。但其实Flutter就是这么做的,所以Flutter2.0又开始向桌面端发展了,而且不局限于Android/iOS,但不知道能走多远。还有的是搞React-Native-Skia的,所以用js代码直接调Skia(2D图形渲染引擎)?(具体没看过)

你写的JavaScript代码为什么能运行?这取决于JavaScript引擎。

扔给它一段js代码(实际上是一个文本字符串),它就能帮你计算结果,处理逻辑。

常见的Weex、RN、Hippy也依赖于此(MLN使用Lua)进行逻辑处理。

这个时候会有很多概念。

有些人喜欢把JavaScript引擎称为JavaScriptCore(不知道为什么,可能是因为iOS开发者才是研究这些比较深入的人,因为苹果的JavaScript引擎叫JavaScriptCore。苹果的这个JavaScriptCore呢?很多人喜欢称之为JSCore或者JSC)。所以,后来看到这些名词,我总是把它们带入语境中去感受他想说的是JavaScript引擎还是苹果的JavaScript引擎3354 JavaScript Core (JSCore/JSC)。

先说JavaScript引擎。

是的,有这么多!当然还有JavaScriptCore(不在图中)。

最后一行是跑分,越多越好。有JIT的V8在3w挂所有东西。其中QuikJS极小,得分很高。估计很多人会用QuikJS做跨端JavaScript引擎吧?赫尔墨斯是由脸书创造的。看来Android目前在RN中使用的JavaScript引擎已经取代了之前使用的JavaScriptCore。RN为什么一直不用V8?这个我也不知道.

但是很多人都在搞Android的V8项目,Github上也有一些开源项目。其次,iOS不支持JIT,有自己的JavaScriptCore,没有JIT改V8似乎意义不大。

一个正常的跨端框架最简单的情况如下(后面会讨论问题,逐步丰富):

用一个

简单的例子看

假设我的 js 文件中就是要 展示一个红色的 p 方块 。那么首先,端会把这个文本传给 JavaScript Runtime,它解析完后形成一个约定的格式,比如如下的 JSON 格式(里面的值用来描述是一个100*100红色方块,我随便定义的)

{ "name":"p", "width":"100", "height":"100", "background":"red"}

通过 JavaScript Runtime 和 端(Android/iOS) 通信,把这个消息传回去。

端拿到了消息,发现要创建一个 100*100 的叫做 p 的东西,没有 p 啊!这就需要端上提前埋好代码,比如 Android 里有 FrameLayout,那么就有类似的注册代码

// 伪代码register("p", FrameLayout.class);

然后端就知道了,oh!我需要创建一个长100宽100的正方形。

首先,这是框架设计提前思考好的,究竟要支持哪些基础组件,比如 image 、text 等等。而且一般这里都会开个口子,让开发者可以自己扩展组件,比如你需要一个横滑列表,没提供怎么办?看看 p 怎么注册的,按照它的过程注册一个列表就好了。这也可以 PPT 吹成: 扩展跨端框架 ,其实 门槛比自定义 View 还要低 。

前面说了 JavaScript Engine,这里咋又来了个 Runtime?

JavaScript Engine 能做什么?

什么都做不了,只能解析执行 js 代码

那么问题来了,我怎么去 描述 我写的 js 代码代表的 视图 呢?其实不用描述,js 代码只要在 内存中 维护好一个树形结构就好了,就是一个 Object,因为实体在具体的端上,怎么理解呢?

左边只要在内存中维护好这样一个树形结构就好了,传递给客户端时,转为

{ "name":"p", "children":[ { "name":"image" }, { "name":"p", "children":[] } // 等等 ]}

端上拿到消息,创建视图为右图中的结构即可。

如何维护好这个模型呢?调用什么 js 的方法发送消息呢?怎么给这些个 p 加上 css 来描述它的大小形状呢?等等更复杂的一系列的前端问题,都需要 写代码 来实现。

所以一般都会有个 core.js 或者 framework.js 类似的一堆 js 代码,就是用来处理这些事情,而这些代码同样依靠 JavaScript Engine 来执行。

从而所谓的 JavaScript Runtime ,我觉得可以单纯的理解为 JavaScript Engine 自身的代码跑起来后的环境,也可以理解为 core.js 等被跨端框架所需要的、包含了各种逻辑的前端代码被加载运行后的环境。

当你用这些跨端框架的时候,你会发现他们只支持 css 子集 ,而且布局方式基本都是 flexbox(一种布局模型) 。

那么比如你写了一个横着容纳了三个小方块的大方块,你的前端 css 代码肯定要写成, flex-diretion:row ,那么抛给端上的消息可能如下:

{ "name":"p", "attribute":{ // 使用布局 "flex-diretion":"row" }, "children":[ { "name":"p" }, { "name":"p" }, { "name":"p" } ]}

端上拿到这个消息,都不知道 flex-direction 是什么。当然,你可以自己写一个解析库来解,但是 Yoga 帮你做了这件事!

所以 RN 使用的是 Yoga 布局引擎(支持 flexbox,也是 Facebook 搞的)。

Weex 似乎一开始是用的 Yoga,后来自己写了一套?

这个地方就出现了一个名词 Layout Engine ,它就是帮我们处理各种布局参数的,然后帮我们算好每个视图的坐标,然后端上拿到坐标后设置对应的视图的坐标,一个井井有条的视图便展示了出来。如果你觉得你写的布局解析算法超越了 Yoga 等等,那么你完全可以自己写一套。

比如从 JavaScript Runtime 处理完各种属性了,要渲染视图了!传了一段 JSON 给端。

端上手指点了一下这个视图,那也要封装成一个消息传递给 JavaScript Runtime,然后触发你之前写的 js 的**代码,比如点击后弹一个弹窗,那就又要封装一个调用弹窗方法的消息给端。

就是这样来来***。

所以两边都有自己的消息队列。

而且当你做动画还想**动画过程的时候,肯定在短时间内发送了大量消息,这些过程肯定是 需要优化 的。

并且!据我个人用 Weex 的经验,有的 flexbox 属性两端都不统一(可能是 Weex 的 Bug,毕竟 KPI 项目,都不维护了)

我记得当时还开玩笑说,用了 Weex 终于领悟了跨端的真谛:

if(platform === 'Andoird') { // 差异化逻辑} else if(platform === 'iOS') { // 差异化逻辑}

跨端的代价就是,你 本以为 真的可以一套代码两端跑,后来发现真的有点做梦了(连 H5 有时候 Andoird/iOS 都不一致,因为用的内核都不是一个),代码里有不少的 if-else。

所以经过上面的一系列科普,一个跨端框架成了这样:

这其中一般是需要一个客户端、一个前端、一个懂 JavaScript Engine 会 C/C 的来分别开发。

我虽然没开发过,但是感觉会有很多问题。

比如 JavaScript Runtime 在另一个进程的话,跨进程通信?

比如消息通信过于频繁是不是就会有各种连锁反应,掉帧啊、事件响应不及时、动画不流畅啊,怎么优化?

其实我本身一直自诩喜欢研究原理,但是直至今日我也没真的一行行看过跨端框架的源码,我知道的这些也未必是对的,只是之前做过 Weex 的一些工作稍微研究了一下,还是挺惭愧的。

既然你自称喜欢研究原理,为什么不看呢?

链接:https://juejin.cn/post/6944289729990885389

相关问答:

相关问答:手机端和电脑端各是什么?

电脑端和手机端,实际上说的就是平台问题。

当我们使用电脑的时候,电脑基本使用的操作平台是windows,或者苹果等常用操作系统。

而手机上用的平台,如安卓,苹果的IOS,当年诺基亚的塞班,黑莓的系统,都叫做手机端。

那么怎么定义手机端和电脑端呢,我们可以这么理解,如果用电脑操作系统的设备,即便是平板电脑,你也可以理解成是电脑端。

如微软平板电脑surface,他的定位是平板也是电脑,

我们很多的平板,多数使用的是安卓系统,苹果的当然就是IOS,但是平板使用基本使用的移动平台,也就可以看成是手机端。

但是,如果这个移动设备的平台使用的是电脑的操作系统的时候,他所使用的平台,也就成了电脑端。

上一篇:花呗自动还款怎么设置银行卡

下一篇:中国人寿学平险都保什么?

需要摆账亮资?咨询在线客服,3分钟快速回复!