当前位置: 首页 > java >正文

【KO】前端面试七

117. 浏览器对队头阻塞有什么优化?【百度一面】

“队头阻塞”(Head-of-Line Blocking, HOLB)指因队列头部请求/数据包阻塞,导致后续请求/数据包无法处理的问题,常见于 HTTP/1.1 资源加载TCP 传输 场景,浏览器及协议层的优化手段如下:

一、针对 HTTP/1.1 资源加载的队头阻塞优化

HTTP/1.1 因“同一 TCP 连接中,请求需串行发送”,若前一个请求阻塞(如大文件加载慢、网络波动),后续请求会被卡在队列头部。浏览器主要通过以下方式缓解:

  1. 同域名并发连接限制

    • 浏览器为每个域名建立多个 TCP 连接(如 Chrome 默认为 6-8 个),将资源请求分散到不同连接中并行传输。例如,一个页面需加载 10 张图片,会分 2 批(每批 6 个)在不同连接中请求,避免单连接串行导致的阻塞。
    • 注意:并发连接数并非越多越好,过多会增加服务器压力,因此浏览器会限制上限。
  2. 资源域名分片(Domain Sharding)

    • 前端将静态资源(图片、CSS、JS)部署到多个子域名(如 img1.example.comimg2.example.com),每个子域名独立计算并发连接数。例如,用 3 个图片子域名,可获得 3×6=18 个并发连接,大幅提升资源加载并行度,避免单域名连接数不足导致的队头阻塞。
  3. 资源预加载与预连接

    • 预连接(Preconnect):通过 <link rel="preconnect" href="https://cdn.example.com"> 提前建立与目标域名的 TCP 连接(含 DNS 解析、TCP 握手、TLS 协商),后续请求直接复用连接,减少连接建立耗时,间接降低队头阻塞影响。
    • 预加载(Preload):通过 <link rel="preload" href="critical.js" as="script"> 优先加载关键资源(如首屏 JS、CSS),避免关键资源被非关键资源阻塞在队列中。
二、针对 TCP 传输层的队头阻塞优化(浏览器依赖协议升级)

TCP 协议本身存在队头阻塞(若某数据包丢失,后续数据包需在接收端缓存,等待丢失包重传后才能处理),浏览器无法直接修改 TCP 协议,但可通过 升级 HTTP 版本 间接规避:

  1. HTTP/2 多路复用(Multiplexing)

    • HTTP/2 基于“二进制帧”传输,同一 TCP 连接中可同时发送多个请求/响应(每个请求对应一个独立的“流”),流之间相互独立,不会因某一个流的阻塞影响其他流。例如,同一连接中,图片请求阻塞时,JS 请求仍可正常传输,从根本上解决了 HTTP/1.1 的队头阻塞问题。
  2. HTTP/3 基于 QUIC 协议

    • HTTP/3 放弃 TCP,改用基于 UDP 的 QUIC 协议。QUIC 同样支持多路复用,且每个流的数据包丢失仅影响当前流(TCP 是整个连接阻塞),进一步降低了传输层队头阻塞的影响,同时还优化了连接建立速度(0-RTT 握手)。
三、浏览器渲染层的间接优化(减少资源加载阻塞)
  • 异步加载 JS:通过 async/defer 属性让 JS 加载不阻塞 HTML 解析和渲染,避免因 JS 加载慢导致的页面渲染阻塞,间接减少“资源加载队头阻塞”对用户体验的影响(详见 116 题)。
  • CSS 优先级处理:浏览器会优先加载关键 CSS(首屏样式),非关键 CSS 延迟加载,避免因大体积 CSS 加载阻塞渲染,减少后续渲染任务的队头阻塞。

118. 如何实现一个图片懒加载(Lazy Loading)功能?【必会】

图片懒加载指“仅当图片进入或即将进入浏览器视口时,才加载图片资源”,核心目的是减少首屏请求数、节省带宽、提升页面加载速度。常见实现方案如下:

一、原生 loading="lazy" 属性(最简单,推荐优先使用)

现代浏览器(Chrome 77+、Firefox 75+、Safari 15.4+)原生支持图片懒加载,无需写 JS,只需给 <img> 标签添加 loading="lazy" 属性:

<!-- 原生懒加载:仅当图片进入视口时加载 -->
<img src="placeholder.jpg"  <!-- 占位图(可选,如灰色背景图) -->data-src="real-image.jpg"  <!-- 真实图片地址(若用自定义逻辑,需配合 JS) -->loading="lazy" alt="描述"<!-- 可选:设置预加载阈值,距离视口 200px 时开始加载 -->width="600" height="400"  <!-- 必设:避免加载后页面重排 -->
>
  • 优点:零 JS 代码、浏览器原生优化、兼容性覆盖主流现代浏览器。
  • 缺点:不支持 IE 及老旧浏览器,需做降级处理;自定义控制能力弱(如无法自定义加载时机、加载动画)。
二、Intersection Observer API 实现(兼容性好,自定义能力强)

Intersection Observer 是浏览器提供的 API,可监听元素与视口(或指定容器)的“交叉状态”(即元素是否进入视口),无需手动计算滚动位置,性能优于传统 scroll 事件监听。

实现步骤:
  1. HTML 结构:用 data-src 存储真实图片地址,src 设为占位图;
  2. JS 逻辑:创建 Intersection Observer 实例,监听所有懒加载图片,当图片进入视口时,替换 srcdata-src 并停止监听。
<!-- HTML:占位图 + data-src 存真实地址 -->
<img class="lazy-img" src="placeholder.png" data-src="image1.jpg" alt="图1" width="600" height="400">
<img class="lazy-img" src="placeholder.png" data-src="image2.jpg" alt="图2" width="600" height="400"><script>
// JS:Intersection Observer 监听
document.addEventListener('DOMContentLoaded', () => {// 1. 选择所有懒加载图片const lazyImages = document.querySelectorAll('.lazy-img');// 2. 创建观察者实例:交叉时执行回调const observer = new IntersectionObserver((entries, observer) => {entries.forEach(entry => {// 3. 若图片进入视口(isIntersecting 为 true)if (entry.isIntersecting) {const img = entry.target;// 替换 src 为真实地址(加载图片)img.src = img.dataset.src;// 可选:加载完成后添加动画img.onload = () => {img.classList.add('fade-in');};// 4. 停止监听已加载的图片(避免重复触发)observer.unobserve(img);}});}, {// 可选配置:距离视口 200px 时开始加载(提前预加载)rootMargin: '200px 0px',// 可选:交叉比例达到 10% 时触发(默认 0,即只要有一点进入就触发)threshold: 0.1});// 5. 给所有懒加载图片添加监听lazyImages.forEach(img => {observer.observe(img);});
});
</script><style>
/* 可选:加载动画 */
.lazy-img {transition: opacity 0.3s ease
http://www.xdnf.cn/news/18552.html

相关文章:

  • 20250823给荣品RD-RK3588开发板刷Rockchip原厂的Android14【EVB7的V10】时调通AP6275P的WIFI
  • react相关知识
  • GitLab CI:Auto DevOps 全解析,告别繁琐配置,拥抱自动化未来
  • 运行npm run命令报错“error:0308010C:digital envelope routines::unsupported”
  • 二叉树的经典算法与应用
  • 【网安干货】--操作系统基础(上)
  • USRP采集的WiFi信号绘制星座图为方形
  • 新手向:异步编程入门asyncio最佳实践
  • K8s 实战:Pod 版本更新回滚 + 生命周期管控
  • 嵌入式学习日记(33)TCP
  • 【UnityAS】Unity Android Studio 联合开发快速入门:环境配置、AAR 集成与双向调用教程
  • CMake link_directories()详细介绍与使用指南
  • STM32F1 GPIO介绍及应用
  • C/C++三方库移植到HarmonyOS平台详细教程(补充版so库和头文件形式)
  • 凌霄飞控开发日志兼新手教程——基础篇:认识基本的文件内容和相关函数作用(25电赛备赛版)
  • 【序列晋升】12 Spring Boot 约定优于配置
  • Spring发布订阅模式详解
  • Python 调用 sora_image模型 API 实现图片生成与垫图
  • 【论文】Zotero文献管理
  • 为什么应用会突然耗尽所有数据库连接
  • 轮廓检测技术不仅能精确计算图像中的轮廓数量,还能完整记录每个轮廓包含的所有像素点坐标
  • 【0基础3ds Max】捕捉工具详解
  • 宋红康 JVM 笔记 Day06|虚拟机栈
  • [激光原理与应用-318]:结构设计 - Solidworks - 草图
  • 损耗源:导线电阻与趋肤效应
  • 深度学习②【优化算法(重点!)、数据获取与模型训练全解析】
  • 线上日志排查问题
  • MCP 与 Function Calling 打开真实世界的两种“母体”方式
  • Spring 框架深度解析:从核心原理到实战应用
  • GitLab CI :深入剖析 gl-sbom-report.cdx.json 解码“数字身份证”