文章目录
1. SPA(单页应用)首屏加载速度慢怎么解决?
1、什么是首屏加载
首屏时间(First Contentful Paint),指的是浏览器从响应用户输入网址地址,到首屏内容渲染完成的时间,此时整个网页不一定要全部渲染完成,但需要展示当前视窗需要的内容
首屏加载可以说是用户体验中最重要的环节
2、加载慢的原因
在页面渲染的过程,导致加载速度慢的因素可能如下:
网络延时问题
资源文件体积是否过大
资源是否重复发送请求去加载了
加载脚本的时候,渲染内容堵塞了
三、解决方案
常见的几种SPA首屏优化方式
减小入口文件积
静态资源本地缓存
UI框架按需加载
图片资源的压缩
组件重复打包
开启GZip压缩
使用SSR
2. Vue中自定义指令的理解,应用场景有哪些?
1、什么是指令
开始之前我们先学习一下指令系统这个词
指令系统是计算机硬件的语言系统,也叫机器语言,它是系统程序员看到的计算机的主要属性。因此指令系统表征了计算机的基本功能决定了机器所要求的能力
在vue中提供了一套为数据驱动视图更为方便的操作,这些操作被称为指令系统
我们看到的v-开头的行内属性,都是指令,不同的指令可以完成或实现不同的功能
除了核心功能默认内置的指令 (v-model 和 v-show),Vue 也允许注册自定义指令
指令使用的几种方式:
//会实例化一个指令,但这个指令没有参数
`v-xxx`
// -- 将值传到指令中
`v-xxx="value"`
// -- 将字符串传入到指令中,如`v-html="'<p>内容</p>'"`
`v-xxx="'string'"`
// -- 传参数(`arg`),如`v-bind:class="className"`
`v-xxx:arg="value"`
// -- 使用修饰符(`modifier`)
`v-xxx:arg.modifier="value"`
2、理解
- 全局自定义指令:vue.directive(’第一个参数是指令名称‘,{第二个参数是一个对象,这个对象有钩子函数})
- 局部自定义指令通过组件options选项中设置directive属性,是定义在组件内部的,只能在当前组件中使用
自定义指令的钩子函数
- inserted:被绑定元素插入父节点时调用 (仅保证父节点存在,但不一定已被插入文档中)。
- bind:只调用一次,指令第一次绑定到元素时调用。在这里可以进行一次性的初始化设置。
- update:所在组件的 VNode 更新时调用,但是可能发生在其子 VNode 更新之前。指令的值可能发生了改变,也可能没有。
- componentUpdated:指令所在组件的 VNode 及其子 VNode 全部更新后调用。
- unbind:只调用一次,指令与元素解绑时调用
3、应用场景
表单防止重复提交
图片懒加载
一键 Copy的功能
3. 大文件如何做断点续传?
断点续传指的是在下载或上传时,将下载或上传任务人为的划分为几个部分
每一个部分采用一个线程进行上传或下载,如果碰到网络故障,可以从已经上传或下载的部分开始继续上传下载未完成的部分,而没有必要从头开始上传下载。用户可以节省时间,提高速度
一般实现方式有两种:
- 服务器端返回,告知从哪开始
- 浏览器端自行处理
上传过程中将文件在服务器写为临时文件,等全部写完了(文件上传完),将此临时文件重命名为正式文件即可
如果中途上传中断过,下次上传的时候根据当前临时文件大小,作为在客户端读取文件的偏移量,从此位置继续读取文件数据块,上传到服务器从此偏移量继续写入文件即可
4. 说说设备像素、css像素、设备独立像素、dpr、ppi之间的区别?
设备像素:称为物理像素,指设备能控制显示的最小物理单位,没有便准的宽高,单位为 pt
Css像素:适用于web编程,在css中以px为后缀,是一个长度单位。长度单位又分为两类,绝对单位以及相对单位,相对的时设备像素,1个css像素等于1个设备独立像素
设备独立像素:与设备无关的逻辑像素,代表可以通过程序控制使用的虚拟像素,是一个总体概念,包括了css像素
Dpr:设备像素比,代表设备独立像素到设备像素的转换关系,在js中可以通过window.devicePixeRatio获取
Ppi:美英寸像素,表示每英寸所包含的像素点数目,更确切的说法应该是像素密度。数值越高,说明屏幕能以更高密度显示图像
区别:
无缩放情况下,1个css像素等于1个设备独立像素
设备独立像素由屏幕生产之后就不会发生改变,而设备独立像素是一个虚拟单位会发生改变
Pc端中,1个设备独立像素=1个设备像素(未缩放的情况下)
在移动端中,标准屏幕下1个设备独立像素=1个设备像素
设备像素比=设备像素/设备独立像素
每英寸像素值越大图象越清晰
5. 谈谈你对BFC的理解?
一、是什么
我们在页面布局的时候,经常出现以下情况:
这个元素高度怎么没了?
这两栏布局怎么没法自适应?
这两个元素的间距怎么有点奇怪的样子?
…
原因是元素之间相互的影响,导致了意料之外的情况,这里就涉及到BFC概念
BFC(Block Formatting Context),即块级格式化上下文,它是页面中的一块渲染区域,并且有一套属于自己的渲染规则:
内部的盒子会在垂直方向上一个接一个的放置
对于同一个BFC的俩个相邻的盒子的margin会发生重叠,与方向无关。
每个元素的左外边距与包含块的左边界相接触(从左到右),即使浮动元素也是如此
BFC的区域不会与float的元素区域重叠
计算BFC的高度时,浮动子元素也参与计算
BFC就是页面上的一个隔离的独立容器,容器里面的子元素不会影响到外面的元素,反之亦然
BFC目的是形成一个相对于外界完全独立的空间,让内部的子元素不会影响到外部的元素
二、触发条件
触发BFC的条件包含不限于:
根元素,即HTML元素
浮动元素:float值为left、right
overflow值不为 visible,为 auto、scroll、hidden
display的值为inline-block、inltable-cell、table-caption、table、inline-table、flex、inline-flex、grid、inline-grid
position的值为absolute或fixed
6. 说说你对栈、队列的理解?应用场景?
栈和队列都属于一位链表,栈是后进先出,进和出都是在同一端进行,就好像一筒羽毛球,只有把上面拿出来,下面的才能拿出来;
队列是先进先出的,进和出分别在不同的端进行,比如排队的人,排在前面的人先到柜台办理业务,后面来的人后得到服务。
栈:是一种运算受限的线性表,限定仅在表尾进行插入和删除操作的线性表
队列:跟栈十分相似,队列是一种特殊的线性表,特殊之处在于它只允许在表的前端进行删除操作,而在表的后端进行插入操作
栈应用场景:实现一个逆序数处,编译器的在对输入的语法进行分析的时候,函数调用和递归的时候
队列应用场景:需要按照一定的顺序来处理数据,而该数据的数据量在不断地变化的时候
7. 说说你对事件循环event loop的理解?
首先,js是一门单线程的语言,意味着同一时间内只能做一件事情,但是这并不意味着单线程就是阻塞,而实现单线程非阻塞的方法就是事件循环
在js中,所有的任务都可以分为:
同步任务:立即执行的任务,同步任务一般会直接进入主线程中执行
异步任务:异步执行的任务,比如ajax网络请求,setTimeout定时函数等
同步任务进入主线程,异步任务进入任务队列,主线程内的任务执行完毕为空,会去任务队列读取对应的任务,推入主线程执行,上述过程的不断重复就是事件循环
宏任务和微任务
微任务:一个需要异步执行的函数,执行时机是在主函数执行借宿之后,宏仁务执行之前
宏仁务:宏仁务的时间粒度比较大,执行的时间间隔是不能精确控制的,对一些高实时性的需求就不太符合
Async和await:async是异步的意思,await则可以理解为等待,放到一起可以理解async就是用来声明一个异步方法,而await是用来等待异步方法执行
正常情况下,await命令后面是一个promise对象,返回该对象的结果,如果不是promise对象,就直接返回对应的值
8. 前端跨域的解决方案?
跨域产生的原因是因为浏览器的安全策略,同源策略 协议+端口+域名只要有一个不同,那么就会产生跨域
- 前端解决跨域:document.domain+iframe(只有在主域相同的时候才能使用该方法)
- 动态创建script
- Location.hash+iframe:原理是利用loctaion.hash来进行传值
- Window.name+ifranme:name值在不同的页面加载后仍然存在,并且可以支持非常长的name值
- Cors:使用自定义的http头部让浏览器于服务器进行沟通,从而决定请求或响应是应该成功还是应该失败
- Jsonp:它包含两部分:回调函数和数据,回调函数就是当响应到来时要放在当前页面被调用的函数
数据就是传入回调函数的中的json数据,也就是回调函数的参数了,jsonp只能发送get请求,这是他的缺点 - 前端代理:通过一个代理服务器和我们的客户端进行交互,我们的客户端和服务器不能直接进行交互,所以我们在我们的客户端和服务器之间创建一个代理服务器,服务器先发送消息给代理服务器,代理服务器再把数据发送到我们的客户端,客户端把响应的数据再发给代理服务器,代理服务器返回数据给服务端
9. 说说你对vue中mixin的理解?
Mixin是面向对象程序设计语言中的类,提供了方法的实现。其他类可以访问mixin类的方法而不必成为其子类
Mixin类通常作为功能模块使用,在需要该功能时“混入”,有利于代码复用又避免了多继承的复杂
10. Vue组件通信?
组件间通信的分类可以分成以下
- 父子组件之间的通信
- 兄弟组件之间的通信
- 祖孙与后代组件之间的通信
- 非关系组件间之间的通信
组件间通信的方案
- 通过 props 传递
- 通过 $emit 触发自定义事件
- 使用 ref
- EventBus
- p a r e n t 或 parent 或 parent或root
- attrs 与 listeners
- Provide 与 Inject
- Vuex