一文搞懂前端兼容问题

标签: 前端 babel webpack 浏览器兼容性 兼容性问题 | 发表时间:2022-08-11 10:19 | 作者:卤代烃
出处:https://segmentfault.com/blogs
如果你喜欢我的文章,希望点赞 收藏 评论 三连支持一下,谢谢你,这对我真的很重要!

对于大部分开发者来说,版本兼容是一件存在感很低的事情,因为它在绝大部分情况下都是一行配置,在一些前端工具链(例如 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 36 - Chrome 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

以上的版本历史和发布时间主要参考官方更新日志/文档 和 维基百科,相关链接如下所示:





如果你喜欢我的文章,希望点赞 收藏 评论 三连支持一下,谢谢你,这对我真的很重要!

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

原文链接 对前端版本兼容问题的研究:更新更及时,阅读体验更佳。

相关 [前端 问题] 推荐:

一文搞懂前端兼容问题

- - SegmentFault 最新的文章
如果你喜欢我的文章,希望点赞 收藏 评论 三连支持一下,谢谢你,这对我真的很重要. 对于大部分开发者来说,版本兼容是一件存在感很低的事情,因为它在绝大部分情况下都是一行配置,在一些前端工具链(例如 Babel、CoreJS,Autoprefixer 等工具)的帮助下适配到目标浏览器,只会在一些大的 break change 事件(例如 Vue3 必须在支持 Proxy 的现代浏览器下才能运行)下才会关注这件不起眼的事情.

前端工程师面试问题列表

- - 博客 - 伯乐在线
前言:@ darcyclarke 在 GitHub 上分享了一个 repo,其中包括了不少前端面试问题,可用于检验潜在的候选人. 绝不推荐在单个候选人身上用上所用的问题(那样会花费好几个小时滴). 从这个列表选择一些,应该能从候选人身上,检测出你所需要的技能. 请记住,下面的很多问题都是开放式的,无标准答案,并能引发有趣的讨论.

校招面试中积累的前端问题 - Matthewsun

- - 博客园_首页
ie6/7下块级元素如何模拟display:inline-block. 众所周知,inline-block是一个很好用的属性. 它可以将对象呈递为内联对象,但是对象的内容都作为块对象呈递. 而旁边的内联对象会被呈递在同一行内,允许空格. 可惜的是,在IE6/7下是不支持这个属性的,这时我们该如何办呢.

一文读懂智能语音前端处理中的关键问题

- - 雷锋网
雷锋网编者按:本文由极限元(微信号:极限元)智能科技语音算法专家、中科院-极限元“智能交互联合实验室”核心技术人员、中科院自动化所博士刘斌整理分享,后续将会为大家分享更多智能语音技术的研究、应用等一系列的优质内容. 随着深度学习技术的快速发展,安静环境下的语音识别已基本达到实用的要求;但是面对真实环境下噪声、混响、回声的干扰,面对着更自然随意的口语表达,语音识别的性能明显下降;尤其是远讲环境下的语音识别,还难以达到实用的要求.

前端开发中使用”有限状态机“解决复杂的交互问题

- - 博客园_知识库
  前端开发是有逻辑的,这点毋庸置疑. 程序员的思维逻辑赋予了代码各种能力,但是前端开发中经常面对的是用户的操作. 在一个比较复杂的页面中(貌似现在也很少有简单页面了),用户的操作是不可预见的,假如有很多按钮,每个按钮都会做一件自己独一无二的事,如果上帝保佑所有的这些操作,这些事件都彼此没有限制,而且结果互不影响,那没有问题.

前端技术

- - CSDN博客综合推荐文章
随着互联网产业的爆炸式增长,与之伴生的Web前端技术也在历经洗礼和蜕变. 尤其是近几年随着移动终端的发展,越来越多的人开始投身或转行至新领域,这更为当今的IT产业注入了新的活力. 尽管Web前端技术诞生至今时日并不长,但随着Web技术的逐渐深入,今后将会在以下几方面发力. JavaScript的兄弟们.

稿费问题

- Ruixing F - 创造社新任社长宋石男
据说现在全中国靠给平媒自由撰稿为生的,超不过1000人,而且不少处于相当窘迫的境况,就算想买根绳子来上吊,都买不起质量好的,结果绳子老断. 作为自由撰稿人的一员,我对此深有体会. 1999年国家版权局出台的基本稿酬标准,每千字30元-100元,至今仍为全国发行的报刊的“行业指导价”. 业内估计,全国报刊的稿费中位数大约也就在100元.

lvs 问题

- - 操作系统 - ITeye博客
1: LVS连接的持久时间. 1)同一个ip发来请求到同一台RS的持久超时时间. ipvsadm -A -t 192.168.169.100:80 -s rr -p 120     #该客户的请求120秒内被分配给同一台web.  2)一个链接创建后空闲时的超时时间(分别是:tcp的空闲超时时间、lvs收到客户端tcp fin的超时时间、udp的超时时间).

Web前端优化

- - JavaScript - Web前端 - ITeye博客
优点:直接使用浏览器内存的缓存数据,减少网站后台压力,用户体验(速度)好. 缺点:对于时时变化的动态页面,这种情况就不能容忍了,因为每次访问的都是第一次访问的内容,这样即使所请求的页面已经变化了,用户也不可能知道,所以此场景必须要消除这种缓存的影响. 延迟加载,将资源延迟到需要的时候的加载,例如detail页面,相关产品推荐,当用户浏览更多的信息往下拉动滚动时,才进行加载,异步加载可以大幅减少对后端资源的使用,在需要的时候加载,是资源合理使用常用的方式,但是也带来一个问题,当往下拉才去加载,如果性能不够好,用户的体验其实是不好的,“菊花”转动的时间会比较长,同时异步加载对前端性能的作用也是非常明显的,渲染的节点数量大幅减少.

Web 前端测试

- - Web前端 - ITeye博客
Web 网站测试流程和方法(转载). 进行正式测试之前,应先确定如何开展测试,不可盲目的测试. 一般网站的测试,应按以下流程来进行:. 1)使用HTML Link Validator将网站中的错误链接找出来;. 2)测试的顺序为:自顶向下、从左到右;. 3)查看页面title是否正确. (不只首页,所有页面都要查看);.