我裂开了。就在今天,有个用户反馈 daima.life 的某个工具在他们那台陈旧的系统浏览器上打不开。我一看日志,好家伙,那还是三年前出的版本。作为一个极度追求性能、拒绝臃肿加载的开发者,在那一刻,我陷入了“让不让用户滚”和“写不写兼容代码”的灵魂考验。在 2026 年技术井喷的今天,兼容性这个老课题,依然是开发者绕不过去的坎。
我的思考
为什么市面上的 Polyfill 方案越来越没诚意?要么就是一刀切,让 99% 的现代浏览器用户陪着那 1% 的旧版本用户一起下载几百 KB 的臃肿代码;要么就是只管新特性,直接对旧系统宣判死刑。在 daima.life,我坚持“Privacy-First, Client-side Only”,但我也希望它是普适的。我不希望我的网站因为所谓的“现代感”,就变成了某种高冷排他的数字堡垒。
我需要一套极致的方案:让现代浏览器用户感受不到任何负担,同时让旧版本用户也能在稍长的加载时间后获得完整的工具体验。我的逻辑很简单:不该加载的,一个字节都不多发。
技术硬核区
我最后实现的是一套“边缘侧分流 + 特性探测”的混合 Polyfill 策略。核心逻辑基于 Cloudflare Workers 的边缘处理,精准识别请求头,并只下发当前浏览器真正缺失的那部分功能块。
// 核心伪代码:按需注入逻辑
async function handlePolyfills(request) {
const userAgent = request.headers.get('User-Agent');
const features = checkMissingFeatures(userAgent);
if (features.length === 0) return null; // 现代浏览器,零注入
// 动态合并所需的 Polyfill 模块
const bundle = await combinePolyfills(features);
return new Response(bundle, { headers: { 'Content-Type': 'application/javascript' } });
}
对于像 Temporal 这种巨型特性,我甚至采用了“延迟注入”。页面先秒开,只有当用户真正触发时间计算功能时,我才会去调取打包好的补丁。这种“精准打击”让我们的首包体积依然维持在 150KB 以内,没有任何妥协。
FAQ 模块
Q1: 既然用户版本那么旧,为什么不直接提示他们升级浏览器?
A: 兄弟,有些人因为工作系统的原因,并没有升级自主权。一个好的开发者工具应该像瑞士军刀一样可靠,而不是像奢侈品一样挑食。多写 10KB 的兼容逻辑,换取这类用户的信任,这账怎么算都不亏。
Q2: 用 Cloudflare 边缘判断 UA 会不会有误杀?
A: 确实存在这种风险。UA 是可以伪造的。所以我在客户端保留了最后的“特性网”,浏览器加载后会再次自检。如果检测到某个关键特性依然报错,会触发最后的兜底加载。这就是所谓的“进攻型防守”。
结尾
写完最后那行 try-catch,看着那个旧系统里的进度条终于跑完,工具完整加载出来的时候,我就知道这份“多此一举”是值得的。高性能和兼容性从来不是死敌,关键看你愿不愿意花心思去打磨这层“保护壳”。现在的你,还在无脑引入 core-js 吗?要不要来 daima.life 感受一下什么叫真正的“边缘侧零负担兼容”?...