这些浏览器前端面试问题你必须知道(一)

1,119 阅读11分钟

一、你对浏览器的理解?

浏览器的主要功能是将用户选择的 web 资源呈现出来,它需要从服务器请求资源,并将其显示在浏览器窗口中,资源的格式通常 是 HTML,也包括 PDF、image 及其他格式。用户用 URI(Uniform Resource Identifier 统一资源标识符)来指定所请 求资源的位置。

HTML 和 CSS 规范中规定了浏览器解释 html 文档的方式,由 W3C 组织对这些规范进行维护,W3C 是负责制定 web 标准的 组织。

但是浏览器厂商纷纷开发自己的扩展,对规范的遵循并不完善,这为 web 开发者带来了严重的兼容性问题。

简单来说浏览器可以分为两部分,shell 和 内核。

  • shell 的种类相对比较多,内核则比较少。shell 是指浏览器的外壳:例如菜单,工具栏等。主要是提供给用户界面操作, 参数设置等等。它是调用内核来实现各种功能的。

  • 内核才是浏览器的核心。内核是基于标记语言显示内容的程序或模块。也有一些 浏览器并不区分外壳和内核。从 Mozilla 将 Gecko 独立出来后,才有了外壳和内核的明确划分。

二、介绍一下你对浏览器内核的理解?

浏览器内核是指浏览器用来解释和渲染网页的核心引擎。浏览器内核主要包括两部分:渲染引擎和 JavaScript 引擎。

渲染引擎是负责解析 HTML 和 CSS 等网页元素,然后将它们转换为可视化的页面。渲染引擎通常会先解析 HTML,构建出 DOM(文档对象模型)树,然后根据 CSS 样式信息,计算出每个元素在页面上的位置和尺寸,最终将所有元素渲染到屏幕上。常见的渲染引擎包括 Blink、Gecko、WebKit 等。

JavaScript 引擎则负责解释和执行 JavaScript 代码,为网页提供动态交互和数据处理能力。常见的 JavaScript 引擎包括 V8、SpiderMonkey、JavaScriptCore 等。

最开始渲染引擎和 JS 引擎并没有区分的很明确,后来 JS 引擎越来越独立,内核就倾向于只指渲染引擎。

三、常见浏览器内核比较

  1. Blink:由Google开发的基于WebKit的渲染引擎,用于Google Chrome、Opera等浏览器。

    • 优点:速度快,能够提供较好的网页加载速度;支持HTML5和CSS3的新特性;能够提供更好的网页渲染效果;对JavaScript引擎进行了优化,能够提供更好的性能表现。
    • 缺点:对内存的消耗较大;相对于其他内核较少的自定义选项;封闭性较高。
  2. Gecko:Mozilla开发的渲染引擎,用于Firefox浏览器。

    • 优点:稳定可靠,能够提供较高的安全性;具有高度的定制化能力;支持HTML5和CSS3的新特性;拥有完整的开发者工具集。
    • 缺点:相对于其他内核较慢的网页加载速度;渲染效果不如其他内核。
  3. WebKit:最初由苹果公司开发的渲染引擎,现在也被Google、Opera等公司采用。用于Safari、Chrome等浏览器。

    • 优点:渲染效果好,支持HTML5和CSS3的新特性;速度较快;提供多样化的可定制选项。
    • 缺点:对于一些网页代码的渲染可能会出现问题;对于低配置电脑可能较为消耗内存。
  4. Trident:由Microsoft开发的渲染引擎,用于Internet Explorer浏览器。

    • 优点:对IE浏览器的兼容性较好;对于一些IE特有的代码支持较好。
    • 缺点:渲染效果较差,对于HTML5和CSS3的新特性支持不完全;网页加载速度较慢。
  5. EdgeHTML:由Microsoft开发的渲染引擎,用于Edge浏览器。现在Edge浏览器已经改为采用Chromium内核。

    • 优点:渲染效果好,能够提供较高的网页加载速度;支持HTML5和CSS3的新特性;能够提供更好的性能表现。
    • 缺点:对一些IE特有代码的支持较差;封闭性较高。

四、常见浏览器所用内核

(1) IE 浏览器内核:Trident 内核,也是俗称的 IE 内核;

(2) Chrome 浏览器内核:统称为 Chromium 内核或 Chrome 内核,以前是 Webkit 内核,现在是 Blink内核;

(3) Firefox 浏览器内核:Gecko 内核,俗称 Firefox 内核;

(4) Safari 浏览器内核:Webkit 内核;

(5) Opera 浏览器内核:最初是自己的 Presto 内核,后来加入谷歌大军,从 Webkit 又到了 Blink 内核;

(6) 360浏览器、猎豹浏览器内核:IE + Chrome 双内核;

(7) 搜狗、遨游、QQ 浏览器内核:Trident(兼容模式)+ Webkit(高速模式);

(8) 百度浏览器、世界之窗内核:IE 内核;

(9) 2345浏览器内核:好像以前是 IE 内核,现在也是 IE + Chrome 双内核了;

(10)UC 浏览器内核:这个众口不一,UC 说是他们自己研发的 U3 内核,但好像还是基于 Webkit 和 Trident ,还有说 是基于火狐内核。

五、浏览器的渲染原理?

一文看懂浏览器解析流程:从标记化到栅格化的全过程

六、渲染过程中遇到 JS 文件怎么处理?(浏览器解析过程)

JavaScript 的加载、解析与执行会阻塞文档的解析,也就是说,在构建 DOM 时,HTML 解析器若遇到了 JavaScript,那么它会暂停文档的解析,将控制权移交给 JavaScript 引擎,等 JavaScript 引擎运行完毕,浏览器再从中断的地方恢复继续解析文档。

也就是说,如果你想首屏渲染的越快,就越不应该在首屏就加载 JS 文件,这也是都建议将 script 标签放在 body 标签底部的 原因。当然在当下,并不是说 script 标签必须放在底部,因为你可以给 script 标签添加 defer 或者 async 属性。

七、什么是文档的预解析?(浏览器解析过程)

文档的预解析(Pre-parsing)指的是在浏览器解析HTML文档时的一种优化机制,它可以在HTML文档完全解析之前,快速识别出文档中的一些关键信息,以加速页面的渲染。

在预解析过程中,浏览器会快速扫描HTML文档的结构,查找并缓存一些重要的元素和属性,例如文档的标题、脚本、样式表等等。这些信息被缓存后,浏览器就可以更快地确定如何渲染文档,同时也可以更快地执行后续的脚本代码。

预解析的过程通常发生在浏览器解析器的主线程之外,因此不会对页面的渲染和响应产生明显的影响。尽管预解析只是一种小优化,但它可以在某些情况下大大提高页面的性能和响应速度,特别是在处理大型HTML文档和复杂页面时。

一个例子是当浏览器遇到一个 script 标签时,它需要停止解析HTML文档,然后下载并解析 JavaScript 文件,执行 JavaScript 代码,然后才能继续解析HTML文档。这个过程可能会比较耗时,尤其是当JavaScript文件比较大或者网络速度比较慢时。

但是如果浏览器进行预解析,它可以在HTML文档解析的同时开始下载和解析JavaScript文件。这样,在解析完HTML文档后,JavaScript文件已经准备好了,浏览器可以立即执行 JavaScript 代码,而不需要再等待下载和解析的时间。这可以提高页面的响应速度和渲染速度。

八、CSS 如何阻塞文档解析?

理论上,既然样式表不改变 DOM 树,也就没有必要停下文档的解析等待它们,然而,存在一个问题,JavaScript 脚本执行时可能在文档的解析过程中请求样式信息,如果样式还没有加载和解析,脚本将得到错误的值,显然这将会导致很多问题。

所以如果浏览器尚未完成 CSSOM 的下载和构建,而我们却想在此时运行脚本,那么浏览器将延迟 JavaScript 脚本执行和文档的解析,直至其完成 CSSOM 的下载和构建。也就是说,在这种情况下,浏览器会先下载和构建 CSSOM,然后再执行 JavaScript,最后再继续文档的解析。

九、渲染页面时常见哪些不良现象?

在渲染页面时,常见的不良现象包括:

  1. 页面闪烁或抖动:这是由于浏览器在加载和渲染页面时,会先显示空白页面或部分内容,然后再根据样式和布局计算结果重新绘制页面。如果计算结果发生变化,就会导致页面抖动或闪烁。
  2. 白屏或黑屏:这是由于页面的内容或样式无法正确加载或渲染导致的,可能是网络连接问题、资源加载失败、脚本错误等原因造成的。
  3. 页面加载时间过长:这是由于页面的资源过多或者太大,网络速度慢,或者服务器响应时间过长等原因导致的。长时间的加载时间会导致用户等待过久,降低用户体验。
  4. 页面卡顿或响应时间慢:这是由于页面中的脚本执行时间过长,或者有大量的计算和渲染任务导致的。这可能会导致页面的响应时间变慢,用户操作不流畅,影响用户体验。
  5. 文字模糊或错位:这是由于页面的字体设置不正确,或者浏览器对字体渲染的支持不足导致的。可能需要对字体设置和渲染进行优化,以保证文字的清晰度和正确显示。

针对这些问题,可以通过优化页面结构、减少资源的加载量和大小、使用异步加载等方法进行优化和改进,以提高页面的渲染速度和用户体验。

十、如何减少重排

重排(reflow)是指浏览器重新计算元素的布局和几何属性,以确定它们在屏幕上的位置和大小。重排是一种昂贵的操作,会导致页面的性能下降。以下是一些减少重排的技巧:

  1. 避免频繁地操作 DOM 元素,可以将多次操作合并为一次操作。

  2. 使用 CSS3 的 transform 和 opacity 属性来实现动画效果,这两个属性不会引起重排。

  3. 尽可能使用固定宽度和高度的元素,避免在页面加载时需要重新计算元素的大小和位置。

  4. 避免在页面中使用 table 布局,因为 table 布局在计算时会强制进行重排。

  5. 尽可能使用绝对定位和固定定位,以避免影响其他元素的布局。

  6. 将元素设置为不可见(display:none),然后再将其显示出来,可以避免在显示之前进行重排。

  7. 避免在页面加载时执行 JavaScript,可以使用 defer 或者 async 属性延迟 JavaScript 的执行,以避免影响页面的渲染。

  8. 避免频繁地改变浏览器窗口的大小,因为这会导致浏览器重新计算页面的布局。

  9. 使用 transform 替代 top

  10. 不要把节点的属性值放在一个循环里当成循环里的变量

  11. 把 DOM 离线后修改。如:使用 documentFragment 对象在内存里操作 DOM

  12. 不要一条一条地修改 DOM 的样式。与其这样,还不如预先定义好 css 的 class,然后修改 DOM 的 className。

以上这些技巧可以帮助减少重排,从而提高页面的性能。但是需要注意,每个网站的情况都不同,需要根据具体情况进行优化。

十一、解释下documentFragment

documentFragment(文档片段)是一种轻量级的 DOM 节点,它不是真正的节点类型,而是一种容器,可以包含多个其他节点。以下是文档片段的语法和定义:

语法:

var fragment = document.createDocumentFragment();

定义: 文档片段是一个空白的文档节点,不属于 DOM 树的一部分。它是一个轻量级的容器,可以用来存储和操作文档中的节点。与普通的 DOM 节点不同,文档片段不会被渲染到页面上,它只是一个临时性的容器。

举例: 以下是一个使用文档片段的示例,假设我们需要向页面中添加 100 个列表项:

var ul = document.getElementById('list');
var fragment = document.createDocumentFragment();

for (var i = 0; i < 100; i++) {
  var li = document.createElement('li');
  li.textContent = 'List item ' + i;
  fragment.appendChild(li);
}

ul.appendChild(fragment);

在上面的示例中,我们首先获取了一个 ul 元素,并创建了一个文档片段。然后使用循环语句创建了 100 个列表项,并将它们添加到文档片段中。最后,我们将文档片段添加到 ul 元素中,这样可以避免在每次添加列表项时都进行一次 DOM 操作,从而提高性能。