刷刷题18(浏览器 中)

211 阅读4分钟

1️⃣ 事件循环(Event Loop)

一句话规则
“同步代码 → 清空微任务 → 执行一个宏任务”,循环往复。
示例代码

console.log('1');                 // 同步 → 1  
setTimeout(() => console.log(2)); // 宏任务 → 最后执行  
Promise.resolve().then(() => console.log(3)); // 微任务 → 插队先执行  
console.log('4');                 // 同步 → 4  
// 输出顺序:1 → 4 → 3 → 2  

2️⃣ 浏览器缓存策略

关键指令对比

指令行为适用场景
max-age=300300秒内不请求服务器静态资源(如图片)
no-cache每次请求需服务器验证频繁更新的数据
no-store完全不缓存敏感信息(如支付页)

1. 强缓存(直接取快递柜)

  • 触发条件Cache-Control: max-age=300 或 Expires 未过期
  • 行为:浏览器直接从内存(Memory Cache)或磁盘(Disk Cache)读取资源,不发送任何请求
  • 应用场景:静态资源(如 JS/CSS/图片),尤其是文件名带哈希的长期缓存资源(如 app.a1b2c3.js

2. 协商缓存(先打电话确认)

  • 触发条件Cache-Control: no-cache 或 max-age 已过期

  • 行为:浏览器向服务器发送请求,通过 If-Modified-Since(对应 Last-Modified)或 If-None-Match(对应 ETag)验证资源是否修改

    • 未修改 → 服务器返回 304 Not Modified,浏览器读取缓存
    • 已修改 → 服务器返回新资源 + 更新缓存头

3. 禁用缓存(禁止用快递柜)

  • 指令Cache-Control: no-store
  • 行为:浏览器和中间代理(如 CDN)均不存储任何响应内容,每次请求都从服务器获取最新资源

3️⃣ CSP 防御 XSS

<!-- 禁止内联脚本,只允许信任域名加载资源 -->  
<meta http-equiv="Content-Security-Policy"  
      content="default-src 'self';  
               script-src 'self' https://trusted-cdn.com;  
               style-src 'self' 'unsafe-inline';">  

指令解析

  • script-src 'strict-dynamic':信任由已加载脚本动态创建的脚本(如 Webpack 打包的懒加载模块)
  • report-uri:将 CSP 违规行为上报至指定端点(用于监控攻击尝试)

4️⃣ 渲染优化(Composite 阶段)

优化技巧

  1. 独立图层:对动画元素添加 transform: translateZ(0)
  2. 减少重排:避免频繁修改 width/height,用 transform 替代

5️⃣ HTTP/3 核心优势

一句话总结
解决队头阻塞:基于 UDP 的 QUIC 协议,每个请求独立传输不互相阻塞。

检测方法

fetch('https://example.com').then(res => console.log(res.protocol)); // 输出 "h3"  

6️⃣ CORS 跨域处理

两种请求类型

请求类型触发条件处理流程
简单请求GET/POST + 标准头直接发送请求
预检请求PUT/DELETE + 自定义头先发 OPTIONS 探路

7️⃣ Service Worker 离线缓存

核心原理

Service Worker 是浏览器后台运行的独立线程,可拦截网络请求并缓存资源,实现 离线访问 和 弱网优化

三步流程

  1. 注册navigator.serviceWorker.register('sw.js')
  2. 安装:在 sw.js 中缓存静态资源(caches.addAll([...])
  3. 拦截:通过 fetch 事件优先返回缓存

注册与安装

// 主线程注册 Service Worker  
if ('serviceWorker' in navigator) {
  navigator.serviceWorker.register('/sw.js')
    .then(registration => console.log('SW 注册成功'))
    .catch(err => console.log('SW 注册失败'));
}

  • sw.js:Service Worker 脚本文件,控制缓存逻辑。

安装阶段(预缓存静态资源)

// sw.js 中监听 install 事件  
const CACHE_NAME = 'v1';  
const ASSETS = ['/', '/app.js', '/styles.css'];  

self.addEventListener('install', event => {
  event.waitUntil(
    caches.open(CACHE_NAME)
      .then(cache => cache.addAll(ASSETS)) // 预缓存关键资源  
      .then(() => self.skipWaiting())     // 强制立即激活新 SW  
  );
});

拦截请求(缓存优先策略)

self.addEventListener('fetch', event => {
  event.respondWith(
    caches.match(event.request)  // 检查缓存  
      .then(cachedResponse => {
        return cachedResponse || fetch(event.request) // 缓存命中则返回,否则请求网络  
          .then(response => {
            // 动态缓存新资源  
            return caches.open(CACHE_NAME).then(cache => {
              cache.put(event.request, response.clone());
              return response;
            });
          });
      })
  );
});

8️⃣ 浏览器存储方案

三大存储对比

类型容量生命周期自动携带
Cookie4KB可设过期时间✔️
localStorage5~10MB永久存储(手动删除)✖️
sessionStorage5~10MB标签页关闭即消失✖️

9️⃣ 性能监控(Web Vitals)

核心三指标

  1. LCP(最大内容渲染):< 2.5 秒
  • 定义:页面最大内容(如图片、标题)渲染完成的时间

  • 达标值:≤ 2.5 秒

  • 优化方法

    • 预加载关键资源:<link rel="preload" href="hero-image.jpg">
    • 使用 CDN 加速静态资源
  1. CLS(布局稳定性):< 0.1
  • 定义:页面布局稳定性(元素意外移位导致用户误点击)

  • 达标值:≤ 0.1

  • 优化方法

    • 为图片/视频指定尺寸:<img width="600" height="400" src="...">
    • 避免动态插入内容覆盖现有元素 .
  1. INP(交互延迟):< 200 毫秒
  • 定义:用户交互(点击、输入)到页面响应的延迟

  • 达标值:≤ 200 毫秒

  • 优化方法

    • 拆分长任务:用 Web Workers 处理复杂计算
    • 使用 debounce/throttle 控制高频事件

🔟 Web Workers 多线程

核心规则

  • 主线程:处理 UI,不能阻塞
  • Worker 线程:通过 postMessage 通信,可处理复杂计算
  • 安全限制:不能操作 DOM

分步使用示例

  1. 创建 Worker
// 主线程  
const worker = new Worker('worker.js');  

// 发送数据给 Worker  
worker.postMessage({ type: 'sum', data: [1, 2, 3] });  

// 接收 Worker 返回结果  
worker.onmessage = event => {
  console.log('计算结果:', event.data); // 输出 6  
};

Worker 线程处理任务

// worker.js  
self.onmessage = event => {
  if (event.data.type === 'sum') {
    const result = event.data.data.reduce((a, b) => a + b, 0);  
    self.postMessage(result); // 返回结果给主线程  
  }
};