前端面试题(九)

目录

1.事件扩展符应用场景

2.重绘、重排区别、如何避免?

3.Vue 列表为什么加 key?

4.vue-router 实现懒加载的方法

5.前端性能优化手段

6.vue钩子函数


1.事件扩展符用过吗(...),什么场景下?

展开语法(Spread syntax),可以在函数调用/数组构造时, 将数组表达式或者string在语法层面展开;还可以在构造字面量对象时, 将对象表达式按key-value的方式展开。常见的场景:等价于apply的方式、将数组展开为构造函数的参数、字面量数组或字符串连接不需要使用concat等方法了、构造字面量对象时,进行浅克隆或者属性拷贝。

2.说一下重绘、重排区别如何避免?

重排:当DOM的变化影响了元素的几何信息(元素的的位置和尺寸大小),浏览器需要重新计算元素的几何属性,将其安放在界面中的正确位置,这个过程叫做重排。重绘:当一个元素的外观发生改变,但没有改变布局,重新把元素外观绘制出来的过程。所以重绘跳过了创建布局树和分层的阶段。重排需要重新计算布局树,重绘不需要,重排必定发生重绘,但是涉及到重绘不一定要重排。涉及到重排对性能的消耗更多一些。触发重排的方法:1.页面初始渲染,这是开销最大的一次重排。2.添加/删除可见的DOM元素。3.改变元素位置。4.改变元素尺寸,比如边距、填充、边框、宽度和高度等。5.改变元素内容,比如文字数量,图片大小等。6.改变元素字体大小。7.改变浏览器窗口尺寸,比如resize事件发生时。8.激活CSS伪类(例如:`:hover`)。9.设置 style 属性的值,因为通过设置style属性改变结点样式的话,每一次设置都会触发一次reflow。10.查询某些属性或调用某些计算方法:offsetWidth、offsetHeight等。避免重排的方式:1.样式集中改变。2.使用absolute或fixed脱离文档流。3.使用GPU加速:transform。

GPU的过程是以下这几步:1.获取DOM并将其分割成多个层(renderLayer)。2.将每个层栅格化,并独立的绘制进位图中。3.将这些位图作为纹理上传至GPU。4.复合多个层来生成最终的屏幕图像(最后的layer),开启了GPU加速的元素被独立出来,不会再影响其他dom的布局,因为它改变之后,只是相当于被贴上了页面。

3.说一说 Vue 列表为什么加 key?

为了性能优化。因为vue是虚拟DOM,更新DOM时用diff算法对节点进行一一比对,比如有很多li元素,要在某个位置插入一个li元素,但没有给li上加key,那么在进行运算的时候,就会将所有li元素重新渲染一遍,但是如果有key,那么它就会按照key一一比对li元素,只需要创建新的li元素,插入即可,不需要对其他元素进行修改和重新渲染。key也不能是li元素的index,因为假设我们给数组前插入一个新元素,它的下标是0,那么和原来的第一个元素重复了,整个数组的key都发生了改变,这样就跟没有key的情况一样了。

4.说一说vue-router 实现懒加载的方法?

懒加载的核心思想是按需加载,也叫做异步加载:只有请求到该组件的时候,才会对该组件进行网络请求并加载。懒加载有利于解决页面首次请求资源过多,导致白屏时间长的问题。vue-router实现懒加载的方法有两种:

ES6的impot方式:

component: () => import(/* webpackChunkName: "about" */ '../views/About.vue')

VUE中的异步组件进行懒加载方式:

component: resolve=>(require(['../views/About'],resolve))

vue-router实现懒加载的作用:性能优化,不用到该路由,不加载该组件。

5.说一说前端性能优化手段?

前端性能优化分为两类,一类是文件加载更快,另一类是文件渲染更快。

加载更快的方法:

让传输的数据包更小(压缩文件/图片):图片压缩和文件压缩。

减少网络请求的次数:雪碧图/精灵图、节流防抖。

减少渲染的次数:缓存(HTTP缓存、本地缓存、Vue的keep-alive缓存等)。

渲染更快的方法:

提前渲染:ssr服务器端渲染。

避免渲染阻塞:CSS放在HTML的head中、JS放在HTML的body底部。

避免无用渲染:懒加载。

减少渲染次数:对dom查询进行缓存、将dom操作合并、使用减少重排的标签。

雪碧图的应用场景一般是项目中不常更换的一些固定图标组合在一起,比如logo、搜索图标、切换图标等。电商项目中最常用到的懒加载,一般在查看商品展示的时候通常下拉加载更多,因为商品数据太多,一次性请求过来数据太大且渲染的时间太长。

6.说一说vue钩子函数?

钩子函数用来描述一个组件从引入到退出的全过程中的某个过程,整个过程称为生命周期。钩子函数按照组件生命周期的过程分为:挂载阶段=>更新阶段=>销毁阶段。每个阶段对应的钩子函数:

挂载阶段:beforeCreate、created、beforeMounted、mounted

更新阶段:beforeUpdate、updated

销毁阶段:beforeDestroy、destroyed

每个阶段特点与适合做什么:

created:实例创建完成,可访问data、computed、watch、methods上的方法和数据,未挂载到DOM,不能访问到el属性,el属性,ref属性内容为空数组常用于简单的ajax请求,页面的初始化

beforeMount:在挂载开始之前被调用,beforeMount之前,会找到对应的template,并编译成render函数

mounted:实例挂载到DOM上,此时可以通过DOM API获取到DOM节点,$ref属性可以访问常用于获取VNode信息和操作,ajax请求

beforeUpdate:响应式数据更新时调用,发生在虚拟DOM打补丁之前,适合在更新之前访问现有的DOM,比如手动移除已添加的事件监听器

updated:虚拟 DOM 重新渲染和打补丁之后调用,组件DOM已经更新,可执行依赖于DOM的操作避免在这个钩子函数中操作数据,可能陷入死循环

beforeDestroy:实例销毁之前调用。这一步,实例仍然完全可用,this仍能获取到实例,常用于销毁定时器、解绑全局事件、销毁插件对象等操作

父子组件钩子函数在三个阶段的代码执行顺序:

挂载:父亲created>子created>子mounted>父亲mounted

更新:父亲beforeUpdate>子beforeUpdated>子updated>父亲updated

销毁:父亲beforeDestroy>子beforeDestroy>子destroyed>父destroyed

(来源:牛客网)

你可能感兴趣的:(前端,javascript,面试)