2026 浏览器原理 常见面试题(附答案)

浏览器渲染流程

1. 浏览器的整体渲染流程是什么?

答案: ① DNS 解析,建立 TCP 连接(TLS 握手);② 发送 HTTP 请求,接收响应;③ 解析 HTML 构建 DOM 树;④ 解析 CSS 构建 CSSOM 树;⑤ 合并 DOM 和 CSSOM 构建 Render Tree(只含可见节点);⑥ Layout(回流/重排):计算每个节点的位置和尺寸;⑦ Paint(重绘):生成绘制指令;⑧ Compositing(合成):将各层合并输出到屏幕。

2. 什么是 DOM 树和 CSSOM 树?

答案: DOM(Document Object Model)树是 HTML 解析后的树形表示,每个 HTML 元素是一个节点,JavaScript 通过 DOM API 操作页面结构。CSSOM(CSS Object Model)树是 CSS 解析后的树形表示,包含每个节点的完整样式信息(含继承和层叠计算结果)。只有两棵树都构建完成,浏览器才能生成 Render Tree 进行布局。

3. CSS 为什么会阻塞渲染?JS 呢?

答案: CSS 阻塞渲染:浏览器必须等 CSSOM 构建完成再构建 Render Tree,因此 CSS 加载会阻塞渲染(但不阻塞 HTML 解析)。同时 CSS 阻塞 JS 执行(JS 可能查询样式,需等 CSSOM 完成)。JS 阻塞 HTML 解析:<script> 标签会暂停 HTML 解析(可能修改 DOM),加载并执行完才继续,这是为什么 JS 推荐放在 </body> 前或使用 defer/async

4. deferasync 的区别?

答案: 两者都异步下载脚本不阻塞 HTML 解析。区别:async 下载完立即执行(暂停 HTML 解析),执行顺序不保证;defer 在 HTML 解析完成后、DOMContentLoaded 事件前按顺序执行。推荐:普通脚本用 defer;独立脚本(如统计、广告)用 async;关键脚本放 <head> 不加属性。

5. 什么是回流(Reflow)和重绘(Repaint)?

答案: 回流(Reflow/Layout):元素的几何属性(位置、尺寸)发生变化,浏览器重新计算布局,成本最高。重绘(Repaint/Paint):样式改变但不影响布局(如颜色、背景),浏览器重新绘制,成本次之。合成(Compositing):只改变变换、透明度等可由 GPU 处理的属性,最高效,不触发回流和重绘。

6. 哪些操作容易触发回流?如何优化?

答案: 触发回流的操作:修改宽高、位置、字体大小、内外边距;增删 DOM 节点;读取 offsetWidth/scrollTop/getBoundingClientRect 等强制同步布局属性。优化:① 批量修改 DOM(DocumentFragment、className 一次性修改);② 避免在循环中读写布局属性(读写分离);③ 用 transform/opacity 代替 top/left 做动画;④ 使用 will-change 提示浏览器创建独立合成层。

7. 什么是合成层(Compositing Layer)?

答案: 浏览器将部分元素提升到独立的合成层,由 GPU 处理,不触发回流和重绘。触发条件:transform: translateZ(0)will-change: transformopacity 动画、position: fixed<video>/<canvas>/<iframe>、有重叠需要处理的透明情况。过多合成层会占用大量内存,will-change 不要滥用。

8. 什么是 DOMContentLoadedload 事件的区别?

答案: DOMContentLoaded:HTML 解析完成、DOM 树构建完毕时触发,不等待样式表、图片、子框架加载完成(但会等待 defer 脚本执行完成)。load:页面所有资源(图片、CSS、JS、iframe等)全部加载完成后触发。一般 DOM 操作在 DOMContentLoaded 监听,统计页面加载完成用 load

9. 什么是 FCP、LCP、CLS、FID/INP?

答案: 这是 Core Web Vitals(核心网页指标):

  • FCP(First Contentful Paint):首次有内容绘制到屏幕的时间,衡量感知加载速度
  • LCP(Largest Contentful Paint):最大内容绘制时间,衡量主要内容加载速度(目标 <2.5s)
  • CLS(Cumulative Layout Shift):累计布局偏移分数,衡量视觉稳定性(目标 <0.1)
  • INP(Interaction to Next Paint,取代 FID):用户交互到下次绘制的延迟,衡量交互响应性(目标 <200ms)

10. 什么是关键渲染路径?如何优化?

答案: 关键渲染路径是浏览器从收到 HTML 到首次渲染的最短路径。优化方向:① 减少关键资源数量和体积(内联关键 CSS、压缩);② 减少关键路径长度(减少 RTT、CDN);③ 预加载关键资源(<link rel="preload">);④ 延迟非关键资源(defer、懒加载);⑤ 服务端渲染或流式渲染提前输出 HTML。

浏览器事件系统

11. 什么是事件捕获、目标阶段和事件冒泡?

答案: DOM 事件分三阶段:① 捕获阶段(从 window 向下到目标元素);② 目标阶段(在目标元素上触发);③ 冒泡阶段(从目标元素向上到 window)。addEventListener(event, handler, true) 在捕获阶段监听;默认(false/不传)在冒泡阶段监听。stopPropagation() 阻止向上冒泡,stopImmediatePropagation() 同时阻止同元素其他监听器。

12. 什么是事件委托?有什么好处?

答案: 事件委托利用事件冒泡,把子元素的事件监听器绑定在父元素上,通过 event.target 判断实际触发元素。好处:① 减少内存占用(一个监听器代替大量子元素监听器);② 动态新增子元素自动生效,无需重新绑定;③ 减少 DOM 操作次数。缺点:stopPropagation 会破坏委托;某些事件不冒泡(如 focus,需用 focusin 代替)。

13. event.preventDefault()event.stopPropagation() 的区别?

答案: preventDefault():阻止元素的默认行为(如阻止链接跳转、表单提交、右键菜单),不影响事件传播。stopPropagation():阻止事件继续向上冒泡(或向下捕获),不影响元素默认行为。两者相互独立,可同时调用。return false(在 jQuery 中)等价于两者都调用,原生事件中只相当于 preventDefault()

14. 什么是自定义事件(CustomEvent)?

答案: new CustomEvent('myEvent', { detail: { data: 123 }, bubbles: true, cancelable: true }) 创建自定义事件,通过 element.dispatchEvent(event) 分发,其他地方用 addEventListener('myEvent', handler) 监听。detail 字段传递自定义数据。适合跨组件、跨模块通信(原生发布订阅),不依赖框架。

浏览器存储

答案:

特性 Cookie localStorage sessionStorage
存储大小 ~4KB ~5-10MB ~5-10MB
过期时间 可设置 永久 标签页关闭
随请求发送 是(自动)
可访问域 可跨子域 同源 同源+同标签页
JS 可读 可被 HttpOnly 禁止

16. 什么是 IndexedDB?

答案: IndexedDB 是浏览器内置的 NoSQL 数据库,支持存储大量结构化数据(非字符串),支持索引、事务、游标。存储上限通常为磁盘的一定比例(远超 localStorage)。API 是异步的(基于事件,建议用 idb 等封装库)。适合离线 Web 应用、缓存大量数据(如邮件客户端、文档编辑器)。

17. 什么是 Cache API 和 Service Worker 缓存?

答案: Cache API 提供独立于 HTTP 缓存的可编程缓存机制,由 Service Worker 管理。Service Worker 是独立线程,可拦截所有网络请求,实现:离线缓存(PWA)、后台同步、推送通知。Cache API 存储 Request/Response 对,容量大,可精确控制缓存策略(Cache First、Network First、Stale-While-Revalidate)。

浏览器事件循环与性能

18. 浏览器的事件循环和 Node.js 有什么区别?

答案: 浏览器事件循环:每次循环取一个宏任务执行,执行完清空微任务队列,然后渲染(如需要),再取下一个宏任务。Node.js 事件循环:基于 libuv,有多个阶段(timers、pending callbacks、idle/prepare、poll、check、close),且有 process.nextTick(优先级高于 Promise 微任务)和 setImmediate(check 阶段)等特有 API。

19. 什么是 requestAnimationFrame?和 setTimeout 的区别?

答案: requestAnimationFrame(callback) 在下一帧绘制前执行回调,与浏览器刷新率同步(通常 60fps = 16.7ms/帧),适合动画。比 setTimeout(fn, 16) 好的地方:① 精确同步屏幕刷新,不丢帧;② 页面不可见时自动暂停(节省资源);③ 合并多个 RAF 回调,避免不必要的绘制。动画应优先用 RAF 或 CSS 动画而非 setInterval

20. 什么是 requestIdleCallback

答案: requestIdleCallback(callback) 在浏览器空闲时(主线程无高优先级任务时)执行回调,callback 接收 IdleDeadline 对象,可查询剩余空闲时间。适合非关键的后台任务(如数据上报、预加载、非紧急 DOM 操作)。React Fiber 架构受此启发,用 MessageChannel 模拟实现时间切片调度。

21. 什么是长任务(Long Task)?如何检测?

答案: 超过 50ms 的任务被称为长任务,会阻塞主线程导致页面卡顿。检测方式:① PerformanceObserver 监听 longtasks 条目;② Chrome DevTools Performance 面板(红色火焰表示长任务);③ performance.getEntriesByType('longtask')。优化:将长任务拆分为小任务(使用 scheduler.yield()setTimeout(fn, 0)requestIdleCallback)。

22. 什么是 Web Worker?

答案: Web Worker 在浏览器后台线程执行脚本,不阻塞主线程 UI,通过 postMessage 与主线程通信。Worker 无法访问 DOM,有独立的全局作用域。类型:① Dedicated Worker(专用,单页面);② Shared Worker(共享,多标签页);③ Service Worker(拦截网络请求,离线缓存)。适合 CPU 密集型任务:图像处理、数据压缩、复杂计算。

浏览器安全

23. 什么是点击劫持(Clickjacking)?如何防御?

答案: 攻击者用透明 iframe 覆盖正常页面,诱导用户点击实际上是 iframe 内目标站点的元素,执行非预期操作(如转账、授权)。防御:① 服务端设置 X-Frame-Options: DENY/SAMEORIGIN 禁止或限制被 iframe 嵌入;② CSP 的 frame-ancestors 'none' 指令;③ JS 判断 window.self !== window.top 时跳出 iframe(framebuster,可被绕过)。

24. 什么是 HTTPS 降级攻击?HSTS 如何防御?

答案: 中间人通过 SSL Stripping 将 HTTPS 连接降级为 HTTP,拦截明文数据。HSTS(HTTP Strict Transport Security)通过响应头 Strict-Transport-Security: max-age=31536000; includeSubDomains; preload 告诉浏览器该域名只能用 HTTPS 访问,并缓存此规则。浏览器在缓存期内自动将 HTTP 请求升级为 HTTPS,不给中间人降级机会。

25. 什么是子资源完整性(SRI)?

答案: SRI(Subresource Integrity)通过在 <link>/<script> 标签上加 integrity 属性(sha256-<base64hash>),让浏览器在加载资源后验证内容哈希是否匹配,防止 CDN 被篡改导致执行恶意脚本。不匹配则拒绝执行。使用第三方 CDN 时应配合 SRI 使用。

浏览器 API

26. IntersectionObserver 有什么用?

答案: IntersectionObserver 异步观察目标元素与视口(或祖先)的交叉状态,替代昂贵的 scroll 事件 + getBoundingClientRect() 方案。常用于:图片懒加载(进入视口才加载)、无限滚动、动画触发、广告曝光统计。性能远优于滚动事件监听,浏览器原生优化,不在主线程同步计算。

27. MutationObserver 有什么用?

答案: MutationObserver 异步监听 DOM 变化(子节点增删、属性变化、文本内容变化),替代已废弃的 Mutation Events(同步、性能差)。常用于:监听第三方代码对 DOM 的修改、虚拟 DOM 框架的 DOM diff 辅助、无障碍工具监听页面变化。每帧合并回调,性能友好。

28. ResizeObserver 有什么用?

答案: ResizeObserver 监听元素尺寸变化(区别于 window.resize 只监听视口),可精确监听任意元素大小变化。常用于:响应式图表(容器大小变化时重绘)、自适应组件、取代轮询判断元素大小。不触发回流,性能比 resize 事件 + getBoundingClientRect 好。

29. history API 和 hash 路由的区别?

答案: Hash 路由:URL 中 # 后的部分不发送到服务器,通过 hashchange 事件监听变化,兼容性好,服务器不需要配置。History 路由:使用 pushState/replaceState 修改 URL(无 #),通过 popstate 事件监听,URL 更美观,但需要服务器配置将所有路径返回 index.html,否则刷新 404。现代框架(React Router、Vue Router)默认推荐 History 模式。

30. 什么是浏览器的 Performance API?

答案: Performance API 提供高精度时间测量和性能数据。常用:performance.now()(比 Date.now() 精度更高);performance.mark()/measure()(自定义性能标记);PerformanceObserver 监听各类性能条目(LCP、FCP、longtasks、resource、navigation);performance.getEntriesByType('resource') 查询所有资源加载时序。是性能监控和优化的基础工具。

总结

这些题目覆盖了浏览器渲染流程、事件系统、存储机制、事件循环、性能优化、安全防护及常用 API,是深入理解前端运行环境的核心知识。

相关推荐
AlienZHOU3 小时前
AI Coding 时代下,我的技术面试实践分享
前端·后端·面试
Captaincc6 小时前
AI用量v0.1.11更新发布 新增 jusage doctor 诊断指令 托盘展示token 和余额 新增 AutoClaw 支持
前端·后端·vibecoding
计算机魔术师8 小时前
德国Wiki被黑后两周,OpenAI终于把模型失控的账本摊开了
前端
kyriewen8 小时前
我让 AI 当面试官面了我一轮:第 3 个追问我就卡住了(附 10 道追问清单)
前端·面试·ai编程
IT_陈寒8 小时前
Python的GIL把我坑惨了,多线程跑得比单线程还慢
前端·人工智能·后端
前端snow9 小时前
ai agent --- 多agent框架之图编排引擎-langgraph
前端
竹林8189 小时前
OmniPic Studio v3.2.1 核心技术架构与全平台发版解析文档
前端·浏览器
JamesZhang800789 小时前
页面内存只涨不跌? 一次泄漏排查, 牵出 WeakMap 的诞生
前端
Z小明9 小时前
第 6 章 组件进阶
前端·vue.js
江华森9 小时前
HTTP请求的完整过程详解:从DNS解析到TCP挥手的微秒级实战分析
前端