-
Notifications
You must be signed in to change notification settings - Fork 365
在小程序中使用 React with Hooks #1
Comments
在小程序内运行react的思路还是让人为之一振的,赞一个~ |
为 LZ 的 idea 点赞👍 !不过这样实现不会产生性能问题么?vdom tree 往往是一个比较大的json,而微信小程序的 setData 涉及到跨进程通信,对于 传递大 json 的行为则可能会导致很明显的卡顿。而小程序底层是模版,想只传递 diff 之后的结果也不是很方便,或者是用的 wxs 处理? |
@guoyang007 可以扫一下上面的小程序 DEMO 体验一下,体验仍然和小程序是一致的。 确实如你所说,目前小程序的多页其实就是多个 webview,体验也比较好。 所以我们就直接用小程序的 router(即写多个 Page)就好,每个 Webview 跑的是一个独立页面而不是 SPA,不强求一定要用类似 react-router 的方式在 JS 层面再实现一遍多页。 |
@zaaack 目前是靠传递整个 vdom 树实现的,只传递 diff 结果估计难以实现(因为 View 层的逻辑太弱了)。 不过可以考虑分片的更新 data(因为小程序的 setData 是 update 而非 rewrite)来提高性能,当然这是个很浅的思路,还没有想得非常的清楚。 其实这里有另外一个问题更让我头疼: |
@zaaack 稍微思考了一下,把整个 tree 分成多块,然后更新时只 set 改变的块的 tree,应该能实现(虽然不能精细到完全只传递 diff 部分) 不过在这之前仍然要解决量化小程序性能的问题,现在只能靠微信提供的调试工具中的 |
setData 不会做自动 merge,而且大数组之类的感觉还是不好处理。。微信小程序模版里支持 wxs 可能可以对 json 做一些操作,不过这样对于其他小程序就支持不太好了。。 小程序的 benchmark 我觉得还好吧,和 App 一样直接上真机,然后运行时查询通过 setData 的 callback 计算渲染时间 log 到 vconsole 上, 感觉应该没问题。。 |
分片@zaaack 不是指 Object 自动 merge,而是数据 key 本身就不同的时候是可以单独 set 的,我们可以据此把单个 VDOM 分割成 {
splitCount: 2,
VDOM_SPLIT_1: {},
VDOM_SPLIT_2: {},
} 然后在第二块改变时只 setData({
VDOM_SPLIT_2: ...
}); 不过这个思路仍然很粗,不能很精细的解决这个问题。 benchmarkbenchmark 你的思路确实可行,之前一直在想电脑上怎么跑,确实还是真机跑才有意义,可以先把这些性能相关的信息都通过 vconsole 打出来让开发者有个感知。 wxs感觉 WXS 确实是这个问题的最靠谱的解法,关于兼容性的问题一方面我相信其他家的小程序会跟进的;另外一方面其实这一层的实现对上层是没有影响的,加上小程序目前最大的 target 仍然是微信小程序,我觉得在不支持的场景降级是可以接受的。 感谢你的思路,非常棒 👍 |
我了解过 跑了下demo,然后看了下demo/dist目录中的生成文件,里面有一个很大的 作者这样的实现方式貌似是给小程序的 |
自从看了Taro感觉还是鸡肋,一直在等一个能够真正兼容React的出来。�楼主的这个idea给10086个👍。 |
@joe-sky 你理解的没错,我们需要 wxml 枚举把 vdom 显示成界面。据我所知 mpvue 仍然是采用的静态编译方案,应该没有采取这种方案。至于其对运行时性能的影响就取决于微信的实现了,目前从 demo 看没有什么问题,不过更复杂的场景确实需要验证。 目前也在思考有没有更优雅的方案,但小程序似乎没有给我们开什么其他口子 |
@HuiguangChu 理论上 redux(准确说是 react-redux)只和 react 相关而无关 react-dom。应该是可以直接支持的。有空我写个 demo 跑跑看有什么问题。 |
@codefalling, 原理上好像是这样的。又仔细看了一下代码以及整个项目结构。如果我理解正确的话remax 就是重写了react 的render ?还有就是把微信小程序对应的tag 通过特定的react component来展现? 用户可定义自己的component 么? 问的问题比较多,望海函,用react 有年头了,就是现在的各种小程序太多了,国外根本无此项目资源,脱节了都。。。。 |
@HuiguangChu @remax/core 主要是重写 react 的 render,@remax/components 是提供一些 react 组件可以渲染成小程序基础组件,@remax/cli 是相关的构建(生成小程序对应的文件结构之类的) 在这种结构下,用户的组件机制完全在 js 里(由 react 接管),不需要真的在小程序的 wxml 中真的体现成 custom tag。 |
@codefalling 或许可以考虑一下怎么把现有的第三方小程序组件接入进来,提供包组件的方法之类的? |
@ahonn 可以,就具体的 feature request 我们可以单开 issue 讨论 |
那如果要支持其他平台的小程序,Components 有一些是不是要重写?webpack 配置那块是不是可以通过CLI不同命令来配置不同的template? |
@HuiguangChu 是的 CLI 肯定是根据平台来生成不同的东西,不仅仅是 template,也包括 WXSS => ACSS 等。@remax/components 就是为了这一点预留的抽象层。 |
个人觉得没必要支持其他小程序平台,微信小程序和H5才是王道,专注才能做好。 |
@dangxuandev 加油,急迫等待在生产环境使用。 |
这里又跑了 react runtime 么,那性能数据呢,逻辑层运行时复杂度? |
群二维码已过期 |
1 similar comment
群二维码已过期 |
介绍一下 Remax
Remax 是一个跨多端小程序 React 开发方案,之所以称其为“方案”而非框架是因为这并非一个新的框架,其主要能力就是让 React 能够直接运行在 微信小程序/支付宝小程序/字节跳动小程序/H5(当然这个本来就支持) 等环境。
可能会有人要会问 “React 不是早就可以运行在小程序中了么“?本文会介绍一下现如今的一些小程序框架的解决方案,以及为什么我们认为把 React 直接搬进小程序是个更为合理的方案。
静态编译类框架
由于大多开发者都更熟悉 React 和 Vue 的 API 和语法,加上小程序本身的开发方式确实让人痛苦,于是便有了一些框架来将这些熟悉的语法编译到小程序的 WXML/WXSS/JS 上,其中比较具有代表性的例如 taro,其目标就是让开发者能够用 React 的开发方式编写小程序。
而这类框架的实现原理其实并非真的是一个 React 或者类 React 框架,而是把看起来像是 JSX 的模板通过静态编译的方式翻译成小程序自身的模板。
这样做的限制非常明显,那就是 JSX 是 JavaScript 的拓展语言(React Blog 写的是
is a syntax extension to JavaScript
),而小程序所采用的 WXML 却是一个表达能力非常受限的模板语言,我们不可能完成从一个通用编程语言到模板语言的编译。而静态编译类框架为了做到这一点,采取的方式就是限制开发者的写法,这也是为什么上面称之为看起来像是 JSX 的模板,这也是为什么 taro 对 JSX 的写法做出了诸多限制。
这种方案大多声称这些限制并没有限制生产力,或者符合最佳实践等等。然而我们其实都知道这是由于小程序本身的坑造成的,静态编译方案编译的永远都只会是模板语言,而不是 JSX。
React Hooks
之所以我说这些限制并非基于最佳实践,是因为 React 本身对于 JSX 的定位就 并非模板。
在最近 React 团队已经向我们介绍了 Hooks,期望可以 functional component 不仅仅可以是无状态组件,也可以是
useState
的。React 官方博客提到
Classes confuse both people and machines
,我们也明显可以看到基于 function 的组件明显更为简洁,噪声更小,未来 React 社区的方向更是会逐渐从 class component 过渡到 functional component。在这种趋势下,把 JSX 当做模板写,且未来永远也不可能支持 functional component 的方案绝非真的基于最佳实践的选择。
在 Remax 中,我们完全可以使用全新的 Hooks API 来开发组件
因为 Remax 中的 React 就是 React.js,而 JSX 就是 JavaScript 的超集。
上图中使用小程序的原生语法,classname 和 inline style 就只能写成
而使用 remax 后就可以写成正常的 react:
实现原理
核心部分
Remax 的实现原理和基于静态编译的方案有所不同,其核心其实是重新实现了 ReactDOM 的部分。
众所周知,React 本身的设计就是支持跨端渲染的,render 部分和 React 的核心逻辑是解耦的(甚至不在一个 npm 包里)。主要的 render 有 ReactDOM(浏览器),ReactDOMServer(服务器端)和 ReactNative。
Remax 要做的事情和 ReactNative 要做的事情非常类似,我们重新接管了 ReactDOM 的 render。
在原有的 React 页面中,React 在完成 Diff 发现需要修改界面时,又 ReactDOM 把改变 Patch 到页面上。
而在小程序中由于我们不能直接修改页面,则由 React 完成 DIFF 后由 Remax 把修改 Patch 到内存中的虚拟 DOM 上,然后再通过小程序自己的虚拟 DOM 最后把改变同步到页面上。
在这里我把这个过程说得非常简单,但实际上是有些坑要填的,主要也都是来自于小程序的限制,后续会有新的文章展开来讲。但是这种实现方式使得我们完全可以把 React 的代码放在小程序的环境中运行。
工程化
工程化很理所当然的用 Webpack 来实现, 除了我们常用的打包等功能外,Webpack 插件也使我们很容易构建一些我们需要的东西出来,例如我们需要在每个 js 入口除了放一个 js 外还需要添加一个
wxml
文件,就可以通过一个很简单的 Webpack 插件来实现。跨端
这种方案想实现同一套代码跨到 H5 端显然没有什么问题,至于支付宝小程序目前验证了一下可行性也是可行的。
项目结构
这个项目主要由几块组成
核心部分,负责 React 组件的 render
顾名思义,CLI 工具,用于构建生成相应的小程序项目等工作
底层 Component,包括诸如 View 等一些基础组件,用于抹平不同环境的差异
自带的基础组件库,这部分还待开发,目前只有一两个示例组件
由于目前整个项目才刚刚起步,暂时还不能用于生产环境,目前的几个主要开发者(和打算参与的)有 @codefalling @bramblex @ahonn @SimplyY
目前的 DEMO 可以扫码体验:
或者在可以按照 https://github.com/CodeFalling/remax#%E5%BF%AB%E9%80%9F%E5%BC%80%E5%A7%8B 体验本地 DEMO。
如果有人想要参与进来一起开发可以联系我,开发相关的细节文档会陆续更新在 https://github.com/CodeFalling/remax/wiki/%E5%85%A5%E9%97%A8 。
推荐阅读
The text was updated successfully, but these errors were encountered: