游览器兼容性问题导致的线上事故
date
Feb 1, 2023
slug
record-client-compatible-error
status
Published
tags
总结
线上事故
type
Post
lang
summary
最近因为兼容性问题搞了个线上事故,暴露出不少问题,水篇文章思考思考如何避免因为兼容性导致的线上问题。
背景
最近需求上线因为游览器兼容性问题搞出个线上事故,虽然我只是个发车上线的工具人,但是对于这次兼容性导致的事故还是能总结出不少问题的,以及思考如何避免因为兼容性导致的线上问题。
主要原因是同事在代码中使用了
Array.prototype.at()
这种比较新的 API。查阅 MDN 文档可以发现,此 API 的 Chrome 版本兼容性最低要求为 92 版本,而我们的产品还有 30% 的用户在使用 86 版本 Chrome 内核的游览器(主要原因是国产游览器都将内核版本锁定在了 90 以下版本,如 360、QQ 游览器等)。事后总结的时候发现,大多数同事压根都没有见过这个 API,不过可读性只是其中比较小的一个问题。
暴露出的问题
一个线上事故无论大小,往往背后都会暴露出很多问题,我这里也总结了一些内部复盘时发现的问题。
前置代码扫描拦截上线拦截并没有做好。在这个问题发生前,组内对产品到底要兼容到什么版本的游览器并没有一个明确的定义,只有概括说明只需要支持现代游览器。这里其实应该是需要通过用户数据来判断最低应该要兼容到什么版本,并对不准备兼容的低版本用户进行强拦截,提示升级为符合要求的游览器。同时对于所有不兼容的高版本 API 都需要做 polyfill 降级处理,在需求上线前需要对代码进行扫描,出现问题时进行强制拦截。
忽视了监控的重要性,在上线的过程中,当时因为各种问题,对于 JS 报错的监控其实是属于宕机状态,但我自己并没有意识到问题的严重性,直接忽视了监控失效的问题,硬着头皮把线给上了。
对用户反馈的敏感度不足,没有关注用户反馈数量陡增问题。对于是否发生线上问题的另一种方案就是在灰度放量到上线的阶段对用户的实时反馈进行观察,当上线时用户的反馈量发生抖增,就需要重点关注是否和自己的上线内容有关了。上线的过程中其实是有部分 oncall 进线反馈出现白屏问题,但是由于排查过程中没有明确问题点导致没有及时回滚,影响了更多的用户。
后续如何规避
兼容性和 polyfill:产品定好最低游览器版本,增加前置上线代码扫描强制拦截,同时对于高版本 API 使用 polyfill 进行降级,这里需要注意的是,需要保证拦截脚本和 polyfill 的及时更新,因为一些新出来的 API 旧版本的打包工具是有可能不进行处理的;
监控:确保监控可用性,上线过程中需要持续观察监控报警,监控失效就不要上线了。同时要及时清除线上的 JS 报错,如果线上已有的错误太多,那么也会导致上线引起的新增错误无法被及时发现;碎碎念:现在没有监控现在是真没勇气上线。
关注用户反馈进线:关注用户反馈进行观测报警,增加到上线监控中;如果没有对于用户实时反馈量的监控,建议搭建一个,在用户量非常大的情况下对于线上问题的发现是非常有效的。
回滚:对于上线过程发现异常现象,大概率是代码有问题,能回滚就需要及时回滚,回滚后再慢慢排查问题;
动态下发的 polyfill
使用 polyfill 必然会带来资源体积增加,对于追求极致性能的场景就会导致性能上的问题。
因此可以考虑借助服务器端的动态下发技术,根据用户浏览器的不同,动态下发 polyfill,以达到更好的资源利用率,可以选择使用 https://polyfill.io 来实现。
如果你的 H5 页面是跑在端上的,那么同时可以考虑用户端技术,提前预加载 polyfill,提前完成等待加载过程,以提升页面性能(其他资源缓存也同理,不只 polyfill 可以进行缓存,不常变更的资源也可以进行缓存)。