Lynx 3.9:Autolink、更贴近 Web 的 CSS、ReactLynx Portal
← 所有文章Lynx 3.9 已经正式发布!
这个版本围绕三条主线展开:用 Autolink 让原生能力可以被打包成库、被安装和复用,用更贴近 Web 的 CSS 能力减少迁移和 AI 生成代码中的常见误用,并让 ReactLynx 在 Portal、渲染与构建表现上继续前进。此外,3.9 也带来了元件、Lynx API 与性能的一组小而实用的更新。下面我们一起来看看 Lynx 3.9 带来了哪些新变化。
Autolink
在 3.9 之前,想用上一个原生能力,得先进原生工程:在 Gradle 和 Podfile 里各加一次依赖,再到 Android 和 iOS 的初始化代码里把元件、原生模块和 Service 分别注册一遍。Lynx 3.9 把这些收敛成一个可以发布、可以安装的单位:一个 Lynx 原生库就是一个 npm 包,用包根目录的 lynx.lib.json 声明原生入口,由 Autolink 在构建期发现并接进宿主应用。
使用库
接入 Autolink 只需要做一次:Android 在 settings.gradle 和 app 的 build.gradle 里各启用一个 Gradle 插件,iOS 安装 cocoapods-lynx-library 并在 Podfile 里调用 use_lynx_library!。之后安装库:
Android 重新 sync、iOS 重新执行 pod install,这个库提供的元件、原生模块和 Service 就会在 LynxEnv 初始化时注册好。
开发库
要把一段原生能力做成库发出去,用 create-lynx-library 生成骨架:
生成的包里带上了 lynx.lib.json:这份清单声明该库的原生入口在哪里,Autolink 正是靠扫描它来发现已安装的库。类型声明、JavaScript facade、原生源码目录和 example 应用也一并生成好。codegen、原生标记的写法和发布流程,见 Autolink 指南。
更贴近 Web 的 CSS
Lynx 3.9 的 CSS 更新重点不是增加属性数量,而是继续贴近 Web 社区已经熟悉的写法:从 Web 迁移过来的样式更容易得到一致结果,AI 生成 Lynx 代码时也更少把 Web 常见写法误用成不可运行的 Lynx 样式。这个版本补上了 !important、flex 简写解析等兼容性能力,也继续推进 Grid、Sticky 和 Motion Path。
!important 优先级支持
在 engineVersion 3.9 或更高版本下,可以在 CSS 值后追加 !important,提升该声明在层叠规则中的优先级。例如下面这段样式中,<view className="foo" /> 的 color 会被应用为 red 而不是 blue:
flex 简写解析
flex 简写会被展开为 flex-grow、flex-shrink 和 flex-basis 的组合。3.9 起,省略的 flex-basis 会按 0% 解析,而不是此前的 0。
虽然 0 是 CSS 规范中的默认值,但浏览器在解析 flex 简写时普遍使用 0%。这个调整可以让 Lynx 的布局结果更接近 Web。具体差异可以参考 Flex basis 0 vs 0%。
Grid、Sticky 与 Motion Path
Lynx 3.9 还补齐了以下 CSS 能力:
- 新增
grid-row和grid-column简写,可通过它们设置grid-*-start和grid-*-end的值。例如grid-row: 1 / span 2等价于grid-row-start: 1; grid-row-end: span 2。 - 支持与 Web 一致的标准
position: sticky行为。 - HarmonyOS 端补齐了更多 Motion Path 能力,包括
offset-path、offset-distance和offset-rotate。
ReactLynx
ReactLynx 带来了 createPortal 与 Snapshot 层级和数量优化,并在构建侧新增了双线程 Minimizer。
Portal
在 React 中,Portal 用于把一段组件树渲染到元件树上的另一个容器里,同时让它仍然留在 React 树中——浮层、弹窗这类需要脱离当前布局层级的 UI 通常都靠它。自 @lynx-js/react 0.121.0 起,ReactLynx 通过 createPortal 提供 Portal。
与 React DOM 中的 Portal 接受一个 DOM 节点作为容器不同,在 ReactLynx 中我们使用一个节点引用(NodesRef)作为 Portal 容器:在承载元件上挂一个 ref 拿到它的 NodesRef,再作为 createPortal 的第二个参数传入。获取节点引用的更多方式见直接操作节点。
Portal 只改变元件在页面上的物理位置。除此之外,渲染进 Portal 的 JSX 表现得就像渲染它的那个组件的子节点:父树提供的 React Context 依然能拿到,状态更新也和普通组件一致。有三点需要注意的地方与 Web 不同:
- 事件冒泡遵循 Preact 的行为。 ReactLynx 的
createPortal沿用 Preact 的实现,而 Preact 中事件不会穿过 Portal 组件向上冒泡,因此事件沿页面实际的元件结构冒泡,而不是 React 树。 - Portal 子树不参与首帧直出(IFR),只在后台线程渲染。
- 不支持跨页面或跨原生容器挂载。 这类场景请改用 lynx-ui 的
Overlay组件,或直接使用<overlay>这个 XElement。
Snapshot 层级和数量优化
ReactLynx 在编译期会把 JSX 中的静态元件结构提取成 Snapshot,运行时只更新其中的动态部分。(Snapshot 我们会在后续博客中详细介绍。)
@lynx-js/react 0.120.0 中我们扩展了 Preact 的 diff 算法,让子节点可以直接声明自己属于父节点的哪个槽位。编译产物因此可以去掉原先必需的中间节点,元件树更浅、Snapshot 更少,渲染时要做的工作也更少。该优化默认启用,业务代码无需修改。
双线程 Minimizer
构建侧新增了双线程 Minimizer 机制,用于对主线程和后台线程产物进行更细粒度的压缩与裁剪。开发者可以通过 optimizeBundleSize 快速启用默认优化,也可以分别配置 Minify.mainThreadOptions 和 Minify.backgroundOptions。
其他更新
元件能力
<frame> 新增 enable-multi-async-thread,可控制嵌入式 Lynx 页面是否使用多个异步线程。它也新增了 preset-height 和 preset-width,用于在内容初始化前指定尺寸;同时新增 bindloadmetrics 事件,方便宿主或业务侧跟踪 frame 的加载与性能指标。
Lynx API
Lynx API,requestResourcePrefetch 新增 config 参数,支持 awaitComplete 和 awaitTimeout。如果你希望 prefetch 完全结束后再触发 callback,现在可以直接通过配置表达。
性能表现
HarmonyOS 端默认启用新版原生图片链路,将图片加载、解码缓存及动图帧调度下沉至图片节点,减少逐帧计算与刷新开销。在我们内部的图片动画基准测试中,总耗时(TotalTime)和 CPU 耗时(CPUTime)均降低约 10%。
升级指南
参照官网接入 Lynx 到现有应用,更新 Lynx 依赖版本,即可完成 Lynx 3.9 版本升级。
Lynx 3.9 包含部分破坏性变更,升级前请结合你的目标平台、engineVersion、页面开关和宿主集成方式进行验证。感谢每一位持续试用新版本、反馈问题并推动 Lynx 生态发展的开发者,我们会继续保持更小、更聚焦的月度发布节奏。
