web前端中浏览器相关知识点与高频考题解析

267 阅读6分钟
Web 前端工程师写的页面要跑在浏览器里面,所以面试中也会出现很多跟浏览器相关的面试题目。

知识点梳理

  • 浏览器加载页面和渲染过程
  • 性能优化
  • Web 安全

本小节会从浏览器的加载过程开始讲解,然后介绍如何进行性能优化,最后介绍下 Web 开发中常见的安全问题和预防。

加载页面和渲染过程

可将加载过程和渲染过程分开说。回答问题的时候,关键要抓住核心的要点,把要点说全面,稍加解析即可,简明扼要不拖沓。

题目:浏览器从加载页面到渲染页面的过程

加载过程

要点如下:

  • 浏览器根据 DNS 服务器得到域名的 IP 地址
  • 向这个 IP 的机器发送 HTTP 请求
  • 服务器收到、处理并返回 HTTP 请求
  • 浏览器得到返回内容
例如在浏览器输入`https://juejin.im/timeline`,然后经过 DNS 解析,`juejin.im`对应的 IP 是`36.248.217.149`(不同时间、地点对应的 IP 可能会不同)。然后浏览器向该 IP 发送 HTTP 请求。

server 端接收到 HTTP 请求,然后经过计算(向不同的用户推送不同的内容),返回 HTTP 请求,返回的内容如下:

其实就是一堆 HMTL 格式的字符串,因为只有 HTML 格式浏览器才能正确解析,这是 W3C 标准的要求。接下来就是浏览器的渲染过程。

渲染过程

要点如下:

  • 根据 HTML 结构生成 DOM 树
  • 根据 CSS 生成 CSSOM
  • 将 DOM 和 CSSOM 整合形成 RenderTree
  • 根据 RenderTree 开始渲染和展示
  • 遇到`<script>`时,会执行并阻塞渲染

上文中,浏览器已经拿到了 server 端返回的 HTML 内容,开始解析并渲染。最初拿到的内容就是一堆字符串,必须先结构化成计算机擅长处理的基本数据结构,因此要把 HTML 字符串转化成 DOM 树 —— 树是最基本的数据结构之一。

解析过程中,如果遇到`<link href="...">`和`<scriptsrc="...">`这种外链加载 CSS 和 JS 的标签,浏览器会异步下载,下载过程和上文中下载 HTML 的流程一样。只不过,这里下载下来的字符串是 CSS 或者 JS 格式的。

浏览器将 CSS 生成 CSSOM,再将 DOM 和 CSSOM 整合成 RenderTree ,然后针对 RenderTree 即可进行渲染了。大家可以想一下,有 DOM 结构、有样式,此时就能满足渲染的条件了。另外,这里也可以解释一个问题 —— **为何要将 CSS 放在 HTML 头部?**—— 这样会让浏览器尽早拿到 CSS 尽早生成 CSSOM,然后在解析 HTML 之后可一次性生成最终的 RenderTree,渲染一次即可。如果 CSS 放在 HTML 底部,会出现渲染卡顿的情况,影响性能和体验。

最后,渲染过程中,如果遇到`<script>`就停止渲染,执行 JS 代码。因为浏览器渲染和 JS 执行共用一个线程,而且这里必须是单线程操作,多线程会产生渲染 DOM 冲突。待`<script>`内容执行完之后,浏览器继续渲染。最后再思考一个问题 —— **为何要将 JS 放在 HTML 底部?**—— JS 放在底部可以保证让浏览器优先渲染完现有的 HTML 内容,让用户先看到内容,体验好。另外,JS 执行如果涉及 DOM 操作,得等待 DOM 解析完成才行,JS 放在底部执行时,HTML 肯定都解析成了 DOM 结构。JS 如果放在 HTML 顶部,JS 执行的时候 HTML 还没来得及转换为 DOM 结构,可能会报错。

关于浏览器整个流程,百度的多益大神有更加详细的文章,推荐阅读下:《[从输入 URL 到页面加载完成的过程中都发生了什么事情? ](http://fex.baidu.com/blog/2014/05/what-happen/)》。

性能优化

性能优化的题目也是面试常考的,这类题目有很大的扩展性,能够扩展出来很多小细节,而且对个人的技术视野和业务能力有很大的挑战。这部分笔者会重点讲下常用的性能优化方案。

题目:总结前端性能优化的解决方案

优化原则和方向

性能优化的原则是**以更好的用户体验为标准**,具体就是实现下面的目标:

  • 多使用内存、缓存或者其他方法
  • 减少 CPU 和GPU 计算,更快展现

优化的方向有两个:

  • 减少页面体积,提升网络加载
  • 优化页面渲染

减少页面体积,提升网络加载

  • 静态资源的压缩合并(JS 代码压缩合并、CSS 代码压缩合并、雪碧图)
  • 静态资源缓存(资源名称加 MD5 戳)
  • 使用 CDN 让资源加载更快

优化页面渲染

  • CSS 放前面,JS 放后面
  • 懒加载(图片懒加载、下拉加载更多)
  • 减少DOM 查询,对 DOM 查询做缓存
  • 减少DOM 操作,多个操作尽量合并在一起执行(`DocumentFragment`)
  • 事件节流
  • 尽早执行操作(`DOMContentLoaded`)
  • 使用 SSR 后端渲染,数据直接输出到 HTML 中,减少浏览器使用 JS 模板渲染页面 HTML 的时间

详细解释

静态资源的压缩合并

如果不合并,每个都会走一遍之前介绍的请求过程

<script src="a.js"></script>
<script src="b.js"></script> 
<script src="c.js"></script>

如果合并了,就只走一遍请求过程

<script src="abc.js"></script> 

静态资源缓存

通过链接名称控制缓存

 <script src="abc_1.js"></script> 

只有内容改变的时候,链接名称才会改变

<script src="abc_2.js"></script>

这个名称不用手动改,可通过前端构建工具根据文件内容,为文件名称添加 MD5 后缀。

使用 CDN 让资源加载更快

CDN 会提供专业的加载优化方案,静态资源要尽量放在 CDN 上。例如:

 <script src="https://cdn.bootcss.com/zepto/1.0rc1/zepto.min.js"></script> 

使用 SSR 后端渲染

可一次性输出 HTML 内容,不用在页面渲染完成之后,再通过 Ajax 加载数据、再渲染。例如使用 smarty、Vue SSR 等。

CSS 放前面,JS 放后面

上文讲述浏览器渲染过程时已经提过,不再赘述。

懒加载

一开始先给为 `src` 赋值成一个通用的预览图,下拉时候再动态赋值成正式的图片。如下,

`preview.png`是预览图片,比较小,加载很快,而且很多图片都共用这个`preview.png`,加载一次即可。待页面下拉,图片显示出来时,再去替换`src`为`data-realsrc`的值。

 <img src="preview.png" data-realsrc="abc.png"/>

另外,这里为何要用`data-`开头的属性值?—— 所有 HTML 中自定义的属性,都应该用`data-`开头,因为`data-`开头的属性浏览器渲染的时候会忽略掉,提高渲染性能。