2021非面试季前端知识整理总结

这次对前端技术涉及到的点进行了一次有序的整理,这样记得更牢,也希望可以帮助到大家,下面是目录结构。(其中有很多内容被简化了,有兴趣可以查看每个目录下的参考文档,内容相对更加详情)

Js基础

事件循环

一个事件循环又一个货多个任务队列;一个任务队列是一组任务;

1. 每个事件循环是一个正在运行的任务,它可以是一个任务或null;

2. 每个事件循环具有microtask队列(微任务队列),最初为空;

3. 每个事件循环都有一个执行微任务检查点的布尔值,该布尔值最初为false;

1. js的事件循环如何环执行?

浏览器事件循环执行顺序:

  1. 首先执行script脚本同步代码,属于宏任务;
  2. 当执行完当前所有同步任务后,执行栈为空,查询是否有异步任务代码需要执行;
  3. 执行当前宏任务下的所有微任务;
  4. 微任务执行完之后,如有必要会渲染页面;
  5. 然后开始下一轮事件循环;

2. 宏任务和微任务有哪些?

宏任务:script、setTimeout、setInterval、setImmediate、I/O、UI Render;

微任务:process.nextTick、promise、MutationObsever;


3. Nodejs的事件循环和浏览器事件循环区别?

Nodejs和浏览器端,宏任务和微任务交替执行,调用顺序基本相同。Nodejs执行会进行阶段区分,分为6个阶段:参考:Node.js 事件循环文档,每进入某个阶段,会从回调队列中取出函数执行。当队列为空或回调函数达到系统设定阈值,就进入下一个阶段。


异步方案

可以把ajax异步回调作为浏览器端的最初的异步解决方案,异步回调 ———> Promise实例 ——> Generator ——> async/await,大致是一个这样的线,我们需要关注的可能主要就是Promise 和 async/await的方案。

1. Promise内部实现了解嘛?它的具体工作流程是怎么样的?

Promise是异步解决方案,包含异步操作结果的对象,特点:内部存在三种状态,状态一旦变化不可更改状态;Promise是链式调用,每次调用then回调函数都会返回一个新的Promise,并且是一个全新的Promise;

Promise异步处理流:执行Promise实例回调函数,由于异步请求或者操作,此时状态未变化。继续执行then回调,由于状态未变化回调会被放入回调数组中。直到Promise实例中异步请求或者操作完成,状态发生变化,调用resolve函数,回调数组遍历执行,then回调函数拿到相关数据


2. 说一说async/await

参考:

Promise原理解析

图解Promise流程

浏览器渲染原理

浏览器是多进程应用,每打开一个Tab页,就相当于创建了一个独立的浏览器进程。浏览器进程有:Browser进程(主进程)、插件进程、GPU进程、渲染进程(浏览器内核)。主进程只有一个是负责协调应用,同时默认每个Tab页面一个渲染进程,互不影响。我们常说的Js线程、GUI渲染线程就包含在渲染进程之中,还包括异步http请求线程、事件触发线程等。

1. 地址栏输入域名地址之后发生了什么?

1. DNS服务查询域名对应的目标服务IP地址;
2. 根据目标IP地址查找到目标服务器,并建立TCP连接;
3. 服务器响应返回数据或文本信息等;
4. 客户端获取到数据之后进行页面渲染;

2. 浏览器渲染的流程?

1. 请求html文件处理html标记构建DOM树;
2. 请求css文件处理css标记构建CSSOM树;
3. 将DOM和CSSOM合并成一个渲染树;
4. 根据渲染树布局,以计算每个节点的几何信息;
5. 将各节点绘制在屏幕上;

存在阻塞的css资源时,浏览器会延迟JS的执行和DOM的构建;

3. 重绘和回流?

重绘是当节点需要更改外观而不影响布局;回流是布局或几何属性需要改变;

参考:渲染性能

参考:

从浏览器多进程到JS单线程

你不知道的浏览器页面渲染机制

网络协议

关于TCP和UDP的介绍、TCP的三次握手和四次挥手就不细说,相关文章可以参考:传输层协议TCP和UDP TCP三次握手和四次挥手

http协议是常用的网络传输协议,全称是超文本传输协议,它规定了http请求和响应的具体结构,当然还包含其他东西,例如:缓存、文件类型、参数、请求类型、状态等。它是建立在传输层TCP协议之上的,TCP握手成功之后,才可以进行网络数据传输。

HTTP/HTTPS

1. 什么是http协议?它是怎么样的?

http是TCP/IP协议应用层协议,主要负责数据或文本图片等内容的传输,它是建立在传输层TCP协议之上的。http分为请求报文和响应报文,从Web客户端发往Web服务器的HTTP报文称为请求报文(request message)。从服务器发往客户端的报文称为响应报文,报文分为:起始行、 首部字段、主体等;


2. http和https的区别?

http和https从字面的区别就是一个s,这个s就是SSL/TCL加密协议。说到加密协议就绕不开加密技术,在SSL/TCL加密协议中既有用到非对称加密,也有用到对称加密。SSL/TCL加密协议相当于是在应用层和传输层之间加了一层,可称为加密层。

大致流程:客户端向服务器端索要加密证书获取公钥等证书信息;双方协商生成"对话密钥";双方采用"对话密钥"进行加密通信。非对称加密保证"对话密钥"的安全传输,对称加密保证客户端和服务端对数据的加解密。


3. http网络缓存如何配置?

如果需要开启强缓存和协商缓存,可在服务端nginx web服务器进行对应的配置,开启对应的网络缓存。其他服务端web服务器也可配置。(配置细节网上一大堆)


4. 强缓存和协商缓存的区别?

强缓存:Cache-Control,常用属性有max-age、no-cache、no-store等。max-age表示相对时间内的缓存,在这个相对时间内不会再去请求对应资源;no-cache表示不意味着不缓存,它的意思是在使用缓存资源之前,它必须经过服务器的检查; no-store表示不缓存。

协商缓存:Last-modified 和 ETag,这两个类似,可以理解为文件标识。也可以将ETag(你选择的版本ID)或者Last-modified日期添加到响应首部中。客户端下次获取资源时,他会分别通过If-None-Match(与ETage对应)和If-Modified-Since(与Last-Mofied对应)两个请求首部将值发送给服务器。如果服务器发现两次值都是对等的,就是返回一个HTTP 304。它们之间的区别:ETag 只要资源变化,它就会改变;Last-modified 不识别秒单位里的修改。

如何使用—————前端中保证HTML资源是最新的,设置如:max-age=300、ETag、Last-modified,当然也可考虑使用no-cache、ETag、Last-modified配合。而CSS和JS找资源已经被注入到HTML中,资源文件地址通常使用哈希值加入文件名中保证资源是最新,css和js文件可设置:max-age=31536000或last-modified 配合使用。


5. 了解http2.0嘛?为什么说http2.0更好?

http2.0基于二进制分帧层,http2.0可以在共享TCP连接的基础上同时发送请求和响应。在http1.x中,是通过文本的方式传输数据,基于文本的方式传输数据存在很多缺陷,文本的表现形式有多样性,因此要做到健壮性考虑的场景必然有很多,但是二进制则不同,只有0和1的组合,因此选择了二进制传输,实现方便且健壮。

为了保证http不受影响,那就需要在应用层(HTTP2.0)和传输层(TCP or UDP)之间增加一个二进制分帧层。在二进制分帧层上,http2.0会将所有传输的信息分为更小的消息和帧,并采用二进制格式编码,其中http1.x的首部信息会被封装到Headers帧,而Request Body则封装到Data帧。在传输中会共用一个TCP流(TCP连接中的一个虚拟通道,可以承载双向的消息),不至于重复连接。


参考:

书籍:HTTP权威指南

SSL/TLS协议运行机制的概述

前端框架

前端框架目前市面主流就是React和Vue,对于框架的使用和学习,前期建议多翻翻文档,中期根据自己在使用过程中遇到的问题学习,后期就可以考虑翻源码了。由于工作原因,我对react了解更多,所以分享主要就是React。

React和Vue作为前端框架在本质上做的是相同的事,在浏览器和开发操作之间加了一个中间层,来进项目的辅助管理和开发。

React框架

1. JSX本质是什么,它和JS的关系是什么?为什么使用JSX?

JSX是类HTML的语法结构,实质是JS的语法扩张。它语法结构简洁,通俗易懂,对于研发效率和体验有大的提升。


2. JSX背后的功能模块是什么,这个功能模块做了哪些事情?

JSX通过babel语法转换之后,实际就是通过React.createElement函数来创建React元素。createElement接收三个参数type类型,config配置,children子元素。通过createElement就可创建出虚拟DOM对象。


3. react16.3新旧生命周期,消失的旧生命周期有哪些?

去掉ComponentWillMountCompoentWillReceiveProps 升级为getDeicvedStateFromProps,保证生命周期更加单一,更可控;去掉ComponentWillUpdate新增getSnapshotDeforeUpdate;


4. React团队为什么要去掉旧的生命周期函数?

React16+引入Fiber架构,Fiber会将一个大的更新任务拆解为多个小任务,而且它是可中止,可恢复的。React16+生命周期被划分为rendercommit两个阶段。render阶段在执行过程中允许被打断,而commit阶段操作涉及真实DOM渲染,是不可打断的。

ComponentWillMountComponentWillUpdateComponentWillReceiveProps 这些生命周期,它们都处于render阶段,而在Fiber架构中,render阶段会被打断,重复被执行。在这些生命周期可能习惯做的事情可能有:setState、异步请求、操作真实DOM等。而在Fiber异步渲染控制下,这些生命周期可能会导致非常严重的bug(例如在这些废弃的生命周期中调用支付接口)。


5. React组件数据如何流动?实现数据通信的方案有哪些?

react是自上而下的单向组件数据流

1.父-子组件通过prop属性传递数据,子-父组件可通过函数;
2.兄弟组件共享同一个父组件,达到兄弟组件通信;
3.Context API实现全局通信;(目前还没试过)
4.redux数据状态容,进行可预测的状态管理;
5.发布/订阅模式实现任意组件通信;

6. 为什么是React Hooks?

相对于Class组件,函数组件更加轻量,更加符合UI=render(data)特点。同时在Fiber架构的加持下,Hooks的实现不是问题。配合函数组件的发展,Hooks应运而生,从而是函数组件真正把数据和渲染绑定到一起。当然Hooks也还是存在部分不足:部分周期不存在;不能很好的消化“复杂”,组件的拆分和组织是一个大的挑战,不易把握。


7. 为什么Hooks执行顺序如此重要?

Hooks本质是链表。例如 使用useText、useState创建state时,hook创建的state会以单链表形式保存,更新时,函数组件重新调用,hooks会依次遍历单链表,读取数据并更新,这一过程完全按照创建时的顺序来的。因此当更新时,位置一旦改变,执行顺序被替换,运行就会出现bug。


8. 调和(协调)和diff的关系或区别?

调和指的是虚拟DOM映射到真实DOM的过程。调和过程并不能喝diff画等号。调和是“使一致”的过程,而diff是“找不同”的过程,它只是“使一致”过程中的一个环节。(当然常说的调和相关问题多半就是diff过程的)


9. react的diff逻辑和思路?

1.因为时间付扎渡的原因,diff过程只针对同层的节点作比较;
2.对于同类型的组件,才有进一步对比的必要性;
3.对于列表组件,通过key属性来维持节点的稳定性,避免总是生产新节点;

10. setState的工作流是怎么样的?

非并发(concurrent)模式:setState会出现异步和同步的现象。在生命周期和合成事件中是同步,而在setTimeout、setInterval、DOM原生函数等函数中是同步的。那么这是为什么尼?在合成事件或生命周期执行时,批量更新的任务锁就被开启了,我们所做的setState操作会被放入到批量更新队列中,直到函数执行完,批量更新的任务锁才会被关闭。批量更新的任务锁是一个同步操作,而一旦你在setTimeout函数使用setState,此时setTimeout函数回调会被放入下一个宏任务执行,而当setState执行时,批量更新的任务锁时关闭的,它就不会放入到批量更新队列中,而是直接执行。

并发(concurrent)模式:setState不会出现异步和同步的现象。因为存在时间切片,只要当前时间片没有结束,依旧可以将多个 setState 合并成一个,即使是在setTimeout中被调用。而对于超过当前时间片的操作,会通过MessageChannel放入到下一个宏任务中继续执行。(MessageChannel接收消息的时机比 Promise 所在的 microTask 要晚,但是早于 setTimeout)


11. Stack Reconciler栈调和 有怎么样的局限性?

浏览器中Js线程和渲染线程是互斥的。这两个线程不能穿插执行,必须串行。而当Js线程长时间占用主线程,那么渲染线程的更新就不得不长时间的等待,这时就会导致页面卡顿。

Stack Reconciler栈调和是一个同步递归过程,虚拟DOM树diff算法遍历是深度优先遍历。由于它是同步的,不可在被打断。当处理结构复杂,体量庞大的虚拟DOM树时,Stack Reconciler时间会很长,以为这Js主线程长时间占用主线程,进而导致上述中说道的渲染卡顿/页面卡死。


12. 说一说Fiber架构?

特点:可中断、可恢复、存在优先级。

 Scheduler ————> Reconciler ————> Renderer
 更新优先级         找不同         渲染不同

Fiber架构模式下,每个更新任务会被赋予一个优先级。当然有任务A进入调度器,这个任务优先级更高,而Reconciler中已有任务B在执行,那么,Reconciler会将任务B终止,更高优先级的任务A被推入Reconciler。当A任务完成之后,新一轮调度会将之前中断的任务B重新推入Reconciler,继续它的渲染之旅。

render开始 ——————> (工作单元| 工作单元 | 工作单元) ——————> commit提交渲染

13. ReactDOM.render调用栈的初始化阶段、render阶段

初始化阶段:会创建root对象这个对象挂载_internalRoot属性,而_internalRoot也就是FiberRootFiberRoot的本质是一个FiberRootNode对象,其中包含current属性,current对象是一个FiberNode实例。current对象就是一个Fiber节点,并是Fiber树的头部节点;确定Fiber的优先级,结合优先级创建当前Fiber的update对象,并将其入队调度FiberRoot;接下来进入render阶段;(此时相当于只有一个Fiber头部节点)

render阶段:通过createWorkInProgress函数,创建rootFiber节点的副本workInProgress节点树(即current节点的副本节点),他们通过alternate互相引用;接着会触发beginWork函数,进而实现对新的Fiber节点的创建。循环遍历,组件元素Fiber会不断被创建(每个元素节点对应一个Fiber节点),直到创建到最后一个为止,此时Fiber树(单链表)基本完成;重点,此时已经遍历到了单链表的最底部节点,然后会由下自上的依次生成真实DOM节点,同时被它的父组件副作用链,这个副作用链也是一个单链表,直遍历到根节点,此时的根节点上的副作用链就包含的全部的DOM更新。那么剩下的只需要拿到root下的副作用链更新即可了。


参考:

修言 深入浅出搞定 React

React 架构的演变 - 从同步到异步

React 架构的演变 - 从递归到循环

React 架构的演变 - 更新机制

React 架构的演变 - Hooks 的实现

性能优化

可使用Chrome Lighthouse进行性能测评,根据测评结果也可以得出一些改进的点:

react框架层面可以做的优化方向核心点:减少重新 render 的次数减少计算的量,主要是减少重复计算。有下列具体方案:

1. 拆分公共组件和业务组件,根据具体业务分离,降低组件颗粒度;
2. shouldComponentUpdate中拦截非不要渲染;
3. 对于简单的数据类型,可考虑使用React.PureComponent;
4. 函数组件考虑使用React.meno,React.memo 与 React.PureComponent 非常相似;(版本React 16.6.0)
5. React Hooks组件使用useCallback缓存函数,避免每次返回一个新的函数;(版本React v16.8)
6. React Hooks组件使用useMemo缓存计算值;(版本React v16.8)

一个前端项目下通用的优化技巧:使用缓存、节流、压缩、按需加载、全局管理等方法或技巧。如下:

1. 避免频繁渲染更新,即使必须的情况下,也需要考虑是否使用节流函数;
2. 对于长列表页面,考虑翻页加载、点击下一页或者虚拟长列表,避免数据量过大,渲染卡顿;
3. 统一控制项目中的定时器函数,避免定时器偷跑;
4. 拆分Js文件,可考虑按需加载,提升加载速度;
5. 保证首屏必要数据渲染,可增加过渡图片,提升用户体验;
6. 对于后端接口多余数据可考虑清洗数据,只保留必要数据;
7. 避免过多的数据请求,可考虑使用数据缓存,提升用户体验;
8. 对于大图考虑CDN图片加载,也可考虑图片懒加载;
9. 避免使用过多css选择器嵌套;
10. 代码文件gzip压缩等,服务器相关缓存配置;

以上更多的是各种技巧和原则,如果要知道具体的标准,可以参考google为Web性能表现提供的文档developers.google.cn/Web Performance

前端安全

以上内容是以前端面试之道目录结构作为大纲进行的系统的整理,有修改也有添加,其中的内容大部分都是查看博客和相关资料获取的,因为自己也有薄弱的地方,所以有些目录下的内容偏少。如果有有更多补偿可以评论或者单独发我,谢谢✍✍。

ps: 微信公众号:Yopai,有兴趣的可以关注,每周不定期更新。不断分享,不断进步

关注微信公号 更多干货 分享
扫码加V可交流 扫码备注 博客交流 欢迎
上次更新: 11/24/2021, 3:06:31 AM

评 论: