关于前端:🔬-一文搞懂前端兼容问题

如果你喜爱我的文章,心愿点赞👍 珍藏 📁 评论 💬 三连反对一下,谢谢你,这对我真的很重要!


对于大部分开发者来说,版本兼容是一件存在感很低的事件,因为它在绝大部分状况下都是一行配置,在一些前端工具链(例如 Babel、CoreJS,Autoprefixer 等工具)的帮忙下适配到指标浏览器,只会在一些大的 break change 事件(例如 Vue3 必须在反对 Proxy 的古代浏览器下能力运行)下才会关注这件不起眼的事件。

但当你略微钻研一下的时候,才会发现这块儿内容常识十分杂,因为版本兼容的相干常识没有那么多外在逻辑性,很多细碎的知识点散落在在各个商业公司的博弈和版本变更中。前段时间因工作须要对局部语言/浏览器个性重点关注了一下,以此文做一下记录。

本文次要记录了挪动端的版本适配问题,未对桌面端做更多的钻研,前面有可能补充相干内容。

1.iOS & Safari

iOS 和 Android 尽管都是一年更新一个大版本,但受害于生态的封闭性,iOS 的更新率极高,基本上最近的两个版本就能笼罩 95% 以上的人群。

例如 Apple 官网统计,截止到 2022-05-31,Apple 四年内推出的新机型中,iOS 15 曾经有 89% 的装机率,iOS 14 也有 10% 的装机率;而在所有历史机型里,iOS 15iOS 14 加起来也有 96% 的装机率,隔壁 Android 都艳羡哭了:

为什么如此关注 iOS 的版本号?因为 iOS 版本基本上和 Safari 版本一一对应的,例如 iOS 15.6 上装置着 Safari 15.6iOS 14.5 上装置着 Safari 14.1,具体的映射关系可见 MDN 的映射表,或者能够看 core-js: SafariToIOS,所以咱们基本上只有比对 iOS 版本号即可。

另外一个问题是,有肯定 C 端开发教训的开发者可能还会关注 iOS 上运行的是 UIWebView 还是 WKWebView,在 2022 年这个工夫点其实曾经不须要关注了,因为 Apple Store 曾经发过布告,2020 12 月之后曾经禁止含 UIWebView 的 APP 上架了,所以 iOS 平台只有 WKWebView 这一个 WebView 了,而且它兼容性也不错,最低反对到 iOS 8

2.Android & Chrome

说完 iOS 咱们再谈谈 Android。因为两个操作系统的倒退策略不同,再加上国内各大厂商的魔改,Android 从一开始就深陷碎片化的深渊,有 Android 开发经验的同学肯定都深有感触。

Android 零碎自身碎片化,Android 零碎自带的浏览器更碎片化。在 Android 晚期,Android 版本和 Chrome 浏览器版本是有绑定关系的,那这个晚期是有多早?那就是 Android 4,2014 年公布,绑定了 Chrome 晚期几个版本,因为数据不多,我这里就间接列出来:

// https://github.com/zloirock/core-js/blob/master/packages/core-js-compat/src/mapping.mjs
ChromeToAndroid: [
  [9, '3.0'],
  [12, '4.0'],
  [30, '4.4'],
  [33, '4.4.3'],
]

事件的转折呈现在 Android 5,这个版本里 WebView 被移植为一个独立的 APK,能够独立更新,不再和 Android 零碎深度绑定。

Google 的想法初衷是好的,借助于 Google 商店,解耦更利于浏览器的版本迭代。然而在国内多厂商魔改和一些网络问题上,极有可能产生这样的事件:对于一台 Android 5 手机,实践上用户能够装置 Chrome 36Chrome 95 任意一个版本

所以和 iOS 比照起来,Android 因为他的开放性带来重大的碎片化问题:Android 版本多样,Chrome 版本多样,还有各种魔改内核,对于开发者来说适配起来真的苦不堪言。

3.Web Browser

理解完操作系统的版本历史,咱们再看看浏览器上最要害的 JavaScript 语法兼容度。

JavaScript

最近十年内,JS 这门语言的的最大改革就是 ES6(ES2015)的公布了,带来了十分多的新个性。上面我搞了一个表格,列出几个大家罕用的 JS 语法是从哪个版本开始反对的:

语法/API iOS Chrome
Class 9 49
=> 10 45
const 11 49
let 11 49
Proxy 10 49
generators 10 39
Promise 8 33
async await 11 55
import export 10.3 61

咱们能够看到,这些语法的最低反对版本集中在 iOS 10iOS 11Chrome 49Chrome 61 这几个版本上,咱们把它们的版本公布工夫列出来:

事件 公布工夫
ES5 规范公布工夫 2009.12
ES6 规范公布工夫 2015.06
iOS 10 公布工夫 2016.06
iOS 11 公布工夫 2017.06
Chrome 49 公布工夫 2016.03
Chrome 61 公布工夫 2017.09

工夫列出来后论断基本上是跃然纸上了:ES6 规范公布后的将来一年工夫内,各大浏览器语法就反对的差不多了,两年后基本上就全副反对了这个工夫点就是 2017 年,对应着 iOS 11 Chrome 61

legacy vs modern

看完 ES6 的反对状况,咱们再来理解两个概念,「经典浏览器」和「古代浏览器」。

这两个词在英文里对应着「legacy browser」和「modern browser」。如果大家比拟关注一些绝对前沿的前端我的项目,比如说 Vue3,Solidjs,Vite,它们的官网里其实常常提到这两个词。

那么问题来了,既然有两个称说,那在工程里必然存在一个分界线去辨别 legacy 和 modern,这个分界线就是 iOS10.3Chrome 61,既浏览器反对 ES Modules 的版本(反对 <script type="module"> & import & export)。

这样一看是不是就和下面的内容对上了?Babel 官网也做了相干的解释,core-js 也专门做了辨别,更具体的介绍能够看 MDN 的文章:JavaScript modules,我就不做多余介绍了。

modern feature

通过下面的摸索,咱们再回过来看看一些比拟 modern 的 browser feature 的反对水平:

browser fature iOS Chrome
Web Worker 5 4
SubtleCrypto 7 37
Service Worker 11.3 45
WebAssembly 11 57
CSS Grid Layout 10.3 58
WebGPU not support not support

看看各个 API 的兼容度,再联合上文的内容,就能够发现很多「兼容性不好」随声附和的说法不攻自破,其实大部分状况下不是兼容度不好从而不必,是我的项目还没有简单到那个水平须要用这些高级性能

4.Open Source Project

日常开发中必定不能写一行代码查一下兼容度,这些都是由社区工具做抹平的。

兼容度数据源头能够追述到 MDN 的 browser-compat-data,记录了各种 API 的兼容,MDN 网站的兼容度间接是从这个 repo 里读的。咱们罕用的 caniuse 网站,一部分数据也是依赖于它的。

接下来是工程上依赖最多的 browserslist,babel、eslint、autoprefixer、postcss,webpack 等构建工具都依赖于它,browserslist 的数据又依赖于 caniuse-lite,其实也是依赖于 caniuse,lite 只保留了外围数据,对一些阐明文案做了裁剪解决。

综合以上剖析,咱们能够看出,在我的项目工程里依赖的 browserslist,数据准确性还是能够失去保障的,所以兼容性还是无需放心的。

5.Adaptation Suggestions

说了这么多,那么有什么配置倡议呢?我集体认为次要有 3 点倡议提供参考。

第一个是参考国民级 APP 的最低反对度配置

在国内,在日活上能称为国民级 APP 的就是微信抖音了,这两个 APP 因为日活微小,基本上曾经笼罩到全副中国人,所以他们的配置肯定有所考量,能够反馈出国内的整体手机版本程度。

从 App Store/Android 利用商店/浏览器 UA 上看,咱们能够得处以下结论(截止到 2022-8-8):

  • 微信:最低反对到 iOS 12Android 5、内置浏览器版本为 Chrome 86
  • 抖音:最低反对到 iOS 10Android 5、内置浏览器版本为 Chrome 75

当然你也能够参考其余 APP,因为精力有限我就不做过多开展了。

依据我的项目的迭代速度来看,iOS 基本上能够做到一年一降级,比如说往年 iOS 16 进去后,明年最低适配版本基本上能够升到 iOS 11 了,Android 因为长尾效应和版本不绑定的问题,应该还会反对到 Android 5

第二个倡议是间接看以后业务的版本数据

不同的公司不同的我的项目都有不同的用户场景,比如说面向三四线 C 端用户的场景,个别低端机就会多一些;面向门店的场景,说不定还得适配 IE 浏览器;面向企业内的开发者我的项目,间接适配到最新几个浏览器即可。

场景如此之多就要依赖于用户版本数据统计了。个别中大厂都有比较完善的数据监控中台,间接拉一份数据就能获取大抵状况,基建不欠缺的小公司也能够独自开个接口记录数据,收集一个月做个去重统计也能失去相干数据。拿到数据后再联合业务场景做些取舍,基本上就能够拿到最低适配了。

第三个倡议联合前端框架和 Chrome 版本做兼容。

联合前端框架其实很好了解,比如说你用了 Vue3,底层依赖于 Proxy,那么最低依赖曾经锁死到 iOS 10Chrome 49 了,那你的最低配置只能比以上版本高,如果你无脑设置为 iOS 9Android 4,除了在最低版本上跑不起来,还要平白无故的多了许多语法转换和 polyfill,在 构建速度/运行时性能/产物体积 上都会产生不必要的劣化。

联合 Chrome 版本做兼容其实就是本文第二小节的内容。因为 Android 5 之后不再和 Chrome 做深度绑定,版本兼容设置 Android 版本其实是无意义的行为,应该依据统计后果间接设置 Chrome 版本,做更细粒度的配置。

Refs: Version History

以上的版本历史和公布工夫次要参考官网更新日志/文档 和 维基百科,相干链接如下所示:

  • iOS 版本历史:https://en.wikipedia.org/wiki/IOS_version_history
  • Android 版本历史:https://en.wikipedia.org/wiki/Android_version_history
  • Chrome 版本历史:https://en.wikipedia.org/wiki/Google_Chrome_version_history
  • WKWebView API 兼容度:https://developer.apple.com/documentation/webkit/wkwebview
  • Android Verison 和 APILevel 的对应关系:https://developer.android.com/guide/topics/manifest/uses-sdk-element#ApiLevels


如果你喜爱我的文章,心愿点赞👍 珍藏 📁 评论 💬 三连反对一下,谢谢你,这对我真的很重要!

欢送大家关注我的微信公众号:卤蛋实验室,目前专一前端技术,对图形学也有一些渺小钻研。

原文链接 👉 🔬 对前端版本兼容问题的钻研:更新更及时,浏览体验更佳。

评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理