面试总结-1

174 阅读5分钟

一. 从输入 URL 到页面加载完成发生了什么?

  • 通过查询DNS,找到目标服务器的IP
  • 请求服务器得到一个html文档
  • 根据相应的编码格式,将html字节,转换为html字符。
  • 读取html字符,浏览器使用令牌生成器生成令牌,同时用令牌生成dom
<p>Hello</p>

令牌生成器解析为如下令牌:
StartTag:p, Hello, EndTag:p
  • 解析css,生成cssom(就是css树),浏览器也是用令牌生成器,只是跟dom的令牌生成器不大一样,css会有继承的属性。
  • dom树和css树最终形成渲染树,形成过程就是复制dom树的属性和css树的属性到渲染树上。
  • 浏览器计算节点的位置和大小等,最后完成渲染。

必须说明的是,以上过程不是从头到尾一次完成的,而是一个循环往复的过程,虽然浏览器加载页面看起来就在一瞬间完成了。

css会阻塞DOM的渲染。 遇到css资源,就是去下载和解析css,同时停止DOM的渲染。现代浏览器一般会预先扫描整个文档,去预下载css和js资源。

JS会阻塞DOM的渲染。 遇到JS会立即下载和解析,同时阻塞DOM渲染。但是JS下载和解析前如有尚未完成的css渲染,则会先完成css的渲染。

由此可以知道为什么以上渲染过程是循环往复的,因为html有很多个css和js,而CSS和JS是会阻塞DOM的渲染的,且JS中也许会操作DOM,导致一定的重排和重绘。

因此处理不好,很影响页面的性能。

二. async,defer区别

async和defer都是在不阻塞DOM解析的情况下,浏览器控制JS脚本的下载和执行的属性。

async:
script标签上带有async属性,则会异步下载脚本,同时DOM解析还在进行,关键在下载完成后就立即执行JS脚本,执行的时候会阻塞DOM解析。 因此带async的script脚本有以下两个特点:

  • 无序执行。因为JS脚本什么时候下载完不可控,async又是下载完就执行,所以决定了带async的script脚本是无序运行的,即使写在文档前面的js,如果下载慢,可能还不如文档后面下载快的脚本先执行。
  • async里面最好不操作dom。因为脚本执行时,可能dom还没解析出来。

defer:
script标签上带有defer属性,脚本会异步下载,同时DOM还在解析,关键是脚本下载完成后并不是立即执行,而是等DOM解析完成,DOMContentLoaded触发之前再执行。 因此带有defer的script有以下两个特点:

  • 有序执行。带有defer脚本的执行是在DOM解析完成后,DOMContentLoaded之前触发,所以浏览器可以有效控制执行顺序。
  • defer脚本里可以操作dom。因为DOM已经解析完成。

三. vue项目的打包体积过大怎么解决?

  • 项目分模块打包,按需加载
  • 框架按需引入
  • vue,axios,vuex等结合webpack的externals使用CDN引入
  • 图片资源走CDN,提高加载速度
  • 资源gzip

四. 首屏渲染速度要求高,除了ssr,还有什么解决方案?

延伸知识点:DevTools怎么使用

关于常规的Vue项目优化,问题三已经描述了,下面总结其他优化方法。
了解了以上页面加载过程,以及css,js,dom渲染的阻塞情况,可以从以下几个方面提高速度。

1. html文档的下载速度

涉及DNS请求你,服务器响应速度等,前端可做的优化不多。

2. css,js的下载
  • css放在头部,js放在底部,提高的是首屏的呈现时间(现代浏览器不等整个页面渲染完成,而是先呈现首屏)
  • 利用缓存,减轻服务端压力又提高了客户端的速度。
  • js可以使用async和defer,提前下载有不阻塞dom解析,提高首屏速度。
3. 资源文件的大小方面

开启gzip,显著缩小资源文件大小,提高速度。

三. vite了解吗

四. JavaScript的垃圾回收机制,闭包是怎么导致内存溢出的,结合垃圾回收机制聊聊

闭包定义: 有权访问另一个函数作用域内变量的函数。

JavaScript的垃圾回收机制:
是周期性循环进行垃圾回收。一般采用标记清除和引用计数方法。
标记清除: 当变量进入执行环境内时被标记为“进入环境”,逻辑上不清除被标记为进入环境的变量;当变量离开执行环境的时候会被标记为“离开环境”。等到下次执行垃圾回收时,就会回收这些比标记为离开环境的变量。
计数清除: 当一个引用类型的值(称为A)被赋值给一个变量的时候,这个值的计数就会加1,当这个变量被赋值为其他变量的时候,A的计数就会减1,。等到下次执行垃圾回收时,就会回收这些计数为0的变量。

闭包的变量是一直存在于内存中的,由于存在着标记,内存回收机制没办法自动回收,如果不进行手动回收,则会导致内存泄露。

如果大量的内存泄露,最终可能内存溢出,最终程序崩溃。

五. 最近在学什么?

六. 对Vue3了解多少?

七. diff算法

八. 以往的亮点项目是哪些

九. 关于回答面试官的问题,我的一些理解