每天一个高级前端知识 - Day 11
今日主题:浏览器API深度挖掘 - 20个你不知道的现代浏览器超能力
核心概念:浏览器远比我们想象的要强大
很多强大API被主流框架的光芒掩盖,掌握它们能在不引入第三方库的情况下解决复杂问题。
🔍 第一类:性能与监控
1. PerformanceObserver - 监听性能事件
// 监听LCP (Largest Contentful Paint)
const lcpObserver = new PerformanceObserver((list) => {
const entries = list.getEntries();
const lastEntry = entries[entries.length - 1];
console.log('LCP:', lastEntry.renderTime || lastEntry.loadTime);
});
lcpObserver.observe({ type: 'largest-contentful-paint', buffered: true });
// 监听长任务(阻塞主线程超过50ms)
const longTaskObserver = new PerformanceObserver((list) => {
for (const entry of list.getEntries()) {
console.warn(`长任务检测: ${entry.duration}ms`, entry);
// 上报到监控系统
}
});
longTaskObserver.observe({ type: 'longtask', buffered: true });
// 监听布局偏移(CLS)
const clsObserver = new PerformanceObserver((list) => {
let clsValue = 0;
for (const entry of list.getEntries()) {
if (!entry.hadRecentInput) {
clsValue += entry.value;
}
}
console.log('CLS:', clsValue);
});
clsObserver.observe({ type: 'layout-shift', buffered: true });
2. scheduler.yield() - 主动让出主线程
// 处理大数据不卡顿
async function processLargeData(data) {
const chunkSize = 100;
for (let i = 0; i < data.length; i += chunkSize) {
const chunk = data.slice(i, i + chunkSize);
// 处理当前块
chunk.forEach(item => heavyComputation(item));
// 让出主线程,让用户交互和渲染有机会执行
await scheduler.yield();
}
}
// 优先级任务调度
scheduler.postTask(() => {
console.log('高优先级任务');
}, { priority: 'user-blocking' });
scheduler.postTask(() => {
console.log('低优先级任务');
}, { priority: 'background' });
3. PerformanceMark - 自定义性能标记
// 标记性能边界
performance.mark('render-start');
await renderComponent();
performance.mark('render-end');
performance.measure('render-duration', 'render-start', 'render-end');
// 自动上报
const measure = performance.getEntriesByName('render-duration')[0];
console.log(`渲染耗时: ${measure.duration}ms`);
// 清理标记
performance.clearMarks();
performance.clearMeasures();
🎨 第二类:UI与交互
4. View Transitions API - 原生动画过渡
// SPA页面切换动画
function navigateToNewPage(url) {
// 检查浏览器支持
if (!document.startViewTransition) {
updateDOM(url);
return;
}
// 自动捕获前后快照,执行过渡动画
document.startViewTransition(() => {
updateDOM(url);
});
}
// 自定义过渡动画
document.startViewTransition({
update: () => updateDOM(),
types: ['slide-in'] // 指定过渡类型
});
// CSS中定义不同过渡效果
::view-transition-old(slide-in) {
animation: slide-out 0.3s ease;
}
::view-transition-new(slide-in) {
animation: slide-in 0.3s ease;
}
5. Popover API - 原生弹窗
<!-- 不需要JS的原生弹窗 -->
<button popovertarget="my-popover">打开弹窗</button>
<div id="my-popover" popover>
<h3>原生弹窗标题</h3>
<p>这是原生popover内容</p>
<button popovertarget="my-popover" popovertargetaction="hide">关闭</button>
</div>
<!-- 悬停触发 -->
<button popovertarget="hover-popover" popovertargetaction="show">
悬停显示
</button>
<div id="hover-popover" popover="hover">
鼠标悬停时显示的内容
</div>
// 程序化控制
const popover = document.getElementById('my-popover');
popover.showPopover(); // 显示
popover.hidePopover(); // 隐藏
popover.togglePopover(); // 切换
// 监听事件
popover.addEventListener('beforetoggle', (e) => {
console.log(e.newState === 'open' ? '即将打开' : '即将关闭');
});
6. CSS Scroll Snap - 滚动捕捉
/* 横向轮播 */
.scroll-container {
display: flex;
overflow-x: auto;
scroll-snap-type: x mandatory;
scroll-behavior: smooth;
}
.scroll-item {
scroll-snap-align: start;
scroll-snap-stop: always; /* 强制停靠 */
flex: 0 0 100%;
}
/* 垂直滚动分页 */
.pagination-container {
scroll-snap-type: y proximity; /* proximity更宽松 */
}
/* 子元素不同停靠位置 */
.item:first-child {
scroll-snap-align: start;
}
.item:last-child {
scroll-snap-align: end;
}
💾 第三类:存储与数据
7. File System Access API - 读写本地文件
// 打开文件
async function openFile() {
const [fileHandle] = await window.showOpenFilePicker({
types: [{
description: '文本文件',
accept: { 'text/plain': ['.txt', '.md'] }
}],
multiple: false
});
const file = await fileHandle.getFile();
const content = await file.text();
return content;
}
// 保存文件
async function saveFile(content) {
const handle = await window.showSaveFilePicker({
suggestedName: 'document.txt',
types: [{
description: '文本文件',
accept: { 'text/plain': ['.txt'] }
}]
});
const writable = await handle.createWritable();
await writable.write(content);
await writable.close();
}
// 读写目录
async function readDirectory() {
const dirHandle = await window.showDirectoryPicker();
for await (const entry of dirHandle.values()) {
if (entry.kind === 'file') {
const file = await entry.getFile();
console.log(file.name, file.size);
}
}
}
8. Origin Private File System - 私有文件系统
// 存储大量应用数据(无大小限制)
const root = await navigator.storage.getDirectory();
// 创建文件
const fileHandle = await root.getFileHandle('data.json', { create: true });
const writable = await fileHandle.createWritable();
await writable.write(JSON.stringify({ data: 'important' }));
await writable.close();
// 读取文件
const file = await fileHandle.getFile();
const content = JSON.parse(await file.text());
// 创建目录
const dirHandle = await root.getDirectoryHandle('images', { create: true });
const imageHandle = await dirHandle.getFileHandle('photo.jpg', { create: true });
// 清空存储
await navigator.storage.estimate(); // 查看使用情况
await navigator.storage.persist(); // 请求持久化存储
🎯 第四类:设备能力
9. EyeDropper API - 取色器
const eyeDropper = new EyeDropper();
async function pickColor() {
try {
const result = await eyeDropper.open();
console.log('选中的颜色:', result.sRGBHex);
document.body.style.backgroundColor = result.sRGBHex;
} catch (err) {
console.error('取色失败:', err);
}
}
// 配合剪贴板使用
async function pickAndCopy() {
const result = await eyeDropper.open();
await navigator.clipboard.writeText(result.sRGBHex);
alert('颜色已复制: ' + result.sRGBHex);
}
10. Virtual Keyboard API - 虚拟键盘控制
// 移动端表单优化
const input = document.querySelector('input');
input.addEventListener('focus', () => {
// 控制虚拟键盘行为
if ('virtualKeyboard' in navigator) {
navigator.virtualKeyboard.overlaysContent = true;
// 键盘弹出时调整布局
navigator.virtualKeyboard.addEventListener('geometrychange', (e) => {
const { height, width } = e.target.boundingRect;
document.body.style.paddingBottom = `${height}px`;
});
}
});
// HTML方式控制
<input virtualkeyboardpolicy="manual" /> <!-- 手动控制键盘 -->
11. Badging API - 应用角标
// 设置未读消息数量
function updateUnreadCount(count) {
if ('setAppBadge' in navigator) {
if (count > 0) {
navigator.setAppBadge(count);
} else {
navigator.clearAppBadge();
}
}
}
// 通知消息时更新角标
new Notification('新消息', { body: '您有3条未读消息' });
updateUnreadCount(3);
🔐 第五类:安全与认证
12. Web Authentication API - 生物识别
// 注册生物识别凭证
async function registerBiometric() {
const publicKeyCredential = await navigator.credentials.create({
publicKey: {
challenge: new Uint8Array(32),
rp: { name: "My App" },
user: {
id: new Uint8Array(16),
name: "user@example.com",
displayName: "User"
},
pubKeyCredParams: [{ alg: -7, type: "public-key" }],
authenticatorSelection: {
authenticatorAttachment: "platform", // 平台认证器(指纹/面容)
userVerification: "required"
}
}
});
// 存储凭证ID供后续登录
localStorage.setItem('credentialId',
btoa(String.fromCharCode(...new Uint8Array(publicKeyCredential.rawId))));
}
// 生物识别登录
async function loginWithBiometric() {
const credentialId = localStorage.getItem('credentialId');
const allowCredentials = [{
id: Uint8Array.from(atob(credentialId), c => c.charCodeAt(0)),
type: 'public-key'
}];
const assertion = await navigator.credentials.get({
publicKey: {
challenge: new Uint8Array(32),
allowCredentials,
userVerification: "required"
}
});
console.log('生物识别验证成功!');
// 执行登录逻辑
}
13. Permissions API - 精细化权限管理
// 查询权限状态
async function checkPermission(permission) {
const result = await navigator.permissions.query({ name: permission });
console.log(`${permission}权限:`, result.state); // 'granted', 'denied', 'prompt'
result.addEventListener('change', () => {
console.log(`${permission}权限变更为:`, result.state);
});
return result.state;
}
// 检查多种权限
await checkPermission('geolocation');
await checkPermission('notifications');
await checkPermission('camera');
await checkPermission('microphone');
await checkPermission('clipboard-read');
// 检查存储持久化权限
const persisted = await navigator.storage.persisted();
if (!persisted) {
const granted = await navigator.storage.persist();
console.log('持久化存储授权:', granted);
}
📡 第六类:网络与通信
14. WebTransport API - 低延迟双向通信
// WebTransport: UDP-like但可靠,比WebSocket更快
const transport = new WebTransport('https://example.com:4433');
await transport.ready;
// 发送数据(无序,低延迟)
const writer = transport.datagrams.writable.getWriter();
writer.write(new Uint8Array([1, 2, 3, 4]));
// 接收数据
const reader = transport.datagrams.readable.getReader();
while (true) {
const { value, done } = await reader.read();
if (done) break;
console.log('收到数据:', value);
}
// 可靠流(有序传输)
const stream = await transport.createBidirectionalStream();
const streamWriter = stream.writable.getWriter();
const streamReader = stream.readable.getReader();
15. Network Information API - 网络质量感知
// 获取网络信息
const connection = navigator.connection || navigator.mozConnection;
console.log({
有效带宽: connection.downlink + 'Mbps',
RTT: connection.rtt + 'ms',
网络类型: connection.effectiveType, // 'slow-2g', '2g', '3g', '4g'
节省数据模式: connection.saveData
});
// 根据网络质量调整内容
connection.addEventListener('change', () => {
if (connection.saveData || connection.effectiveType === 'slow-2g') {
// 低质量模式:加载低分辨率图片,减少请求
loadLowQualityImages();
} else if (connection.effectiveType === '4g') {
// 高质量模式
loadHighQualityImages();
}
});
🎯 今日挑战
实现一个浏览器性能监控仪表板,要求:
- 实时监控LCP、FID、CLS等核心Web指标
- 监控长任务并可视化
- 显示网络状态(带宽、RTT)
- 存储监控数据到IndexedDB(使用私有文件系统)
- 提供导出报告功能(使用File System Access API)
// 使用示例
const monitor = new PerformanceMonitor();
monitor.start({
metrics: ['lcp', 'fid', 'cls', 'longtask'],
samplingInterval: 1000,
onMetricsUpdate: (metrics) => {
updateDashboard(metrics);
},
onLongTask: (task) => {
console.warn(`长任务: ${task.duration}ms, 开始于: ${task.startTime}`);
}
});
// 导出报告
document.getElementById('export').onclick = async () => {
const report = monitor.generateReport();
const handle = await window.showSaveFilePicker({
suggestedName: `performance-report-${Date.now()}.json`
});
const writable = await handle.createWritable();
await writable.write(JSON.stringify(report, null, 2));
await writable.close();
};
📚 更多强大API速查
| API | 用途 | 浏览器支持 |
|---|---|---|
| Screen Wake Lock | 防止屏幕休眠 | Chrome 84+ |
| Contact Picker | 选择联系人 | Chrome 80+ |
| Shape Detection API | 人脸/条码/文本识别 | Chrome 83+ |
| Idle Detection | 检测用户空闲状态 | Chrome 94+ |
| Periodic Background Sync | 后台定期同步 | Chrome 80+ |
| WebCodecs | 音视频编解码 | Chrome 86+ |
| Content Indexing API | 离线内容索引 | Chrome 84+ |
明日预告:设计系统实战 - 从0到1构建企业的组件库(设计令牌、无头组件、可访问性)
💡 浏览器智慧:每半年重新审视一次浏览器API,你总会有新的发现!