都2025年了,我们还有必要为了兼容性,去写那么多polyfill吗?

最近在Code Review里,我看到一个新同学在一个vite.config.js里,习惯性地加上了@vitejs/plugin-legacy,用来支持旧版浏览器。

我问他:"我们的目标用户里,真的还有人用那些浏览器吗?"

他愣了一下,说:"不知道,但加上总比不加好吧?万一呢?"

这个回答,让我陷入了沉思。"加上总比不加好",这句听起来非常正确的话,真的是对的吗?

要做好兼容性,这句话,就像一句咒语,刻在了我们这代前端工程师的骨子里。从当年大战IE6,到后来ES6普及时,为各种新语法打补丁,polyfillbabel就是我们的救命稻草。在入口文件顶部写下一行import 'core-js/stable',仿佛是一种兼容标准。

但现在都2025年了,IE早已入土为安,主流浏览器都已现代化。我越来越觉得,盲目地、无差别地为项目引入全量polyfill,已经从一个最佳实践,变成了一种技术债。


过度追求兼容性,让我们付出了哪些代价?

我们先来算一笔账。当我们无脑地引入一个完整的polyfill方案时,我们付出的代价是什么?

打包体积的代价

这是最直接的代价,最终由我们的用户来买单。

我随手在一个Vite + Vue 3的项目里,

javascirpt 复制代码
import 'core-js/stable'
import 'regenerator-runtime/runtime'

只是import 'core-js/stable',然后用rollup-plugin-visualizer分析一下打包体积:

一个完整的core-js,会给你的JS包增加几百KB的大小,而且占用整个项目78%的代码!!!这些代码,对于你项目中99%的、使用现代浏览器的用户来说,是完全用不上、不会被执行的死代码。他们却要为这部分代码,付出实实在在的流量和加载时间。

运行时性能的代价

Polyfill不只是下载下来就完事了,它还需要在浏览器里被解析和执行。虽然这个开销对于单个polyfill来说很小,但当一个庞大的polyfill集合在你的应用启动时就开始注入和执行,这无疑会增加主线程的负担,对首次可交互时间(TTI)和总阻塞时间(TBT)产生负面影响。


都2025年了,我们到底在兼容什么?

既然代价如此之大,那我们回头看看,我们如此大费周章,到底是在兼容什么?

首先,我们必须明确一点:IE已经死了!

在2025年,任何还在要求兼容IE的项目,要么是预算给够的古董维护项目,要么就应该重新评估它的商业价值。对于绝大多数面向公众的互联网产品,我们可以、也应该,大胆地和IE说再见。

其次,主流浏览器都是常青的。

Chrome, Firefox, Edge都具备自动更新能力,这意味着你绝大部分的用户,使用的都是最新或次新的浏览器版本,它们对ES2020+的特性支持都非常好。

那么,我们现在做兼容,主要目标是谁?

答案是:那些无法更新操作系统的、旧款设备上的浏览器。

所以,问题的关键就变成了:你的用户里,到底有多少人在用这些过时的浏览器?

根据 Statcounter的数据 ,全球浏览器市场份额👇:

Chrome 仍然是全球用户的首选,其次是 Safari,成为第二受欢迎的选择。Edge、Firefox 和 Samsung Internet 也占有相当大的份额,而 Opera 和其他小众浏览器则占到只有 5% 的市场份额

作为技术组长,我要求我们团队做任何关于兼容性的决策前,必须拿数据说话。打开你们自己项目的统计后台看一看,那个小于1%的others,真的值得我们让99%的用户去承担性能代价吗?


我的一些建议,Polyfill使用策略

我不是在鼓吹完全放弃兼容性,而是主张一种更智能、更精准、代价更小的策略。

明确定义 - 你的浏览器支持基线

和你的团队、产品经理一起,根据你的用户数据,明确定义出你们产品需要支持的最低浏览器版本。比如,我们可以定义为:"所有主流浏览器最近两个大版本"。把它写进团队的开发规范文档里。这是一个契约,也是我们后续做决策的依据。

放弃全量引入,按需分析

请立刻从你的项目入口文件里,删掉 import 'core-js/stable'或import 'babel-polyfill' 这种一刀🔪切的写法。

我们应该完全信赖构建工具的静态分析能力。比如,在babel.config.js里这样配置:

JavaScript 复制代码
presets: [
  ['@babel/preset-env', {
    useBuiltIns: 'usage', // 关键配置
    corejs: 3
  }]
]

useBuiltIns: 'usage' 这个选项,意味着Babel会自动检测你的代码,只把你代码中用到了的 、并且在你目标浏览器中不支持的 那些新特性,才引入对应的polyfill。这能极大地减小polyfill的体积。

考虑使用Polyfill后端服务

对于一些大型应用,可以考虑使用Polyfill服务(比如polyfill.io的自建替代品,因为官方服务曾出现过稳定性问题, 现在好像都无法访问了😒)。

它的原理是:服务器根据请求的User-Agent头,判断出用户的浏览器版本,然后只下发这个浏览器所需要的polyfill脚本。这是最高效、最精准的方案。

拥抱渐进增强,接受优雅降级

(这是一个说烂了的话题, 说白了就是 摆烂🤔)

对于一些非核心的、锦上添花的新API(比如View Transitions API),我们可以不提供polyfill。在支持的浏览器上,用户能体验到炫酷的页面切换动画;在不支持的浏览器上,它就是一个普通的页面跳转。

不是所有功能,都值得我们用增加全体用户性能负担的方式,去强行兼容。


作为开发者,我们的职责不只是实现功能,还包括控制我们产品的开发成本------这其中就包括了用户需要付出的加载成本。

为那1%的、甚至在你的用户数据里根本不存在的旧浏览器用户,让99%的现代浏览器用户去承担额外的加载负担,在2025年,这已经是一笔不划算的买卖了。

是时候检查一下你的项目了。打开你的打包分析报告,看看core-js占了多大。

然后,问问你自己:"这些代码,真的有必要吗?"

欢迎大家讨论😎

相关推荐
WeiXiao_Hyy几秒前
成为 Top 1% 的工程师
java·开发语言·javascript·经验分享·后端
吃杠碰小鸡17 分钟前
高中数学-数列-导数证明
前端·数学·算法
kingwebo'sZone23 分钟前
C#使用Aspose.Words把 word转成图片
前端·c#·word
xjt_090142 分钟前
基于 Vue 3 构建企业级 Web Components 组件库
前端·javascript·vue.js
我是伪码农1 小时前
Vue 2.3
前端·javascript·vue.js
夜郎king1 小时前
HTML5 SVG 实现日出日落动画与实时天气可视化
前端·html5·svg 日出日落
辰风沐阳1 小时前
JavaScript 的宏任务和微任务
javascript
夏幻灵2 小时前
HTML5里最常用的十大标签
前端·html·html5
冰暮流星2 小时前
javascript之二重循环练习
开发语言·javascript·数据库
Mr Xu_3 小时前
Vue 3 中 watch 的使用详解:监听响应式数据变化的利器
前端·javascript·vue.js