前端面试题总结大全

简介: 前端面试题总结大全

首屏加载速度慢怎么解决?

首屏时间?

首屏时间是指。浏览器从响应用户输入地址,到浏览器渲染完成的时间,此时整个页面不一定要全部渲染完成。但是需要展示当前视窗需要完成的内容。

首屏加载慢的原因?

网络延时问题

资源文件积是否过大

资源是否直接发送请求去更改了

加载脚本的时候,渲染内容堵塞了。

首屏加载速度慢

首屏加载慢的优化方式?

减小入口文件积(懒加载,把不同的路由对应的组件分割为不同的代码)

静态资源本地缓存

ul框架按需加载

图片资源的压缩

大文件如何做断点续传

做断点续传的原因?

不管怎么样的需求,在量级达到一定标准之后,就会变得非常复杂,大文件上传就会变得异常困难。上传时间会过长,高频词上传失败,失败后又重新上传。为了解决上述问题,我们对大文件进行单独处理。

分片上传?

分片上传就是将一个大文件,按照一定的大小,将整个文件分割成多个数据块来进行分片

react事件机制

React基于浏览器的事件机制自身实现了一套事件机制,包括事件注册、事件的合成、事件冒泡、事件派发等,在React中这套事件机制被称之为合成事件。

React的时间机制:

React 上注册的事件最终会绑定在document这个 DOM 上,而不是 React 组件对应的 DOM(减少内存开销就是因为所有的事件都绑定在 document 上,其他节点没有绑定事件)

React 自身实现了一套事件冒泡机制,所以这也就是为什么我们 event.stopPropagation()无效的原因。

React 通过队列的形式,从触发的组件向父组件回溯,然后调用他们 JSX 中定义的 callback

React 有一套自己的合成事件 SyntheticEvent

React组件之间如何通信?

组件是vue中最强大的功能之一,同样组件化是React的核心思想

相比vue,React的组件更加灵活和多样,按照不同的方式可以分成很多类型的组件,而通信指的是发送者通过某种媒体以某种格式来传递信息到收信者以达到某个目的,广义上,任何信息的交通都是通信,组件间通信即指组件通过某种方式来传递信息以达到某个目的.

父组件向子组件传递:

(父组件在调用子组件的时候,只需要在子组件标签内传递参数,子组件通过props属性就能接收父组件传递过来的参数)

子组件向父组件传递

(父组件向子组件传一个函数,然后通过这个函数的回调,拿到子组件传过来的值)

兄弟组件之间的通信

(父组件作为中间层来实现数据的互通,通过使用父组件传递)

父组件向后代组件传递

(使用context提供了组件之间通讯的一种方式,可以共享数据,其他数据都能读取对应的数据)

非关系组件传递

(如果组件之间关系类型比较复杂的情况,建议将数据进行一个全局资源管理,从而实现通信,例如redux。关于redux的使用后续再详细介绍)

说说你对fiber架构的理解?解决了什么问题

JavaScript引擎和页面渲染引擎两个线程是互斥的,当其中一个线程执行时,另一个线程只能挂起等待

如果 JavaScript 线程长时间地占用了主线程,那么渲染层面的更新就不得不长时间地等待,界面长时间不更新,会导致页面响应度变差,用户可能会感觉到卡顿

而这也正是 React 15 的 Stack Reconciler所面临的问题,当 React在渲染组件时,从开始到渲染完成整个过程是一气呵成的,无法中断

如果组件较大,那么js线程会一直执行,然后等到整棵VDOM树计算完成后,才会交给渲染的线程

这就会导致一些用户交互、动画等任务无法立即得到处理,导致卡顿的情况

Fiber: React Fiber 是 Facebook 花费两年余时间对 React 做出的一个重大改变与优化,是对 React 核心算法的一次重新实现。

在react中,主要做了以下的操作:

为每个增加了优先级,优先级高的任务可以中断低优先级的任务。然后再重新,注意是重新执行优先级低的任务

增加了异步任务,调用requestIdleCallback api,浏览器空闲的时候执行

dom diff树变成了链表,一个dom对应两个fiber(一个链表),对应两个队列,这都是为找到被中断的任务,重新执行。

从架构角度来看,Fiber 是对 React核心算法(即调和过程)的重写。

从编码角度来看,Fiber是 React内部所定义的一种数据结构,它是 Fiber树结构的节点单位,也就是 React 16 新架构下的虚拟DOM。

解决过程:

Fiber把渲染更新过程拆分成多个子任务,每次只做一小部分,做完看是否还有剩余时间,如果有继续下一个任务;如果没有,挂起当前任务,将时间控制权交给主线程,等主线程不忙的时候在继续执行。

说说如何借助webpack来优化前端性能?

随着前端的项目逐渐扩大,必然会带来的一个问题就是性能,一般项目在完成后,会通过webpack进行打包,利用webpack对前端项目性能优化是一个十分重要的环节。

通过webpack优化前端的手段有

JS代码压缩

CSS代码压缩

Html文件代码压缩

文件大小压缩

图片压缩

Tree Shaking

代码分离

内联 chunk

JS代码压缩

上传。上传完成之后,再由服务端多所有上传的文件进行汇总整合成原始的文件。

说说Real diff算法是怎么运作的?

跟Vue一致,React通过引入Virtual DOM的概念,极大地避免无效的Dom操作,使我们的页面的构建效率提到了极大的提升.而diff算法就是更高效地通过对比新旧Virtual DOM来找出真正的Dom变化之处。diff作用:渲染真实DOM的开销很大,有时候我们修改了某个数据,直接渲染到真实dom上会引起整个dom树的重绘和重排。我们希望只更新我们修改的那一小块dom,而不是整个dom,diff算法就帮我们实现了这点。

diff算法的本质是找出两个对象之间的差异

diff算法的核心是子节点数组对比,思路是通过首尾两端对比

key的作用主要是

决定节点是否可以复用

建立key-index的索引,主要是替代遍历,提升性能。

react中diff算法主要遵循三个层级的策略:

tree层级

1)React通过updateDepth对Virtual DOM树进行层级控制。

(2)对树分层比较,两棵树只对同一层次节点进行比较。如果该节点不存在时,则该节点及其子节点会被完全删除,不会再进一步比较。

(3)只需遍历一次,就能完成整棵DOM树的比较。

  • DOM节点跨层级的操作不做优化,只会对相同层级的节点进行优化,只有删除、创建操作,没有移动操作进行比较

conponent 层级:

如果是同一个类的组件,则会继续往下diff运算,如果不是一个类的组件,那么直接删除这个组件下的所有子节点,创建新的

element 层级

在element 层级中,每个节点在对应的层级用唯一的key作为标识,当我们比较同一层级的节点的时候,key就起到了关键的作用。通过key可以准确地发现新旧集合中的节点都是相同的节点,因此无需进行对节点删除和创建,只需要将旧集合中节点的位置进行移动,更新为新集合中节点的位置。

刚刚提到了对节点进行删除、创建和移动,这是element提供的三种操作。

基于Diff的开发建议

基于tree diff:

开发组件时,尽可能少地动态操作DOM结构,尤其是移动操作。

当节点数过大或者页面更新次数过多时,页面卡顿的现象会比较明显。

这时可以通过 CSS 隐藏或显示节点,而不是真的移除或添加 DOM 节点。

基于component diff:

注意使用 shouldComponentUpdate() 来减少组件不必要的更新。

对于类似的结构应该尽量封装成组件,既减少代码量,又能减少component diff的性能消耗。

基于element diff:

当操作列表的时候,尽量减少这种大操作,比如将最后一个节点移动到列表首部的操作,当节点数量过大或更新操作过于频繁时,在一定程度上会影响 React 的渲染性能。

说说react 中jsx语法糖的本质?

eact通过babel把JSX转成createElement函数,生成ReactElement对象,然后通过ReactDOM.render函数把ReactElement渲染成真实的DOM元素。

Jsx通过babel最终转化成react.createElement这种形式,在转化的过程中,babel在编译时候,会判断jsx中组件的首字母,情况分为以下几种:

当首字母小写的时候,其备认定为原生的dom 标签,createElement的第一个变量被编译为字符串

当首字母为大写的时候,其被认定为自定义组件,createElement的第一个变量被编译为对象。

这些都会通过renderDom.render()方法进行挂载。

在react中,节点大致可以分成四个类别:

原生标签节点,

文本节点

函数组件

类组件。

这些类别最终都会被转化成React.createElement这种形式,createElement会根据传入的节点信息进行一个判断:

如果是原生标签节点, type 是字符串,如div、span

如果是文本节点, type就没有,这里是 TEXT

如果是函数组件,type 是函数名

如果是类组件,type 是类名

虚拟DOM会通过ReactDOM.render进行渲染成真实DOM,当首次调用时,容器节点里的所有 DOM 元素都会被替换,后续的调用则会使用 React 的 diff算法进行高效的更新

如果提供了可选的回调函数callback,该回调将在组件被渲染或更新之后被执行Render

执行流程

使用React.createElement或JSX编写React组件,实际上所有的 JSX 代码最后都会转换成React.createElement(…) ,Babel帮助我们完成了这个转换的过程。

createElement函数对key和ref等特殊的props进行处理,并获取defaultProps对默认props进行赋值,并且对传入的孩子节点进行处理,最终构造成一个虚拟DOM对象.

ReactDOM.render将生成好的虚拟DOM渲染到指定容器上,其中采用了批处理、事务等机制并且对特定浏览器进行了性能优化,最终转换为真实DOM

**

说说AMD、CMD、commonJS模块化规范的区别?

**

这三个规范都是为Js模块化加载而生的,使模块能够按需加载,使系统同庞杂的代码得到组织和管理。模块化的管理代码使多人开发得到了更好的合作

**CommonJS:**nodejs中的模块化机制,模块通过require()引入,exports或modules.exports导出

规范的特点

当使用require命令加载某个模块时,就会运行整个模块的代码。

对于基本数据类型,属于复制。即会被模块缓存。同时,在另一个模块可以对该模块输出的变量重新赋值。

对于复杂数据类型,属于浅拷贝。由于两个模块引用的对象指向同一个内存空间,因此对该模块的值做修改时会影响另一个模块

循环加载时,属于加载时执行

执行流程:

根据CommonJS规范,一个单独的文件就是一个模块。每一个模块都是一个单独的作用域,也就是说,在该模块内部定义的变量,无法被其他模块读取,除非定义为global对象的属性2、模块输出:模块只有一个出口,module.exports对象,我们需要把模块希望输出的内容放入该对象3、加载模块:加载模块使用require方法,该方法读取一个文件并执行,返回文件内部的module.exports对象

第二个AMD:上面的commonjs主要适用于node.js这种后端模块化,其中的require引用是同步的,前端环境中有很多异步的情况,因此commonjs是不够用的,AMD就出现了。

多个js文件可能有依赖关系,被依赖的文件需要早于依赖它的文件加载到浏览器

2、js加载的时候浏览器会停止页面渲染,加载文件越多,页面失去响应时间越长

CMD规范是阿里的玉伯提出来的,实现js库为sea.js。和requirejs非常相似,也是前端异步加载模块化。不同的是它的模块是需要的时候去请求,而不是先加载再使用。RequireJS用的就是AMD,AMD用define定义方法,用require引用模块。

AMD与CMD区别:

最明显的区别就是在模块定义时对依赖的处理不同

1、AMD推崇依赖前置,在定义模块的时候就要声明其依赖的模块

2、CMD推崇就近依赖,只有在用到某个模块的时候再去require

说说你对webSocket的理解?

WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。

WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。

为什么需要WebSocket

1、传统上的HTTP协议它是无状态的,服务器不能够识别是哪个客户端发送的请求,不能够保存状态。

2、WebSocket弥补了这一问题,在客户端向服务端发送请求之后,服务器处理请求并返回到客户端,使用WebSocket可以使得服务器主动向浏览器推送消息

WebSocket与HTTP的区别

1、HTTP是客户端直接向服务端发送请求,WebSocket是在完成一次握手之后建立连接

2、发送HTTP请求的时候,服务器不能记住是谁发给他的

3、发送WebSocket请求,服务器可以记住是谁发给他的

websoket协议流程

服务器可以主动向客户端推送消息,客户端也可以主动向服务器发送消息。是真正的双向平等对话,属于服务器推送技术的一种。websocket协议的协议标识符是ws(如果加密,则为wss),服务器网址就是URL。

WebSocket的优缺点

优点:建立WebSocket连接之后,客户端与服务端交流更方便

客户端只需要向服务端发送一次请求,服务端主动向客户端发送消息

缺点:在服务端的状态不会频繁变化的时候,就不需要使用WebSocket连接了,浪费性能。

说说你对React中虚拟dom的理解?

通俗点理解,虚拟DOM是一棵虚拟的JavaScript对象树,虚拟DOM的实现原理

React虚拟DOM的实现原理,通过JS模拟网页文档节点,生成JS对象树(虚拟DOM),然后再进一步生成真实的DOM树,再绘制到屏幕。如果后面有内容发生改变,React会重新生成一棵全新的虚拟DOM树,再与前面的虚拟DOM树进行比对diff,把差异的部分打包成patch,再应用到真实DOM,然后渲染到屏幕浏览器。

React虚拟DOM与Jquery操作真正DOM,性能优在哪?

在学习的过程中,一直有个疑问,虚拟DOM的这种技术真的比Jquery性能会优吗?React发生更改还总是生成新的虚拟DOM树,最终也是需要去更新真实的DOM的呀,为什么呢?

1、虚拟DOM的节点元素相对比较简单,真实DOM的节点要复杂得多。

2、虚拟DOM的操作和真实DOM的操作是两个引擎,相互独立。

3、虚拟DOM在内存中操作,其实速度是非常快的,所以他们的瓶颈在于JS引擎与真实DOM引擎通信和DOM引擎的绘制上。

4、虚拟DOM通过diff算法,计算更改的部分,从而降低了真实DOM的操作节点。

5、增加缓冲区,等全部计算好后,再将缓冲区的数据一次性复制到显示缓冲区,这样的图形输出也比较稳定。Jquery以及传统的做法,频繁的调用DOM API,操作真实的DOM,引起页面的重绘,开销会变得非常昂贵。

但是,如果我们改动的部分很小,与真实DOM引擎的通信内容和次数一样,相反,虚拟DOM更像是个累赘,多余的。不过,React这种前端技术,要解决的问题,不仅仅如此,是从整体和综合性思考的,对于复杂的系统,让开发者更关注数据和视图的变化,把复杂的真实DOM操作包装掩盖起来,是一种前端开发模式的革命。

真实dom和虚拟dom的区别?

Real DOM,真实 DOM,意思为文档对象模型,是一个结构化文本的抽象,在页面渲染出的每一个结点都是一个真实 DOM 结构。

Virtual Dom,本质上是以 JavaScript 对象形式存在的对 DOM 的描述

创建虚拟 DOM 目的就是为了更好将虚拟的节点渲染到页面视图中,虚拟 DOM 对象的节点与真实 DOM 的属性一一照应。

JSX 通过 babel 的方式转化成 React.createElement 执行,返回值是一个对象,也就是虚拟 DOM。

区别

两者的区别如下:

虚拟 DOM 不会进行排版与重绘操作,而真实 DOM 会频繁重排与重绘

虚拟 DOM 的总损耗是“虚拟 DOM 增删改+真实 DOM 差异增删改+排版与重绘”,真实 DOM 的总损耗是“真实 DOM 完全增删改+排版与重绘

例子:

传统的原生 api 或 jQuery 去操作 DOM 时,浏览器会从构建 DOM 树开始从头到尾执行一遍流程

当你在一次操作时,需要更新 10 个 DOM 节点,浏览器没这么智能,收到第一个更新 DOM 请求后,并不知道后续还有 9 次更新操作,因此会马上执行流程,最终执行 10 次流程

而通过 VNode,同样更新 10 个 DOM 节点,虚拟 DOM 不会立即操作 DOM,而是将这 10 次更新的 diff 内容保存到本地的一个 js 对象中,最终将这个 js 对象一次性 attach 到 DOM 树上,避免大量的无谓计算

三、优缺点

真实 DOM 的优势

易用

缺点

效率低,解析速度慢,内存占用量过高

性能差:频繁操作真实 DOM,易于导致重绘与回流

使用虚拟 DOM 的优势如下

简单方便:如果使用手动操作真实 DOM 来完成页面,繁琐又容易出错,在大规模应用下维护起来也很困难

性能方面:使用 Virtual DOM,能够有效避免真实 DOM 数频繁更新,减少多次引起重绘与回流,提高性能

跨平台:React 借助虚拟 DOM,带来了跨平台的能力,一套代码多端运行

缺点:

在一些性能要求极高的应用中虚拟 DOM 无法进行针对性的极致优化

首次渲染大量 DOM 时,由于多了一层虚拟 DOM 的计算,速度比正常稍慢


相关文章
|
3天前
|
存储 缓存 前端开发
100道 IT名企前端面试真题,Web前端阿里等大厂面试题汇总
100道 IT名企前端面试真题,Web前端阿里等大厂面试题汇总
|
3天前
|
移动开发 前端开发 JavaScript
【前端面试】前端面试题300道~~熬夜吐血整理,2024年最新大厂面试经验分享稿
【前端面试】前端面试题300道~~熬夜吐血整理,2024年最新大厂面试经验分享稿
|
3天前
|
前端开发 JavaScript 中间件
Vue3整合VxeTable,2024大厂前端面试
Vue3整合VxeTable,2024大厂前端面试
|
3天前
|
前端开发 JavaScript
JavaScript新科技:PostCSS的安装和使用,2024年最新2024网易Web前端高级面试题总结
JavaScript新科技:PostCSS的安装和使用,2024年最新2024网易Web前端高级面试题总结
|
3天前
|
移动开发 前端开发 JavaScript
10款精美的web前端源码的特效,2024年最新面试题+笔记+项目实战
10款精美的web前端源码的特效,2024年最新面试题+笔记+项目实战
|
3天前
|
移动开发 前端开发 JavaScript
10款精美的web前端源码的特效(1),头条前端面试节奏
10款精美的web前端源码的特效(1),头条前端面试节奏
|
3天前
|
JavaScript 前端开发 算法
JQuery 基本使用,2024BAT大厂Web前端社招面试题
JQuery 基本使用,2024BAT大厂Web前端社招面试题
JQuery 基本使用,2024BAT大厂Web前端社招面试题
|
3天前
|
移动开发 前端开发 JavaScript
Java和web前端,IT新人该如何选择?,2024年最新Web前端内存优化面试
Java和web前端,IT新人该如何选择?,2024年最新Web前端内存优化面试
|
3天前
|
前端开发 JavaScript
JavaScript:this-关键字,2024中级前端开发面试解答
JavaScript:this-关键字,2024中级前端开发面试解答
|
3天前
|
前端开发 JavaScript
Web前端开发之面试题全解析 一,2024年最新面经牛客
Web前端开发之面试题全解析 一,2024年最新面经牛客