Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

跨端方案 #58

Open
ChelesteWang opened this issue Apr 23, 2022 · 0 comments
Open

跨端方案 #58

ChelesteWang opened this issue Apr 23, 2022 · 0 comments

Comments

@ChelesteWang
Copy link
Owner

多端融合的意义
发挥各自的技术优势,实现性能及体验上的突破
比如性能优化,单纯的 web 能做的就那些事情,非常依赖浏览器本身的性能,但是结合原生,就可以从并行、预加载、缓存三个方面做更极致的优化

Flutter

cross platform first 框架
Flutter架构最核心的便是 Framework(框架)和 Engine(引擎)

渲染原理

开发者通过 widget 写 ui,dart framework 通过比对 widget 更新 element,最后调度 RenderObject Tree完成布局排列和绘制

  • ui 线程负责 widget tree、element tree、renderObject tree 的构建、布局,并生成 layer tree(保存绘制指令)
  • gpu 线程执行 skia 代码,负责将 layer tree 进行删格化和图层合成并渲染到屏幕上

skia

  • 调用平台底层图形引擎接口进行渲染,如 OpenGL、vulkan、metal
  • gpu 线程通过 skia 向 gpu 硬件绘制一帧的数据,gpu 将帧信息保存到 framebuffer 里面
  • 然后视频控制器会根据 vsync 信号从 framebuffer 取帧数据传递给显示器,从而显示出最终的画面

Platform Channels

提供让 dart 可以调用 native 功能的能力

跨平台原理

  • android 将引擎 C++ 代码使用 NDK 编译生成 flutter.jar, dart 代码编译成本地 ARM 库。最终编译产物会包含在 apk 包中
  • ios 将引擎的 C++ 代码使用 LLVM 编译生成 flutter.framework,dart 代码编译成本地 ARM 库。最终编译产物包含在 ipa 包中
  • 调试模式时则使用虚拟机 (VM) 来运行 Dart 代码,这样便可以启用有状态热重载 (Stateful Hot Reload)

NDK

提供了一系列的工具,帮助开发者快速开发 C(或C++)的动态库,并能自动将 so 和 java 应用一起打包成apk

Kotlin

基于 Kotlin Multiplatform 提供跨平台能力

  • 不需要桥接和重写渲染层,直接将代码编译为与目标平台完全相同的格式
  • 问题是 kotlin 只写业务逻辑,ui 需要使用特定平台的 ui 语言
  • Jetpack Compose 进一步提供了 ui 组合能力

优势


跨终端架构

四种模式:webapp、hybrid(ionic)、调用原生(rn、weex)、完全接管(flutter)

  • webapp 是最简单直接的方式,未来要看 pwa 的推进
  • hybrid 采用 webview + native api 通信的方式,代表框架有 IONIC、DCloud
  • 调用原生通过 js引擎 - bridge - native 可以提供比 h5 更好的性能,通常还需要一个布局引擎 yoga
  • 完全接管即框架自己实现 dsl、控制层、渲染层等,性能上限最好

js-bridge

给 h5 提供调用原生的能力,有 schema 和注入两种实现方式,现在一般都使用注入的方式
技术点有数据的序列化与反序列化、回调函数全局挂载

  • android 比较简单,通过 addJavascriptInterface 放即可
  • uiWebview 可以直接向 jsCore 的 jsContext 上添加成员
  • wkWebview 使用 addScriptMessageHandler
  • js 框架来抹平接口、参数、callback 以及序列化方面的差异

方案一

  • 选取一个开源 dsl 框架,编译成小程序的代码,各端分别有一个运行时框架或兼容组件库保证代码正确运行
  • runtime 处理生命周期关联,事件代理,data change,以及 render 重写

方案二

提供全新的 dsl 框架,编译成小程序的 dsl,针对不同端提供不同的运行时组件,完全适配

mpvue

主要的技术点:wxml 模板生成、生命周期同步、事件代理、setData 性能

  • 通过 vue-template-compiler 将模板编译成 wxml、css 和 json,而 vue 的 js 部分与 小程序的 js 代码都放在 wxss 逻辑层运行
  • 同时持有 vue 对象和小程序 page 对象,打通两者的生命周期、事件、以及 setData
  • 逻辑部分通过 vue 处理,界面更新以及事件交互通过小程序处理
- 屏蔽 vue  dom 的处理,数据变化时通过 update 生命周期执行小程序的 setData
- vue 组件和小程序组件之间通过 id 建立关联(小程序元素和 vnode 保存相同的 id)
- 事件触发时通过 id 找到 vdom,然后拿到 event handler 执行

taro

  • 旧版是重编译时,把 react 语法完全转化成小程序语法,产物就是 wxml、wxss、json、js
  • 编译 jsx 会有很多问题,一个是语法适配,另外还要跟进 react 的新特性
  • 新版是重运行时,跟 remax 实现原理一致
  • 小程序事件全部通过代理找到 dom 元素使用 dispatch 触发原生事件,最终转化为 taroEvent 由 taro 的事件机制处理
// render 编成 wxml,剩下的作为 js 重新定义
组件都继承 BaseComponent 适配 react 的生命周期
createComponent 与小程序打通

remax

  • 复用 react-core 和 react-reconciler,自己实现 renderer 通过 hostConfig 与 reconciler 建立连接
  • 小程序组件封装成 template,递归 dom 树进行模板嵌套
  • setData 通知渲染进程后,通过 wxs 动态构建渲染模板

chameleon

多态协议框架,可以将框架 dsl 编成各端的 dsl,每个端都有一个运行时提供通用方法和组件

小程序性能

建议按照 wx 官方标准 [性能 | 微信开放文档](https://developers.weixin.qq.com/miniprogram/dev/framework/audits/performance.html)

自定义标准

  • 首屏时间不超过 2.5 秒
  • setData 的数据量不超过 100kb
  • 所有网络请求都在 1 秒内返回结果
  • 组件滑动、长列表滚动无卡顿感

优化方式

思路就是小程序文档 + web 优化方法论结合

  • 资源压缩、分包、分包预加载、数据预取、接口本地缓存、页面 h5 化、内存占用、setData 调用频率、数据合并

react native 新架构

  • 通过 jni 使 js 可以持有 c++ 对象,将异步的 birdge 通信变为同步调用
  • 简化渲染时复杂的跨线程交互,将 react - bridge - shadow tree - native ui 转化为 js - fabric
  • 转为 rn 优化的 hermes 引擎,主要有两个改进:预先编译字节码、放弃 jit 减少引擎大小已经一些热点优化的性能消耗

flutter 跨终端生态

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant