千家信息网

浏览器的面试题有哪些

发表于:2025-11-17 作者:千家信息网编辑
千家信息网最后更新 2025年11月17日,本文小编为大家详细介绍"浏览器的面试题有哪些",内容详细,步骤清晰,细节处理妥当,希望这篇"浏览器的面试题有哪些"文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。1.常见的浏览
千家信息网最后更新 2025年11月17日浏览器的面试题有哪些

本文小编为大家详细介绍"浏览器的面试题有哪些",内容详细,步骤清晰,细节处理妥当,希望这篇"浏览器的面试题有哪些"文章能帮助大家解决疑惑,下面跟着小编的思路慢慢深入,一起来学习新知识吧。

1.常见的浏览器内核有哪些?

浏览器的内核可以分成两部分:

渲染引擎JS引擎注意:我们常说的浏览器内核就是指渲染引擎

由于JS引擎越来越独立,内核就指的只是渲染引擎了,渲染引擎主要用来请求网络页面资源解析排版后呈现给用户

浏览器/RunTime内核(渲染引擎)JavaScript 引擎
ChromeBlink(28~) Webkit(Chrome 27)V8
FireFoxGeckoSpiderMonkey
SafariWebkitJavaScriptCore
EdgeEdgeHTMLChakra(For JavaScript)
IETridentChakra(For JScript)
OperaPresto->blinkLinear A(4.0-6.1)/ Linear B(7.0-9.2)/ Futhark(9.5-10.2)/ Carakan(10.5-)
Node.js-V8

2.浏览器的主要组成部分有哪些?

  • 用户界面:包括地址栏,前进/后退/刷新/书签等按钮

  • 浏览器引擎:在用户界面和呈现引擎之间传送指令

  • 渲染引擎:用来绘制请求的内容

  • 网络:用来完成网络调用,例如http请求,它具有平台无关的接口,可以在不同平台上工作

  • JavaScript解释器:用来解析执行JavaScript代码

  • 用户界面后端:用于绘制基本的窗口小部件,比如组合框和窗口,底层使用操作系统的用户接口

  • 数据存储:属于持久层,浏览器在硬盘中保存类似cookie的各种数据,HTML5定义了web database技术,这是一种轻量级完整的客户端存储技术

注意:与大多数浏览器不同的是,谷歌(Chrome)浏览器的每个标签页都分别对应一个呈现引擎实例。每个标签页都是一个独立的进程

3.说一说从输入URL到页面呈现发生了什么?

这个题可以说是面试最常见也是一道可以无限难的题了,一般面试官出这道题就是为了考察你的前端知识深度。

1、浏览器接受URL开启网络请求线程(涉及到:浏览器机制,线程与进程等)

2、开启网络线程到发出一个完整的http请求(涉及到:DNS查询,TCP/IP请求,5层网络协议等)

3、从服务器接收到请求到对应后台接受到请求(涉及到:负载均衡,安全拦截,后台内部处理等)

4、后台与前台的http交互(涉及到:http头,响应码,报文结构,cookie等)

5、缓存问题(涉及到:http强缓存与协商缓存,缓存头,etag,expired,cache-control等)

6、浏览器接受到http数据包后的解析流程(涉及到html词法分析,解析成DOM树,解析CSS生成CSSOM树,合并生成render渲染树。然后layout布局,painting渲染,复合图层合成,GPU绘制,外链处理等)

7、css可视化模型(涉及到:元素渲染规则,如:包含块,控制框,BFC,IFC等)

8、JS引擎解析过程(涉及到:JS解析阶段,预处理阶段,执行阶段生成执行上下文,VO(全局对象),作用域链,回收机制等)

你会发现一个简单的输入URL到页面呈现,之间会发生这么多过程,是不是瞬间觉得崩溃了?(别急,这一章我们不讲这么深,先教你如何回答这个问题,后面这一节单独出文章讲)

  • 浏览器通过DNS服务器得到域名的IP地址,向这个IP地址请求得到HTML文本

  • 浏览器渲染进程解析HTML文本,构建DOM树

  • 解析HTML的同时,如果遇到内联样式或者样式文件,则下载并构建样式规则,如果遇到JavaScript脚本,则会下载执行脚本

  • DOM树和CSSOM构建完成之后,渲染进程将两者合并成渲染树(render tree)

  • 渲染进程开始对渲染树进行布局,生成布局树(layout tree)

  • 渲染树对布局树进行绘制,生成绘制记录

4.浏览器是如何解析代码的?

解析HTML

HTML是逐行解析的,浏览器的渲染引擎会将HTML文档解析并转换成DOM节点。

  • 将HTML解析成许多Tokens

  • 将Tokens解析成object

  • 将object组合成一个DOM树

解析CSS

浏览器会从右往左解析CSS选择器

我们知道DOM树与CSSOM树合并成render树,实际上是将CSSOM附着到DOM树上,因此需要根据选择器提供的信息对DOM树进行遍历。

我们看一个例子:

从右至左的匹配:

  • 先找到所有的最右节点 span,对于每一个 span,向上寻找节点 div.title

  • 由 h4再向上寻找 div.nav 的节点

  • 最后找到根元素 html 则结束这个分支的遍历。

解析JS

在浏览器中有一个js解析器的工具,专门用来解析我们的js代码。

当浏览器遇到js代码时,立马召唤"js解析器"出来工作。

解析器会找到js当中的所有变量、函数、参数等等,并且把变量赋值为未定义(undefined)。

把函数取出来成为一个函数块,然后存放到仓库当中。这件事情做完了之后才开始逐行解析代码(由上向下,由左向右),然后再去和仓库进行匹配。

5.DOMContentLoaded与load的区别?

  • DOMContentLoaded:仅当DOM解析完成后触发,不包括样式表,图片等资源。

  • Load:当页面上所有的DOM,样式表,脚本,图片等资源加载完毕事触发。

6.浏览器重绘域重排的区别?

  • 重排: 部分渲染树或整个渲染树需要重新分析且节点尺寸需要重新计算,表现为重新生成布局,重新排列元素

  • 重绘: 由于节点的几何属性发生改变或样式改变,例如元素背景元素,表现为某些元素的外观被改变

重绘不一定导致重排,但重排一定绘导致重绘

如何触发重绘和重排?

任何改变用来构建渲染树的信息都会导致一次重排或重绘:

  • 添加、删除、更新DOM节点

  • 通过display: none隐藏一个DOM节点-触发重排和重绘

  • 通过visibility: hidden隐藏一个DOM节点-只触发重绘,因为没有几何变化

  • 移动或者给页面中的DOM节点添加动画

  • 添加一个样式表,调整样式属性

  • 用户行为,例如调整窗口大小,改变字号,或者滚动。

如何避免重绘或重排?

  • 集中改变样式:比如使用class的方式来集中改变样式

  • 使用document.createDocumentFragment():我们可以通过createDocumentFragment创建一个游离于DOM树之外的节点,然后在此节点上批量操作,最后插入DOM树中,因此只触发一次重排

  • 提升为合成层

    将元素提升为合成层有以下优点:

    • 合成层的位图,会交由 GPU 合成,比 CPU 处理要快

    • 当需要repaint 时,只需要 repaint 本身,不会影响到其他的层

    • 对于 transformopacity 效果,不会触发 layoutpaint

      提升合成层的最好方式是使用 CSS 的 will-change 属性

7.为什么JS是单线程的?

这主要与JS的用途有关,JS作为浏览器的脚本语言,最初主要是实现用户与浏览器的交互,以及操作DOM。这就决定了它只能是单线程,否则会带来许多复杂的同步问题。

举个例子: 如果JS是多线程的,其中一个线程要修改一个DOM元素,另外一个线程想要删除这个DOM元素,这时候浏览器就不知道该听谁的。所以为了避免复杂性,从一诞生,JavaScript就被设计成单线程。

为了利用多核CPU的计算能力,HTML5提出Web Worker标准,允许JavaScript脚本创建多个线程,但是子线程完全受主线程控制,且不得操作DOM。所以,这个新标准并没有改变JavaScript单线程的本质

8.CSS加载会阻塞DOM吗?

先上结论

  • CSS不会阻塞DOM的解析,但会阻塞DOM的渲染

  • CSS会阻塞JS执行,但不会阻塞JS文件的下载

CSSOM的作用

  • 第一个是提供给JavaScript操作样式表的能力

  • 第二个是为布局树的合成提供基础的样式信息

  • 这个CSSOM体现在DOM中就是document.styleSheets

由之前讲到的浏览器渲染流程我们可以看出:

  • DOM和CSSOM通常是并行构建的,所以CSS加载不会阻塞DOM的解析

  • render树是依赖DOM树和CSSOM树的,所以它必须等到两者都加载完毕才能开始构建渲染,所以CSS加载会阻塞DOM的渲染

  • 由于JavaScript是可以操作DOM与CSS的,如果在修改这些元素属性同时渲染界面(即JavaScript线程与UI线程同时进行),那么渲染线程前后获得的元素可能就不一致了。所以为了防止渲染出现不可预期的结果,浏览器设置GUI渲染线程与JavaScript线程为互斥的关系

JS需要等待CSS的下载,这是为什么呢?(CSS阻塞DOM执行)

如果JS脚本的内容是获取元素的样式,那它就必然依赖CSS。因为浏览器无法感知JS内部到底想干什么,为避免样式获取,就只好等前面所有的样式下载完毕再执行JS。但JS文件与CSS文件下载是并行的,CSS文件会在后面的JS文件执行前先加载执行完毕,所以CSS会阻塞后面JS的执行

避免白屏,提高CSS的加载速度

  • 使用CDN(CDN会根据你的网络状况,挑选最近的一个具有缓存内容的节点为你提供资源,因此可以减少加载时间)

  • 对CSS进行压缩

  • 合理使用缓存

  • 减少http请求数,合并CSS文件

9.JS会阻塞页面吗?

先上结论

JS会阻塞DOM的解析,因此也就会阻塞页面的加载

这也是为什么我们常说要把JS文件放在最下面的原因

由于 JavaScript 是可操纵 DOM 的,如果在修改这些元素属性同时渲染界面(即 JavaScript 线程和 UI 线程同时运行),那么渲染线程前后获得的元素数据就可能不一致了。

因此为了防止渲染出现不可预期的结果,浏览器设置 **「GUI 渲染线程与 JavaScript 引擎为互斥」**的关系。

当 JavaScript 引擎执行时 GUI 线程会被挂起,GUI 更新会被保存在一个队列中等到引擎线程空闲时立即被执行。

当浏览器在执行 JavaScript 程序的时候,GUI 渲染线程会被保存在一个队列中,直到 JS 程序执行完成,才会接着执行。

因此如果 JS 执行的时间过长,这样就会造成页面的渲染不连贯,导致页面渲染加载阻塞的感觉。

10.defer和async的区别?

  • 两者都是异步去加载外部JS文件,不会阻塞DOM解析

  • Async是在外部JS加载完成后,浏览器空闲时,Load事件触发前执行,标记为async的脚本并不保证按照指定他们的先后顺序执行,该属性对于内联脚本无作用 (即没有**「src」**属性的脚本)。

  • defer是在JS加载完成后,整个文档解析完成后,触发 DOMContentLoaded 事件前执行,如果缺少 src 属性(即内嵌脚本),该属性不应被使用,因为这种情况下它不起作用

11.浏览器的垃圾回收机制

垃圾回收是一种自动的内存管理机制。当计算机上的动态内存不再需要时,就应该予以释放。

需要注意的是,自动的意思是浏览器可以自动帮助我们回收内存垃圾,但并不代表我们不用关心内存管理,如果操作不当,JavaScript中仍然会出现内存溢出的情况,造成系统崩溃。

由于字符串,数组,对象等都没有固定大小,因此需要当它们大小已知时,才能对他们进行动态的存储分配。JavaScript程序每次创建字符串,数组或对象时,解释器都必须分配内存来存储那个实体。

JavaScript解释器可以检测到何时程序不在使用一个对象了,当它确定这个对象是无用的时候,他就知道不再需要这个对象了,就可以把它占用的内存释放掉了。

浏览器通常采用的垃圾回收有两种方法:标记清除引用计数

标记清除

这是JavaScript中最常用的垃圾回收方式

从2012年起,所有现代浏览器都使用了标记清除的垃圾回收方法,除了低版本IE还是采用的引用计数法。

那么什么叫标记清除呢?

JavaScript中有一个全局对象,定期的,垃圾回收器将从这个全局对象开始,找出所有从这个全局对象开始引用的对象,再找这些对象引用的对象...对这些活跃的对象标记,这是标记阶段。清楚阶段就是清楚那些没有被标记的对象。

标记清除有一个问题,就是在清除之后,内存空间是不连续的,即出现了内存碎片。如果后面需要一个比较大的连续的内存空间,那将不能满足要求。而标记整理 方法可以有效德地解决这个问题。

在标记的过程中,引入了概念:三色标记法,三色为:

  • 白:未被标记的对象,即不可达对象(没有扫描到的对象),可回收

  • 灰:已被标记的对象(可达对象),但是对象还没有被扫描完,不可回收

  • 黑:已被扫描完(可达对象),不可回收

标记整理:

标记阶段与标记清除法没什么区别,只是标记结束后,标记整理法会将存活的对象向内存的一边移动,最后清理掉边界内存。

引用计数

引用计数的含义是跟踪记录每个值被引用的次数。当一个变量A被赋值时,这个值的引用次数就是1,当变量A重新赋值后,则之前那个值的引用次数就减1。当引用次数变成0时,则说明没有办法再访问这个值了,所以就可以清除这个值占用的内存了。

大多数浏览器已经放弃了这种回收方式

内存泄漏

为避免内存泄漏,一旦数据不再使用,最好通过将其值设为null来释放其引用,这个方法叫做接触引用

哪些情况会造成内存泄漏?如何避免?

以 Vue 为例,通常有这些情况:

  • 监听在 window/body 等事件没有解绑

  • 绑在 EventBus 的事件没有解绑

  • Vuex$storewatch 了之后没有 unwatch

  • 使用第三方库创建,没有调用正确的销毁函数

解决办法:beforeDestroy 中及时销毁

  • 绑定了 DOM/BOM 对象中的事件 addEventListenerremoveEventListener

  • 观察者模式 $on$off处理。

  • 如果组件中使用了定时器,应销毁处理。

  • 如果在 mounted/created 钩子中使用了第三方库初始化,对应的销毁。

  • 使用弱引用 weakMapweakSet

浏览器中不同类型变量的内存都是何时释放的?

  • 引用类型

    • 在没有引用之后,通过 V8 自动回收。

  • 基本类型

    • 如果处于闭包的情况下,要等闭包没有引用才会被 V8 回收。

    • 非闭包的情况下,等待 V8 的新生代切换的时候回收。

12.说一说浏览器的缓存机制?

认识浏览器缓存

当浏览器请求一个网站时,会加载各种资源,对于一些不经常变动的资源,浏览器会将他们保存在本地内存中,下次访问时直接加载这些资源,提高访问速度。

如何知道资源是请求的服务器还是读取的缓存呢?

看上面这张图,有些资源的size值是大小,有些是from disk cache,有些是from memory cache,显示大小的是请求的服务器资源,而显示后面两种的则是读取的缓存。

  • disk cache: 就是将资源存储在磁盘中,等待下次访问时不需重新下载,直接从磁盘中读取,它的直接操作对象为CurlCacheManager。(效率比内存缓存慢,但存储容量大,存储时间长)

  • memory cache: 就是将资源缓存到内存中,等待下次访问时不需重新下载,直接从内存中读取。(从效率上看它是最快的,从存活时间来看,它是最短的。)

-memory cachedisk cache
相同点只能存储一些派生类资源文件只能存储一些派生类资源文件
不同点退出进程时数据会被清除退出进程时数据不会被清除
存储资源一般脚本、字体、图片会存在内存当中一般非脚本会存在内存当中,如css等

浏览器缓存分类

  • 强缓存

  • 协商缓存

浏览器在向服务器请求资源时,首先判断是否命中强缓存,没命中再判断是否命中协商缓存

强缓存

浏览器在加载资源时,会先根据本地缓存资源的header中判断是否命中强缓存,如果命中则直接使用缓存中的资源,不会再向服务器发送请求。 (这里的header中的信息指的是 expirescache-control

  • Expires

该字段是 http1.0 时的规范,它的值为一个绝对时间的 GMT 格式的时间字符串,比如 Expires:Mon,18 Oct 2066 23:59:59 GMT。这个时间代表着这个资源的失效时间,在此时间之前,即命中缓存。这种方式有一个明显的缺点,由于失效时间是一个绝对时间,所以当服务器与客户端时间偏差较大时,就会导致缓存混乱。所以这种方式很快在后来的HTTP1.1版本中被抛弃了。

  • Cache-Control

Cache-Control 是 http1.1 时出现的 header 信息,主要是利用该字段的 max-age 值来进行判断,它是一个相对时间,例如 Cache-Control:max-age=3600,代表着资源的有效期是 3600 秒。cache-control 除了该字段外,还有下面几个比较常用的设置值:

no-cache:需要进行协商缓存,发送请求到服务器确认是否使用缓存。

no-store:禁止使用缓存,每一次都要重新请求数据。

public:可以被所有的用户缓存,包括终端用户和 CDN 等中间代理服务器。

private:只能被终端用户的浏览器缓存,不允许 CDN 等中继缓存服务器对其缓存。

Cache-Control 与 Expires 可以在服务端配置同时启用,同时启用的时候 Cache-Control 优先级高。

协商缓存

当强缓存没命中时,浏览器会发送一个请求到服务器,服务器根据 header 中的信息来判断是否命中协商缓存。如果命中,则返回304 ,告诉浏览器资源未更新,可以使用本地缓存。 (这里的header信息指的是Last-Modify/If-Modify-SinceETag/If-None-Match

  • Last-Modify/If-Modify-Since

浏览器第一次请求一个资源的时候,服务器返回的 header 中会加上 Last-Modify,Last-modify 是一个时间标识该资源的最后修改时间。

当浏览器再次请求该资源时,request 的请求头中会包含 If-Modify-Since,该值为缓存之前返回的 Last-Modify。服务器收到 If-Modify-Since 后,根据资源的最后修改时间判断是否命中缓存。

如果命中缓存,则返回 304,并且不会返回资源内容,并且不会返回 Last-Modify。

缺点:

短时间内资源发生了改变,Last-Modified 并不会发生变化。

周期性变化。如果这个资源在一个周期内修改回原来的样子了,我们认为是可以使用缓存的,但是 Last-Modified 可不这样认为,因此便有了 ETag。

  • ETag/If-None-Match

与 Last-Modify/If-Modify-Since 不同的是,Etag/If-None-Match 返回的是一个校验码。ETag 可以保证每一个资源是唯一的,资源变化都会导致 ETag 变化。服务器根据浏览器上送的 If-None-Match 值来判断是否命中缓存。

与 Last-Modified 不一样的是,当服务器返回 304 Not Modified 的响应时,由于 ETag 重新生成过,response header 中还会把这个 ETag 返回,即使这个 ETag 跟之前的没有变化。

Last-Modified 与 ETag 是可以一起使用的,服务器会优先验证 ETag,一致的情况下,才会继续比对 Last-Modified,最后才决定是否返回 304。

总结

当浏览器访问一个已经访问过的资源是,它的步骤是:

1.先看是否命中强缓存,命中?的话直接使用缓存

2.没命中强缓存,则会发送请求到服务器看是否命中?协商缓存

3.如果命中了协商缓存,服务器会返回304告诉浏览器可以使用本地缓存

4.没命中协商缓存,则服务器会返回新的资源给浏览器

13.什么是浏览器的同源策略,以及跨域?

同源策略

同源策略是浏览器的一种自我保护行为。所谓的同源指的是:协议,域名,端口均要相同

浏览器中大部分内容都是受同源策略限制的,但是以下三个标签不受限制:

跨域

跨域指的是浏览器不能执行其它域名下的脚本。它是由浏览器的同源策略限制的。

你可能会想跨域请求到底有没有发送到服务器?

事实上,跨域请求时能够发送到服务器的,并且服务器也能过接受的请求并正常返回结果,只是结果被浏览器拦截了。

跨域解决方案(列出几个常用的)
  • JSONP

它主要是利用script标签不受浏览器同源策略的限制,可以拿到从其他源传输过来的数据,需要服务端支持。

优缺点:

兼容性比较好,可用于解决主流浏览器的跨域数据访问的问题。缺点就是仅支持get请求,具有局限性,不安全,可能会受到XSS攻击。

思路:

  • 声明一个回调函数,其函数名(如show)当做参数值,要传递给跨域请求数据的服务器,函数形参为要获取目标数据(服务器返回的data)。

浏览 浏览器 服务 攻击 缓存 服务器 资源 用户 页面 对象 线程 内存 数据 网站 情况 域名 标记 脚本 引擎 策略 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 如何打开WPS数据库 合肥联宝服务器维修工作环境 大创软件开发申请书 批量更新多个数据库表 宿迁机械软件开发流程 湘潭软件开发培训哪里好 福建工程学院专利数据库 商品评论用什么数据库比较好 软件开发市场的占有率 为什么服务器被限制 网络安全宣传画四年级 泰拉瑞亚手机版服务器怎么登录 洛阳锦游网络技术有限公司 mysql数据库能存视频 软件开发项目管理与需求分析 网络安全保障技术人才最重要 中专计算机网络技术应用 人气协议软件开发源码 向星社区提高网络安全意识 cas 数据库配置 多媒体通信网络安全教育 璧山区企业网络技术服务活动方案 黑钛网络技术有限责任公司 数据库有线程安全 宁波向海软件开发有限公司 数据库自动关闭连接 永宁县办公软件开发案例 三级网络技术题目 增值税发票填开系统服务器端口 网络安全工作缺乏
0