说实话,我喜欢写技术文章。但今天我要分享的是:浏览器早就原生支持的9个功能,你却还在引入第三方库。
别误会——库是伟大的。但有时候,你只是为了打开一个对话框就安装了12KB的库。动笔之前,先问自己一句:浏览器是不是已经比我想得更周到了?
有时候答案确实是肯定的。
—
## 1. “等会儿再执行” → requestIdleCallback
这个API看着没什么用——就是空闲时跑点代码。但实际上用法太多了:采集用户行为数据(绝对不能在200个组件渲染时做这个)、预加载非关键数据、后端处理、后台生成图片……
function trackUserScrolling() {
console.log("用户滚动了。");
}
if ("requestIdleCallback" in window) {
requestIdleCallback(trackUserScrolling);
} else {
setTimeout(trackUserScrolling, 0);
}
支持:现代浏览器(Safari历史上缺失,建议加fallback)
—
## 2. “为什么输入框获取焦点时样式不变?” → :focus-within
给有焦点的元素加样式很简单,但如果你想给父元素加样式呢?比如让它变成粉色、加点装饰?以前你可能写40行JavaScript……现在一个CSS伪类搞定。
.form-field {
border: 1px solid #ccc;
padding: 12px;
}
.form-field:focus-within {
border-color: hotpink;
}
无需监听器、无bug、无痛苦。支持:基本所有现代浏览器。
—
## 3. “显示离线模式” → navigator.onLine
做过PWA的朋友都知道,用户断网是常态。你可以在离线时把数据存到IndexedDB,恢复网络后再同步到服务器。
window.addEventListener("offline", () => {
alert("你断网了。");
});
window.addEventListener("online", () => {
alert("网络恢复了。");
});
支持:广泛支持(但”在线”≠”你的后端正常”)
—
## 4. “流畅动画” → requestAnimationFrame
你肯定见过这种代码:
setInterval(() => {
element.style.left = Math.random() * 100 + "px";
}, 16);
卡顿是必然的。requestAnimationFrame与浏览器重绘周期同步,动画才真正流畅。
function animate() {
element.style.transform = `translateX(${Date.now() % 300}px)`;
requestAnimationFrame(animate);
}
requestAnimationFrame(animate);
支持:所有现代浏览器。
—
## 5. “这个卡片应该自适应……但只在这里生效” → 容器查询
这功能对我来说几乎是”作弊”。以前恨不得给每个组件写媒体查询,现在组件自己就能感知大小。
.card-wrapper {
container-type: inline-size;
}
.card {
display: grid;
}
@container (min-width: 400px) {
.card {
grid-template-columns: 1fr 2fr;
}
}
支持:现代浏览器(需要的话加fallback)
—
## 6. “随机ID能有什么问题?” → crypto.getRandomValues
这是Bug的温床。不同引擎实现不同、可能产生重复。crypto.getRandomValues熵更高、无奇怪模式、碰撞概率极低。
const bytes = new Uint8Array(8);
crypto.getRandomValues(bytes);
const id = Array.from(bytes)
.map(b => b.toString(16).padStart(2, "0"))
.join("");
支持:广泛支持。
—
## 7. “我们需要模态框” → <dialog>
浏览器终于说:好吧,给你一个。原生的dialog元素默认无障碍、用户喜爱。不用再为了一个弹窗引入12KB的库了。
<dialog id="modal">
<p>确定要发布吗?</p>
<button onclick="modal.close()">取消</button>
<button onclick="alert('祝你好运')">发布</button>
</dialog>
<button onclick="modal.showModal()">打开弹窗</button>
支持:现代浏览器。
—
## 8. “语音输入会很酷” → Speech API
为了语音识别就引入transformers.js?先看看浏览器自带的。至少Chromium内核的浏览器都支持。
const SpeechRecognition = window.SpeechRecognition || window.webkitSpeechRecognition;
if (SpeechRecognition) {
const recognition = new SpeechRecognition();
recognition.onresult = e => { console.log("你说的是:", e.results[0][0].transcript); };
recognition.start();
}
支持:主要是Chromium内核浏览器。
—
## 9. “这个CSS会生效吗?” → @supports
经典难题”在我电脑上明明是好的”——至少在CSS层面可以检测。用@supports判断浏览器是否支持某个特性。
.card { background: white; }
@supports (backdrop-filter: blur(10px)) {
.card {
backdrop-filter: blur(10px);
background: rgba(255, 255, 255, 0.6);
}}
支持:非常好。
—
## ⚠️ 但别误会我的意思
库是伟大的。有时候你绝对需要它们。
但有时候……你只是在为浏览器几年前就解决的问题安装依赖。在安装任何东西之前,先问问自己(或者Google):”浏览器是不是已经比我想得更周到了?”
有时候答案确实是肯定的。而这……完全没问题。😄
—
原文:9 Things You’re Overengineering (The Browser Already Solved Them) — Sylwia Laskowska




























暂无评论内容