去年笔者写了一篇「全网首发」Flutter element embedding 初探(面向 Web 未来),后面忙各种杂七杂八,没有持续投入在 Flutter 上。
兜兜转转一年过去了,越发觉得这能力真的很重要,不亚于 Flutteradd to app在 App 上混合开发的价值。
element embedding 简介
Flutter 的 element embedding
简而言之,就是把 Flutter 塞到 HTML 的<div>
标签中,并且可以使用 CSS 控制样式变化,也可以通过 JS 进行数据交互。
去年还是实验性功能,现在看element embedding
已经转正了,且在 samples 传送门 跟 web 的 Demo 并列:
之前是在expermental中:
除了之前的基础 Demo 外,还提供了 Angular 框架的 Demo:
并且还有2个社区贡献 Demo,React 和 RN(但没有 Vue【手动狗头】):
看了下他们的源码,RN 确实符合我对这能力的理解,开发一个 FlutterView 可以运行在任意端上,但 Demo 的通信没有去抹平,那对开发来说还是很复杂的。
这几个 Demo 运行起来都一样,虽然效果蛮惊艳的,但并没有体现出我为什么要用,用它的价值在哪里?
优势分析
更好的用户体验
网速越来越快,流量越来越不值钱,wasm 大势所趋。
去年笔者只是觉得它可能是未来,但也没有想出除了一次开发,多端可用外,那它对于前端的好处在哪里呢?
最近,笔者颠沛流离的去写前端代码,任务也都是各种性能优化、卡顿优化,比如 使用「vue-virtual-scroller」实现在 App 横向滚动分页效果。
但这些方案都治标不治本,就拿虚拟列表来说,是去实现长列表是必要的技术。但市面上有完美的前端虚拟列表吗?并没有,且从根源上解释就没法有。
笔者公司也是,无论 PC 端还是移动端,各种长列表相关的优化一直没停过。
归根结底,因为前端是 dom 布局,一旦 dom 元素渲染过多,性能、内存都是扛不住的,只能通过各种复用来减缓。
那有什么治本的办法?是有的,抛弃 dom 布局渲染,用<canvas>
绘制复杂页面/功能。
业界上抛弃 dom 渲染布局的厂商也很多,比如 adobe 的Lightroom,整个编辑画布就是用<canvas>
渲染的:
分析它的源文件,盲猜应该是 lua 脚本开发的:
这种架构在市面上确实小众。
更常见的是用three.js
等基于WebGL
的动画绘制。
说明在复杂的应用场景下,未来趋势大概率会慢慢减少 dom 布局,转向<canvas>
绘制,来终结 dom 渲染的瓶颈问题。
更好的开发体验
应该说还没有任何一款框架能像 Flutter 一样在 Web 上使用<canvas>
绘制,且提供了完整的 UI 开发库,这对我们开发来说,意味着门槛低,开发简单。
甚至可以直接复用 App 的现有代码:Flutter Web – 优雅的兼容 Flutter App 代码
但它的缺陷也很明显:不支持 SEO(搜索引擎优化),也没有 SSR(服务端渲染),这点在浏览器上是致命的,也是各大中厂不采用该方案的主要原因。
当然也是用的人少,不成熟的地方就比较多 …
Flutter element embedding 提供关键连接
大伙看到这,应该就能隐约体会到element embedding的真正价值。
划重点:我们还是可以用 Vue、React 等主流框架开发主体框架,且可以正常使用 SEO\SSR 等现有能力。但其中影响性能的 UI 布局改由FlutterView
提供,完美解决 dom 布局渲染性能缺陷以及 Flutter Web 的缺陷。
甚至,FlutterView
只提供绘制能力,具体接口请求、业务逻辑、本地缓存都还是由框架 JS 提供,并不需要在前端架构上伤筋动骨。
再发散一下,对线上影响也不大,通过 AB 实验以及用户设备性能判断,可以自由切换由传统的 dom 渲染还是FlutterView
来渲染,甚至首屏用 dom 渲染,等 wasm 加载完成后再替换成FlutterView
。
应用场景
遗憾的是,貌似 Flutter engine group(多引擎)还没有和element embedding结合起来,那我们当下还不能在一个 HTML 页面上绘制多个FlutterView
…
那低颗粒度的用 Flutter UI 组件替换 Web 组件现在并不可行,当然也有<canvas>
本身的限制,一个 HTML 中绘制多个<canvas>
性能上也是差强人意的。
但换个思路,只解决一个页面核心性能布局是可行的。
笔者想了几个在当下就可以用到的几个场景:
长列表
笔者公司的官网,随便滚滚,内存也是在膨胀,到更多的瀑布流时,就只能采用分页这种。
瀑布流、无限滚动、虚拟列表,长列表相关的瓶颈问题都可以改用 Flutter。
从发展上看,最佳的方式如同社区提供的 RN Demo,一套 Flutter UI View 在 App 上使用 Flutter 原生渲染,在 Web 上使用<canvas>
渲染,如果这套 Flutter UI View 还是响应式布局(题外话: Flutter 响应式布局现在很 low),那就可以在各端浏览器上通用。
复杂布局
就比如笔者前面优化的这个面板,整体都可以用一个FlutterView
承接,这个布局里面有两个横向虚拟滚动,里面嵌套一个竖向瀑布流,无论怎么优化,滚动的用户体验还是性能都已经到 dom 布局的瓶颈了,实在是差强人意。
安全防护
Flutter Web 的产物是 wasm(WebAssembly),不说它反编译的效果如何,单说这个破解门槛就比 JS 高了几个档次(adobe 的源码笔者就没分析出来,只能靠猜):
无论是代码安全、用户隐私等等,安全性大大提高了。
当然,业务逻辑适不适合藏在 Flutter 中,要看具体的业务架构和需求了。笔者心中最佳的是用 Rust 而不是 Flutter 做业务逻辑,毕竟 Flutter 适合的是 UI 布局,Rust 调用底层能力十分优秀。
后续
说了这么一堆,并不能说服你的公司接受你去用它【手动狗头】。毕竟在当下,明显能感受到搞技术的基本都躺平了,活着的公司都以维护赚钱为主,性能不性能的,只要不击穿用户的底裤,肯付费就行了【手动滑稽】。
虽然大家躺的都很平,但技术的追求更多的源于内心的热爱,工作是工作,技术是技术。再退一步,至少面试的时候,领导问到的时候,也能拿出来吹吹牛逼,不是没办法优化,是这方式超出了你的底裤 ~~~
笔者后续会用 Vue3 实现一个 Flutter element embedding 的 Demo(当然,不是官方那种华而不实的 Demo)。大体的思路是使用 Vue 做业务逻辑,获取接口数据,用 Flutter 视图展示瀑布流的完整实现,来验证它的性能。
后续文章会放出源码及讲解,有兴趣的同学记得关注作者 ~~
原文链接:https://juejin.cn/post/7352713583224619060 作者:园宵