说说Real DOM和Virtual DOM的区别?优缺点?
说说React生命周期有哪些不同的阶段?每个阶段对应的方法是?
说说你对redux中间件的理解?常用的中间件有哪些?实现原理?
说说你对@reduxjs/toolkit的理解?和react-redux有什么区别?
如何通过原生js实现一个节流函数和防抖函数,写出核心代码,不是简单的思路?
说说你对react的理解?有哪些特性?
React是构建用户界面的JavaScript库,只提供了UI层面的解决方案,遵循组件设计模式、声明式编程范式和函数式编程概念,使得前端应用程序更加高效
使用虚拟DOM来有效地操作DOM,遵循从高阶组件到低阶组件的单向数据流,帮助我们将界面成了各个独立的小块,每一个块就是组件,这些组件之间可以组合、嵌套,构成整体页面
特性:jsx语法,单向数据绑定,虚拟dom,声明式编程,component
说说Real DOM和Virtual DOM的区别?优缺点?
虚拟dom不会进行排版与重绘,真实dom会频繁的进行重绘与排版
虚拟dom优点:简单方便,跨平台,性能比较方便
缺点:在一些性能极高的一些应用中虚拟dom没办法针对性的极致优化,第一次渲染dom的时候,速度比正常来说稍微慢了一些
真实dom优点:容易使用
缺点:效率比较低,解析速度慢,内存占用量高,性能差
说说React生命周期有哪些不同的阶段?每个阶段对应的方法是?
挂载阶段,更新阶段和销毁阶段
挂载阶段:constructor():组件挂载前调用
ComponentWillMount():调用render之前调用
ComponentDidMount():组件挂载后调用
更新阶段:
ComponentWillReceiveProps():接收父组件传递的值
ShouldComponentUpdate():组件渲染生命周期
Render():class组件中必须实现是方法
ComponentWillUpdate():组件重新渲染之前进入
销毁阶段:ComponentWillUnmount():销毁组件
说说React中setState执行机制?
一个组件显示形态可以由数据状态和外部参数所决定,数据状态就是state,需要修改里面的值的状态,需要通过setState来改变,从而达到更新内部数据的作用
说说react的事件机制?
React上注册的事件最后会绑定到document上面
React自身实现了一些事件冒泡机制,这就是我们使用event.stoppropagation无效的原因
React有一套自己的合成事件
React组件之间如何通信?
父组件向子组件通讯:父组件向子组件传入props的方式,向子组件进行通讯
子组件向父组件通讯:props+回调的方式,父组件向子组件传递props进行通讯,此props为作用域为父组件自身的函数,子组件调用该函数,将子组件想要传递的信息,作为参数,传递到父组件的作用域中
兄弟组件通讯:兄弟组件之间的传递,则父组件作为中间层来实现数据的互通,通过使用父组件传递 例:组件A--传值-->父组件-传值-->组件B
跨层级通讯:context设计的目的是为了共享哪些对于 一个组件树是全局的数据
使用context提供了组件之间通讯的一种方式,可以共享数据,其他数据都能读取对应的数据
发布订阅者模式:订阅者监听事件并作出反应,可以通过引入event模块进行通信
全局状态管理工具:借助redux或者mobx等全局状态管理工具进行通信,这种工具会维护一个全局状态中心store,根据不同的事件产生新的状态
说说你对受控组件和非受控组件的理解?应用场景?
受控组件:简单来讲,就是受我们控制的组件,组件的状态全程响应外部数据
非受控组件,简单来讲,就是不受我们控制的组件,一般情况是在初始化的时候接收外部数据,然后自己在内部存储其自身状态 大部分时候推荐使用受控组件来实现表单,因为在受控组件中,表单数据由react组件负责处理,如果选择非受控组件的话,控制能力较弱,表单数据就由dom本身处理,但更加方便快捷,代码量少
说说你对fiber架构的理解?解决了什么问题?
fiber架构适用于实现增量渲染和提高react应用的性能。他解决了在react中存在的一些问题,包括长时间占用主线程,无法中断渲染和难以实现优先级控制等。
Fiber架构的主要思想是将渲染过程分解为多个可中断的任务单元,使用优先级调度算法来控制任务执行顺序。可以让react在主线程上进行灵活的任务切换,避免长时间阻塞,提高应用的响应性能和用户体验
说说react diff的原理是什么?
Diff算法是比较Virtual dom树的变化,只对真正发生变化的部分进行更新,提高渲染性能和效率。
原理:对于两棵树的根节点;对比两棵树的根节点(组件的根节点),不同类型,会销毁旧树创建新树,相同类型的组件,会继续对比他们的子节点
对比子节点:逐个对比旧树的子节点,进行列表对比,属性对比,对比子节点
列表遍历:对比子节点的过程中,react尽可能复用已存在的节点,而不是销毁和创建新节点,减少不必要的操作
说说你对redux中间件的理解?常用的中间件有哪些?实现原理?
Redux中间件是用于在redux数据流中进行扩展和处理的功能。获取redux的action和state,对其进行处理,转换或执行额外的操作,然后将结果传递给下一个中间件或redux的reducer
常见中间件:
React thunk:允许action创建函数返回一个函数而不是一个普通的action对象
Redux Saga:使用生成器函数来处理异步操作
Redux logger:用于在开发中记录redux的action和state的变化,方便调试和监控
Redux promise:允许action创建函数返回一个promise对象,支持异步操作
实现原理:中间件的实现原理基于redux的dispatch机制,在react中,当一个action被dispatch时,会依次经过中间件链中的每个中间件进行处理。每个中间件都一一个对action进行拦截,修改,延迟处理等操作,并将处理结果传递给下一个中间件,知道最后一个中间件将结果传递给redux的reducer进行状态更新
如何使用css实现一个三角形,写出两种以上方案得满分?
使用border属性:设置width和height为0,border-left和border-right为相同长度,border-bottom为需要高度
使用伪元素
什么是强缓存和协商缓存?
强缓存:通过在响应头中设置Expires或Cache-Control字段来实现。当浏览器发送请求,会检查缓存中的原数据,满足强缓存条件,直接从缓存中获取响应,不发送请求到服务器
协商缓存:通过子请求头设置if-Modified-Since和if-None-Match字段
服务器根据这些字段判断客户端缓存的数据是否依然有效。如果服务器判断资源未发生变化,返回304状态码,告诉客户端可以继续使用缓存的数据
说说React jsx转换成真实DOM的过程?
当jsx被渲染时,会通过react的渲染过程将其转化为真实dom元素
过程:
Jsx解析:react使用解析器来解析jsx代码,转为js对象
创建react元素:解析jsx后,react创建虚拟react元素
Diff算法:使用虚拟dom diff算法,将新的虚拟dom与之前渲染的虚拟dom比较,找出差异并计算最小的dom更新操作
更新dom:根据diff算法结果,进行dom更新操作,应用到真实dom上
渲染完成
说说你对@reduxjs/toolkit的理解?和react-redux有什么区别?
@reduxjs/toolkit是官方提供的redux工具包,简化redux的使用和减少样板代码
功能:状态管理简化,异步流程简化,不可变性处理DevTools继承
React-redux是用于在react应用中集成redux的库,提供了用于来连接redux store和react组件的api包括以下性能:provider组件,可以将store注入到react应用中的组件层级中,使组件树的所有组件都访问到redux的状态和操作hooks支持
React render方法的原理,在什么时候会触发?
原理:
Render函数中的jsx语法可以让我们使用最熟悉的js代码,在render过程中react将调用render函数返回的值和旧版本的进行比较,这一步决定如何更新dom的必要臂肘,然后进行diff比较,更新dom树
在类组件中调用setState方法的时候会触发render方法
在函数组件中调用useState方法的时候会触发render方法
React性能优化的手段有哪些?
虚拟dom:使用虚拟dom作为中间层,前后比较两个dom之间的差异,对差异部分进行更新,而不是操作真实的dom。可以减少dom操作的次数,提高性能
列表和键:在渲染列表时,为每个列表项提供唯一的键。这样react更好的识别和跟踪列表项的变化,减少重新渲染的开销
组件生命周期优化:合理使用组件的生命周期方法,避免不必要的渲染和副作用
使用react的代码拆分特性:通过将应用程序拆分成更小的代码块,可以实现按需加载,减少初始加载时的资源负担,提高首次加载速度
使用react的懒加载特性:将组件按需加载,只在需要时才加载
使用react的memo组件:使用react.memo来包裹无需重新加载渲染的纯函数,避免不必要的组件重新渲染
使用react的性能分析工具
避免不必要的渲染:在组件的render方法中,避免在每次渲染时创建新的对象或函数,减少垃圾回收压力
通过shouldComponentUpdate:对比state和props,确认是否重新渲染,默认返回true,不希望渲染返回false
PureComponent:通过对比state和props键比较结果来实现
避免使用内联函数
使用React.Fragments避免标记
使用Immutable:减少渲染次数
事件绑定方式
服务器渲染
如何通过原生js实现一个节流函数和防抖函数,写出核心代码,不是简单的思路?
节流函数可以限制某个函数在指定时间间隔内只执行依次,使用throttled
防抖函数在指定时间内,只执行最后一次触发的函数使用debouned
节流函数:
function throttle(func, wait) {
let timeout;
return function () {
if (!timeout) {
timeout = setTimeout(() => {
func.apply(this, arguments);
timeout = null;
}, wait);
}
};
}
防抖函数:
function debounce(func, delay) {
let timer;
return function () {
clearTimeout(timer);
timer = setTimeout(() => {
func.apply(this, arguments);
}, delay);
};
}
说说webpack中代码分割如何实现?
手动配置:手动配置webpack的入口点和输出配置,将不同模块或文件拆分成独立块
动态导入
预加载:使用预加载,告诉浏览器在空闲时间预先加载的资源块
说说如何借助webpack来优化前端性能?
代码压缩:使用webpack的压缩插件,提高加载速度
按需加载 :使用动态导入语法,将应用拆分多个块,按需加载
代码拆分
资源优化
缓存优化
懒加载
优化构建速度
说说javascript内存泄漏的几种情况?
闭包引起的内存泄露
意外的全局变量
被遗忘的定时器
没有清理dom元素引用