iOS UIWebView 的 Bug 集锦
Apple 在 App Store Review Guidelines 中提到 iOS 软件只允许使用其 WebKit 内核,事实上就是只能选择 UIWebView 和 WKWebView 来实现 Web 浏览。而官方推荐在 iOS 8 之后的系统中使用 WKWebview,UIWebView 已处于 Deprecated 状态:
In apps that run in iOS 8 and later, use the WKWebView class instead of using UIWebView. Additionally, consider setting the WKPreferences property javaScriptEnabled to false if you render files that are not supposed to run JavaScript. – Apple Developer
尽管如此,由于商业或技术上的原因很多国内浏览器仍然在使用 UIWebview。 比如 WKWebview 直到 iOS11 才支持 WKURLSchemeHandler (类似 UIWebView 的 NSURLProtocol)影响 Web 页面和 Native 通信的实现。
- QQ 浏览器。曾经是 UIWebView 现在已经切换到 WKWebview(不存在官方 Changelog)。
- 微信内置浏览器。从2017年3月1日切换到 WKWebview,参考:iOS WKWebview 网页开发适配指南。虽然不知道为啥 WKWebview 还要“适配”,WTF
- UC 浏览器。目前(版本 12.0.3.1077)仍然是 UIWebView。
- 百度(手机百度)。目前(版本 10.8.6)仍然是 UIWebView。
本文描述的是 UIWebview 下的 Bug,Safari 和基于 WKWebview 的浏览器比如 Chrome 不受影响。
touch 交互暂停动画
在发生手势交互时,页面中脚本线程会挂起,事件不再触发,动画也不会继续执行。
animation
和 transition
都会冻结。
可能是因为早期 iOS 手势操作优先的性能策略,UIWebView 的主要问题都集中在手势操作的场景下。
这是一个例子:
- 用 iOS UC 浏览器访问:https://harttle.land/animation-bugs/a-normal-animation.html ,你会看到一个旋转的动画。
- 手势触发一下页面滚动,在手指未离开屏幕期间动画会被暂停。
这里有一个录屏: https://harttle.land/animation-bugs/a-normal-animation-uiwebview.mp4
恢复滚动位置不触发 scroll 事件
浏览器都会有一个恢复滚动位置的策略:当你刷新一个已经浏览过的页面时,
页面加载后浏览器会恢复到上次滚动到的位置。
因为这一操作是在页面加载后进行的(显然要先有页面才能进行滚动),
这时浏览器会触发一个 scroll
事件。
但是 UIWebView 下不触发这个事件,可以按以下步骤复现:
- 访问这个示例页面:https://harttle.github.io/scroll-restoration-demos/scroll-event.html,每次触发 scroll 事件都会显示在页面右上角。
- 滚动到页面底部,刷新页面。
- 浏览器会恢复滚动位置到底部,然而右上角并未显示触发了
scroll
事件。
scroll 事件延迟
几乎所有前端都听说过 scroll 事件节流,因为 Webkit 下 scroll
事件会非常频繁地触发。
但 UIWebView 下却是每次开始滚动到结束滚动只触发一次 scroll
。
这意味着滚动期间无法做到任何跟随效果,由于动画、事件都被挂起,根据 MDN 的描述:
In iOS UIWebViews, scroll events are not fired while scrolling is taking place; they are only fired after the scrolling has completed. See Bootstrap issue #16202.
同样访问这个示例页面 https://harttle.github.io/scroll-restoration-demos/scroll-event.html,
每次滚动都有日志,可以查看 scroll
事件的触发频率。
本文采用 知识共享署名 4.0 国际许可协议(CC-BY 4.0)进行许可,转载注明来源即可: https://harttle.land/2018/06/23/uiwebview-bugs.html。如有疏漏、谬误、侵权请通过评论或 邮件 指出。