Flutter 学习资料及笔记总结

也许是程序员天生的鄙视链作祟,后端出身的自己一直认为前端/客户端就是一个“画皮”的事,因此一直不愿意投资时间系统地学习前端技术栈。一般都是实在不得不做前端的时候,在 github 找个功能需求差不多的代码库,修改一下上线。开发速度倒是很快,但是出来的效果总是被评价为“程序员审美”。

一直在寻找一个性价比高的方案,希望能够真正 Write once, run anywhere. 对于桌面客户端,尝试过一段时间 Electron, 但是发布安装包的体积大以及web级别的性能使得只能在有限场景下使用。移动端,当前最火的自然是 RN. 但个人是在受不了RN中屁大点的事情都搞得复杂难用,因此一直也是敬而远之。而去年12月Google发布的Flutter却让自己有了眼前一亮的感觉。

RN vs Flutter

Flutter比RN晚出生两年,而在很多概念上,其实也是借鉴的RN。无论是从社区还是成熟度来看,Flutter都还有很长一段时间要走:

但是,Flutter的设计哲学更加简单,更符合自己的品味。举个例子,Flutter中,几乎所有的UI元素都是一个 widget, 没有那些乱七八糟故弄玄虚的概念,一切都非常直白。从上表的比较可以看出,其实技术层面,Flutter其实并没有绝对的优势,在社区和成熟度上还有明显的短板,但这些都不重要。重要的是,判断一个技术是值得投资,要看未来三五年中,这个技术有没有可能成为行业标准,尤其是在大公司引领下成为事实标准。

显然,Flutter具有这样的潜力。移动开发中,在 web/H5 无法覆盖的场景,在效率和成本的驱动下,跨平台开发会是行业的趋势。最近火热的 996.icu 也算是一种从侧面透露出以后并不需要那么多的客户端开发同学。另一方面,Flutter 是Google为下一代操作系统Fusion的重要布局,且有chromium项目加持。无论从战略还是项目层面,都是天空给的足够高,翅膀长的足够硬。从这个层面看,RN简直就是一群小学生在玩过家家了(开个玩笑,不要当真)。国内方面,无论是阿里还是腾讯,都开始在Flutter上进行布局和项目技术投入。需要特别指出的是,在Flutter之前,阿里是有自研 Weex的,具体项目上,闲鱼团队已经有在实际项目中使用 Flutter.

Flutter 学习资料及笔记

Flutter 可以简单的理解为一个使用Dart语言进行开发的跨平台UI框架。因此,入门需要学习的东西主要有两块:

  1. Dart语言;
  2. Flutter 框架;

Dart 语言设计之初是为了替代 Javascript, 因此,整体上没有那么多语言bug, 会比 JS 要更加符合后端同学的语言习惯。语言入门只推荐一个官方的 A Tour of the Dart Language 学习资料。看资料的过程中,可以结合 DartPad
写一些代码片段,辅助记忆和理解。Dart 语言学习笔记:

  • 一切皆对象,默认值都是null
  • 下划线开头的变量是私有变量,跟Golang的语言设计风格类似
  • 基础类型转换,依赖 parse 和 toString 方法
  • string是 utf-16, 有点非主流
  • 函数默认值必须是 const, 规避不可重入的问题
  • Dart的所有异常都是 unchecked exception,且可以抛出任意object作为异常
  • 构造函数可以取名称,便于阅读理解,但是这点改进对于引入的复杂度并不划算

整体看,Dart 引入的一些语言特性是 python + Java 的合体。语言上中规中矩,没有什么亮点。可以看成是 javascript 的静态类型版。但是,谁让Dart搭上了Flutter这趟潜力股,而Flutter又找了Google这个大干爹呢。老实学吧,反正也就一两个小时的事。

关于Flutter本身的学习资料,其官方网站的文档一如既往地保持了 Google 级文档的水准。但是官方文档有点大而全,可能没有足够时间通读,一时半会也不容易抓住重点。我推荐几个资料你一定要仔细阅读:

学习完以上资料,附带一些课程联系,你会花大约1~2个周末的时间。学完以后,你已经初步具备开发跨平台 app 的能力了。(我个人的情况是, 两个周末学习完上面的资料,并完成一个简单的 app 开发并提交到app store审核,相信你也能做到。)

在开发app过程中,你可能会查找组件,这里推荐阿里的flutter-go.

如果需要进一步深入,可以阅读学习其他人的代码

此外,如果你关注 Flutter 在桌面端的跨平台情况,由于官方还没有发布桌面支持的正式版本。推荐你当前先watch Desktop Embedding for Fluttergo-flutter 两个项目。

总结

在Google Fusion战略和明星项目chromium加持下,以及国内巨头积极跟入的背景下,花两个周末系统学习一下Flutter个人认为是一个潜在投资性价比很高的事情。另一方面,Flutter从去年12月才发布1.0正式版,整体成熟度还不是很高,因此在实际项目中并不建议太激进的引入使用,并且Flutter在一些原生支持上海不够完善。比如,使用Flutter接收其他app分享的内容,android平台下你可以根据How do I handle incoming intents from external applications in Flutter?来解决,但是在iOS平台,当前阶段则是彻底不支持。

四五年前iOS客户端开发炙手可热的机会已经一去不复返了,Flutter也许是下一个机会。

HTTP/3 已经箭在弦上,你准备好了吗?

去年的这个时候,国内的 web 网络环境开始普及和部署 HTTP/2. 时隔一年,HTTP/2 的普及程度有了显著提升,而各大CDN厂商普及的广度和速度一直走在行业前列。甚至有不少CDN厂商在直播以及部分HTTP场景还引入了 QUIC.

在拙文《当我们在谈论HTTP队头阻塞时,我们在谈论什么?》中,我们提到,HTTP/2 over QUIC 是当前唯一应用落地解决了传输层队头阻塞问题的HTTP实现。那个时候,无论是 HTTP/2 over TCP 还是 HTTP/2 over QUIC(UDP) 都被我们认为是 HTTP/2,只是传输层使用的协议不一样。这种略带暧昧的模糊叫法在2018年11月成为了历史:

在2018年10月28日的邮件列表讨论中,互联网工程任务组(IETF) HTTP和QUIC工作组主席Mark Nottingham提出了将HTTP-over-QUIC更名为HTTP/3的正式请求,以“明确地将其标识为HTTP语义的另一个绑定……使人们理解它与QUIC的不同”,并在最终确定并发布草案后,将QUIC工作组继承到HTTP工作组。在随后的几天讨论中,Mark Nottingham的提议得到了IETF成员的接受,他们在2018年11月给出了官方批准,认可HTTP-over-QUIC成为HTTP/3。

虽然看起来像是之前的 HTTP/2 over QUIC 换了一个名称(从我个人角度理解,取名为 HTTP/2.1也许更合适),但是其背后却体现了 IETF 对 HTTP 未来标准的态度和方向,也许几年以后来看这次名称的确立会更加明白其重要意义。

HTTP/3 与 HTTP/2 over QUIC 的区别

QUIC 将成为一个通用安全传输层协议

当前阶段,Google 实现的 QUIC 与 IETF 实现的 QUIC 是不兼容的。Google 版 QUIC 只能用于 HTTP/2,且在协议层面与 HTTP/2 有一些强绑定。如 QUIC 帧映射 HTTP/2 frame. 这就导致很多大厂都没有跟进 QUIC,使得 HTTP/2 over QUIC 基本只能在 Google 自家的 Chrome, Gmail 等软件中普及使用,一度给行业造成“只有Google在弄”的错觉。

纳入 IETF 以后,显然 Google 就不能这么玩了。QUIC 定位为一个通用安全传输层协议:

可以近似的认为 QUIC over UDP 将成为下一代(或替代)TLS over TCP. 也就是说, QUIC 将能应用于任何应用层协议中,只是当前阶段将优先在 HTTP 中进行应用和验证。

统一使用 TLS 1.3 作为安全协议

2018年,有几个重要的WEB标准终于尘埃落定,其中一个便是 RFC 8446 TLS 1.3. 这个标准对于降低延迟,改善用户体验,尤其是移动端的体验有非常重要的意义。在拙文《TLS1.3/QUIC 是怎样做到 0-RTT 的》中,我们提到 虽然 TLS 1.3和 QUIC 都能做到 0-RTT,从而降低延迟,但是 QUIC 却自顾自地实现了一套安全协议。主要是因为当时 TLS 1.3 标准还没有发布,而 QUIC 又需要一套安全协议:

The QUIC crypto protocol is the part of QUIC that provides transport security to a connection. The QUIC crypto protocol is destined to die. It will be replaced by TLS 1.3 in the future, but QUIC needed a crypto protocol before TLS 1.3 was even started.

如今,TLS 1.3 标准已经发布,而 HTTP/3 也纳入 IETF,因此 QUIC 也就顺理成章的使用 TLS 1.3 作为其安全协议。Google 在这些方面倒是从来都不鸡贼和墨迹,点赞。

使用 QHPACK 头部压缩代替 HPACK

其实,QPACK与HPACK的设计非常类似,单独提出QPACK主要是更好的适配QUIC,同时也是 Google 将 QUIC 从与 HTTP/2 的耦合中抽离出来,与 IETF 标准完成统一的必要一步。

HTTP/3 问题与挑战

UDP 连通性问题

几乎所有的电信运营商都会“歧视” UDP 数据包,原因也很容易理解,毕竟历史上几次臭名昭著的 DDoS 攻击都是基于 UDP 的。国内某城宽带在某些区域更是直接禁止了非53端口的UDP数据包,而其他运营商及IDC即使没有封禁UDP,也是对UDP进行严格限流的。这点上不太乐观,但是我们相信随着标准的普及和推广落地,运营商会逐步改变对UDP流量的歧视策略。国外的情况会稍好一些,根据Google的数据,他们部署的QUIC降级的比例不到10%。

QUIC 不支持明文传输

对于用户来说,这是一个优势,并不是问题。对于国内内容审查环境来说是个不可忽视的坎。但QUIC以后毕竟也是基于TLS协议的,国内HTTPS都能普及下来,QUIC的普及也许会更乐观一些。

UDP 消耗资源多

当前阶段,UDP消耗的CPU资源多,且处理速度慢。这是不争的事实,但是我相信随着UDP应用的增多,内核和硬件的优化一定会跟上,直至达到或超过TCP的性能。而 QUIC 因为实在应用层实现,因此迭代速度更快,部署和更新难度和代价更小,能够一定程度缓解如TCP那样的协议僵化问题。

进一步了解 HTTP/3

如果希望全面的了解 HTTP/3,推荐 Daniel Stenberg (CURL 作者)的 HTTP/3 explained, 如果不想看英文,可以翻阅 Yi Bai 同学翻译了中文版本HTTP/3详解