终于找到了Flutter在iOS上卡顿的原因

最近用 Flutter 做了一个项目,上线测试的时候 iOS 界面非常卡顿,那怕一个简单的页面切换,都会卡在一半的位置,而安卓上正常。一开始以为是 Flutter 代码问题,但是经过几天的代码优化和问题排查,最后定位问题出在了服务端 https 证书上面。据说 iOS 端给 Let’s Encrypt 做联网验证,验证的地址是 http://ocsp.int-x3.letsencrypt.org ,而该地址国内无法访问,就导致 iOS 直接卡死。

这个问题在 Github 上有许多讨论,参见 dart-lang-issuedio-issue,基本上可以断定:只要在国内,服务端用了 LetsEncrypt 证书,Flutter 在 iOS 上进行网络请求就会卡顿。注意这不是 Flutter 的问题,是 iOS 系统和 LetsEncrypt 证书共同造成的问题,例如 Safari 打开 LetsEncrypt 证书的网页也会卡,所以解决方案就是换证书。

查了一下资料,OCSP 叫做在线证书状态协议(英语:Online Certificate Status Protocol,缩写:OCSP),是 TLS 协议的扩展协议,在 TLS 的使用中,客户端无法判断一个还没有过期的证书是否被吊销了。这个时候有些客户端在从服务端拿到了一个证书之后,会去找服务端的接口去验证一下这个证书的是否过期、是否吊销等,而有些则不进行客户端检查。iOS 上的软件会检查,而 Android 不检查,据说因为 Google 不满意 OCSP 这个解决方案,认为检查证书状态并不能增加安全性,反而会导致 https 请求时间变长,所以所有 Google 的产品,无论是 Android 还是 Chrome 都不进行 OCSP 检查。

如果坚持要用 LetsEncrypt 证书的话,也是有解决办法的,这篇文章里面有详细介绍,通过配置 ssl_stapling_responder 使得请求 OCSP 被发送到设置的服务器。不过建议大家还是换证书吧!