1、SPA(单页应用)首屏加载速度慢怎么解决?
首屏加载慢的原因?
在页面渲染的过程中,导致加载速度慢的原因可能如下:
网络延迟问题
资源文件体积是否过大
资源是否重复发送请求去加载了
加载脚本的时候,渲染内容堵塞了
如何解决?
常见的集中SPA首屏优化方法
减少入口文件体积
静态资源本地缓存
UI框架按需加载
图片资源的压缩
组件重复打包
开启GZip压缩
使用SSR
2、Vue中自定义指令的理解,应用场景有哪些?
理解
在vue中提供了一套为数据驱动视图更为方便的操作,这些操作被称之为指令系统,我们看到的v-开头的行内属性,都是指令,不同的指令可以完成不同的或实现不同的功能。
应用场景
表单防止重复提交
图片懒加载
一键Copy的功能
3、说说React生命周期中有哪些坑?如何避免?
一些常见的一些坑
getDerviedStateFromProps容易编写反模式代码,使受控组件和非受控组件容易混乱
网络请求应该放在componentDidMount生命周期钩子函数中
ComponentWillReceivedProps被getDerviedStateFromProps所取代,主要因为性能问题
ShouldcomponentUpdate通过返回true或false来确定是否要渲染更新
如何在componentWIllUnMount函数中忘记解除事件绑定,取消定时器等清理操作,容易引发bug
如何避免
不在恰当的时候调用不该调用的代码
在该调用的时候不要忘记调用
4、说说Real diff算法是怎么运作的?
diff算法可以看作是一种对比算法,对比的对象是虚拟dom,可以对比出新旧虚拟dom的差异。但diff算法不仅可以对比新旧虚拟dom差异,还可以根据对比的结果去更新真实的dom。
合理的利用key可以有效地减少真实dom的变动,从而减少负面重绘和回流的频率,进而提高页面更新的效率
5、调和阶段setState做了什么?
在组件中调用了this.setState这个函数之后,react会将传入的参数与当前组件的状态进行合并,然后触发所谓的调和过程。
经过调和之后,react会以高效地方式根据新的状态构建一个react元素数,并且着手渲染整个UI页面。
react得到元素树后,react会进行diff算法进行对比,对比出新树与旧树的差异,然后根据差异对界面进行最小化的更新渲染。
在差异计算算法中,react能够相对准确地知道那些位置放生了改变以及应该如何改变,这就保证了按需更新,而不是全部更新
6、为什么React元素有一个$$type属性?
防止一些xxs攻击 详见:https://blog.csdn.net/zz130428/article/details/128238574
7、说说Connect组件的原理是什么?
这个函数允许我们将 store 中的数据作为 props 绑定到组件上
connect 的第二个参数是 mapDispatchToProps
由于更改数据必须要触发action, 因此在这里的主要功能是将 action 作为props 绑定到 组件上
Provider就是react-redux中的一个组件, Provider 做的事情也简单, 它就是一个容器组件, 会把嵌套的内容原封不动作为自己的子组件渲染出来. 它还会把外界传给它的 props.store 放到 context, 这样子组件 connect 的时候都可以获取到.
8、说说你对fiber架构的理解?解决了什么问题?
什么是fiber架构?
是react16以后的一个虚拟dom思想
为每个增加了优先级,优先级高的任务可以中断优先级低的任务。然后重新,注意是重新执行优先级低的任务
增加了异步任务
dom diff树变成了链表,一个dom对应两个fiber,对应两个队列,这都是为找到被中断的任务,重新执行
解决问题
Fiber把渲染更新过程拆分成多个子任务,每次只做一小部分,做完看是否还有剩余时间,如果有继续下一个任务;如果没有,挂起当前任务,将时间控制权交给主线程,等主线程不忙的时候在继续执行
9、说说你对事件循环event loop的理解?
JavaScript是一门单线程的语言,也就是说同一时间只能去做一件事情,为了解决单线程的阻塞问题,JavaScript用到了一种计算机的运行机制,这种运行机制就叫做事件循环
在JavaScript中所有的任务都可以分为:
同步任务:立即执行的任务,同步任务一般会直接进入到主线程中进行执行
异步任务:同步任务执行完之后才会执行异步任务;比如ajax请求,setTimeout定时函数
10、前端跨域的解决方案?
JSONP
nginx代理
WebSocket协议跨域
CORS
11、说说你对vue中mixin的理解?
mixin提供了一种非常灵活的方式,来分发vue中可复用的功能
其本质就是一个js对象,它可以包含我们组件中任意功能选项,如data、componets、methods等
我们只要将公用的功能以对象的方式传入到minxins选项中,当组件使用minxins对象时所有mixins对象的选项都被混入到该组件本身的选项中
12、for...in循环和for...of循环的区别?
for...in和for...of都是JavaScript中遍历数据的方法
for...in是为遍历对象属性而构建的,它以任意顺序遍历一个对象的除Symbol以外的可枚举属性,可用break或者throw跳出
for...of语句在可迭代对象上创建一个迭代循环,调用自定义迭代钩子,并为每个不同属性的值执行语句(包括Array,Map,Set,String,TypedArray,arguments等等,不包括Object),可用break或者throw跳出。
13、说说你对Object.defineProperty()的理解?
Object.defineProperty() 方法会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性,并返回此对象。
该方法接受三个参数,第一个参数是 obj:要定义属性的对象,第二个参数是 prop:要定义或修改的属性的名称或 Symbol,第三个参数是 descriptor:要定义或修改的属性描述符
14、说说你对webSocket的理解?
是一种网络传输协议,位于OSI模型的应用层。可在单个TCP连接上进行全双工通信,能更好的节省服务器资源和带宽并达到实时通迅
客户端和服务器只需要完成一次握手,两者之间就可以创建持久性的连接,并进行双向数据传输
15、最少说出三种前端清除浮动的方法?
使用带clear属性的空元素
使用css的overflow属性
使用css的::after属性
16、说说你对git rebase 和git merge的理解?区别?
git rebase 和 git merge 都是将一个分支的提交合并到另一分支上
通过 merge 合并分支会新增一个 merge commit 然后将两个分支的历史联系起来
rebase 会将整个分支移动到另一个分支上,主要的好处是历史记录更加清晰,不好的是会丢失一些分支从何时创建及合并进来的一些信息。
区别:
merge
通过merge合并分支会新增一个merge commit,然后将两个分支的历史联系起来
其实是一种非破坏性的操作,对现有分支不会以任何方式被更改,但是会导致历史记录相对复杂
rebase
rebase会将整个分支移动到另一个分支上,有效地整合了所有分支上的提交
主要的好处是历史记录更加清晰,是在原有提交的基础上将差异内容反映进去,消除了 git merge所需的不必要的合并提交
17、说说你对栈、队列的理解?应用场景?
栈:又名堆栈,它是一种运算受限的线性表,限定仅在表尾进行插入和删除操作的线性表,
队列:跟栈十分相似,队列是一种特殊的线性表,特殊之处在于它只允许在表的前端(front)进行删除操作,而在表的后端(rear)进行插入操作
应用场景
栈:借助栈的先进后出的特性,可以简单实现一个逆序数处的功能,首先把所有元素依次入栈,然后把所有元素出栈并输出
栈的特点就是跟坐电梯一样,先进的后出,后进的先出
队列:当我们需要按照一定的顺序来处理数据,而该数据的数据量在不断地变化的时候,则需要队列来帮助解题队列的使用广泛应用在广度优先搜索种
队列的特点就是跟排队一样
18、前端性能优化的手段有哪些?
前端性能优化分为两类:
1.文件加载更快:
① 让传输的数据包更小(压缩文件/图片):图片压缩和文件压缩
②减少网络请求的次数:雪碧图/精灵图、节流防抖
③减少渲染的次数:缓存(HTTP缓存、本地缓存、Vue的keep-alive缓存等)
2.文件渲染更快:
①提前渲染:ssr服务器端渲染
②避免渲染阻塞:CSS放在HTML的head中 JS放在HTML的body底部
③ 避免无用渲染:懒加载
④ 减少渲染次数:对dom查询进行缓存、将dom操作合并、使用减少重排的标签