vue2响应式原理
vue2主要是采用了数据劫持结合发布者-订阅者模式来实现数据的响应式,vue在初始化的时候,会遍历data中的数据,使用object.defineProperty为data中的每一个数据绑定setter和getter,当获取数据的时候会触发getter,在getter中会收集对应的依赖,即收集订阅者,将这些订阅者存储起来;当数据被赋值或者修改时,就会触发setter,在setter中会调用notify方法通知订阅者数据发生变化,订阅者收到消息后调用update方法更新视图。以上是model(数据)改变,view(视图)随之一起改变的原理,而要做到view改变,model也随之改变的话,主要就是监听dom事件,在事件回调函数中对model数据进行修改。
什么是泛型?
泛型允许我们在定义的时候不具体指定类型,而是泛泛地说一种类型,并在函数调用的时候再指定具体的参数类型,也就是说泛型也是一种类型,只不过不同于 string, number 等具体的类型,它是一种抽象的类型,我们不能直接定义一个变量类型为泛型。简单来说,区别于平时我们对「值」进行编程,泛型是对「类型」进行编程。
从浏览器输入url后都经历了什么?
- 从浏览器输入网址后,首先要经过域名解析,因为浏览器并不能直接通过域名找到服务器,而是通过IP地址找到对应的服务器,DNS域名解析时,先查看本地hosts文件,查看有没有当前域名对应的ip地址,若有直接发起请求,没有的话会在本地域名服务器去查找,该查找属于递归查找,如果本地域名服务器没查找到,会从根域名服务器查找,该过程属于迭代查找,根域名会告诉你从哪个与服务器查找,最后查找到对应的ip地址后把对应规则保存到本地的hosts文件中。
如果想加速以上及之后的http请求过程的话可以使用缓存服务器CDN,CDN过程如下:
用户输入url地址后,本地DNS会解析url地址,不过会把最终解析权交给CNAME指向的CDN的DNS服务器,CDN的DNS服务器会返回给浏览器一个全局负载均衡IP,用户会根据全局负载均衡IP去请求全局负载均衡服务器,全局负载均衡服务器会根据用户的IP地址,url地址,会告诉用户一个区域负载均衡设备,让用户去请求它。区域负载均衡服务器会为用户选择一个离用户较近的最优的缓存服务器,并把ip地址给到用户,用户想缓存服务器发送请求,如果请求不到想要的资源的话,会一层层向上一级查找,直到查找到为止。
- 浏览器通过IP地址找到对应的服务器后,建立TCP连接,通过三次握手以同步客户端和服务端的序列号和确认号,并交换TCP窗口大小的信息;
- TCP三次握手结束后,开始发送HTTP请求;
- 服务器处理请求,并返回HTTP响应报文,可能返回304也可能返回200
返回304说明客户端缓存可用,直接使用客户端缓存即可,该过程属于协商缓存 返回200的话会同时返回对应的数据
- 客户端拿到响应文本HTML后,自上而下执行代码,开始解析渲染页面
其中遇到CSS加载的时候,CSS不会阻塞DOM树的解析,但是会阻塞DOM树的渲染,并且CSS会阻塞下面的JS的执行
然后是JS加载,JS加载会影响DOM的解析,之所以会影响,是因为JS可能会删除添加节点,如果先解析后加载的话,DOM树还得重新解析,性能比较差。如果不想阻塞DOM树的解析的话,可以给script添加一个defer或者async的标签。
defer:不会阻塞DOM解析,等DOM解析完之后在运行,在DOMContentloaed之前 async:
不会阻塞DOM解析,等该资源下载完成之后立刻运行 进行DOM渲染和Render树渲染 获取html并解析为Dom树
解析css并形成一个cssom(css树) 将cssom和dom合并成渲染树(render树) 进行布局(layout)
进行绘制(painting) 回流重绘 回流必将引起重绘,重绘不一定引起回流 当改变 width、height
等影响布局的属性时会引起回流,或者当获取 scroll、client、offset的值时,浏览器为获取这些值也会进行回流,getComputedStyle 也会引起回流
- 当数据传送完毕后,断开TCP连接。
讲一下https相关知识?
HTTPS是在HTTP上建立SSL加密层,并对传输数据进行加密,是HTTP协议的安全版,具有不可否认性,可以保证对方身份的真实性,默认端口是443端口,而且会保证数据的完整性。采用 对称加密 和 非对称加密 结合的方式来保护浏览器和服务端之间的通信安全。
HTTPS实现原理:
首先客户端向服务端发送一个随机值和一个客户端支持的加密算法,并连接到443端口。
服务端收到以后,会返回另外一个随机值和一个协商好的加密算法,这个算法是刚才发送的那个算法的子集
随后服务端会再次发送一个 CA 证书,这个 CA 证书实际上就是一个公钥,包含了一些信息(比如颁发机构和有效时间等)
客户端收到以后会验证这个 CA 证书,比如验证是否过期,是否有效等等,如果验证未通过,会弹窗报错。
如果验证成功,会生成一个随机值作为预主密钥,客户端使用刚才两个随机值和这个预主密钥组装成会话密钥;再使用刚才服务端发来的公钥进行加密发送给服务端;这个过程是一个非对称加密(公钥加密,私钥解密)
服务端收到以后使用私钥解密,随后得到那两个随机值和预主密钥,随后再组装成会话密钥。
客户端在向服务端发起一条信息,这条信息使用会话秘钥加密,用来验证服务端时候能收到加密的信息
服务端收到以后使用刚才的会话密钥解密,在返回一个会话密钥加密的信息,双方收到以后 SSL 建立完成;这个过程是对称加密(加密和解密是同一个)。
什么情况下会抽取组件?
1、设计稿上样式相似,多个地方使用: 当多个地方需要类似的功能或UI样式相似时,可以将其抽离为一个组件,以便在多个地方重复使用。
2、复杂的UI结构: 如果某个页面或部分的UI结构设计得非常复杂,可以将其拆分为更小、更易管理的组件,以提高可维护性。
3、可复用的逻辑: 如果某个组件包含了复杂的业务逻辑,这些逻辑可能在其他地方也需要使用,可以将这些逻辑抽离为一个可复用的组件。
4、应用需要较高性能: 通过按需加载组件,可以在页面渲染时减少不必要的资源加载,从而提高应用性能。
5、团队协作: 在多人协作的项目中,拆分组件可以让团队成员更容易独立开发、测试和维护不同的部分。
6、考虑技术栈变化: 如果考虑项目技术栈发生变化的情况,组件的抽离可以使迁移工作更加容易,因为你只需要关注一个个独立的组件。
注意:过度抽离可能会导致组件层次过深,增加理解和调试的难度,因此需要在合理的范围内进行抽离。
在平时的开发工作中,做过哪些性能优化?
1、配置webpack,在生产环境中去除console.log的打印;
2、将项目中用到的图标制作成雪碧图,减少http 请求数,并且充分利用缓存来提升性能;
3、去除不必要的请求,将项目中残留的无效请求连接去除(废弃的后台接口等),避免重复的资源请求,合理设置HTTP缓存;;
4、图片懒加载,在图片即将进入可视区域的时候进行加载;
5、使用 webpack 插件 image-webpack-loader对图片进行压缩;
6、使用事件委托,防抖和节流,尽量不要使用JS动画,css3动画和canvas动画都比JS动画性能好;
7、将外部脚本置底(将脚本内容在页面信息内容加载后再加载);
8、在首页不需要使用的脚本文件,可以使用懒加载的方式对其进行加载(只有在需要加载的时候加载,在一般情况下并不加载脚本内容。)使用import(“…/…/xxxx.js”)方式加载文件即懒加载,webpack 的懒加载实现在打包时会将懒加载的代码切割出去单独打包,然后在主包中进行按需加载,最后执行调用;
9、精简javaScript和css;
10、减少不必要的 HTTP跳转 。
【关于性能优化这个问题也可以用具体的实例说明,回答的模板:
性能问题的出现:在今年的xx月,测试同事发现在这个项目的xx页面加载的时候出现卡顿。(这点其实能编,注意 对于产品、测试、用户 而言,能直观感受到的就是卡顿、慢)
问题复现:随后我打开页面,通过工具测试发现(这里的工具可以是performance、lighthouse、前端埋点SDK亦或者其他第三方的监测工具,你要说你直接调用浏览器的performance API估计也能行但不推荐,容易被面试官反问为什么不封装个性能检测工具…orz)几个性能指标存在问题:FCP、TTI这两个性能指标都过长,FCP达到了3.x秒,TTI更是长达5.x秒(不要选太多性能指标,很多性能指标可以不纳入你们公司的衡量范围,or你编的衡量范围~~)。
问题分析:(分析过程相信大家都有,这段大家可以自己想想,在此我以FCP为例)我发现在xx页面加载的时候会先获取几张比较大的图片,导致FCP指标过长。
优化方案:采取了图片优化策略xxx执行优化。(下文提及哪些优化策略)
量化优化效果:在经过上述的优化方案后,我们最终将FCP优化到了1.8秒,TTI优化到了3.8秒。(量化你的优化成果)
(非必要)优化是否达标:如果同学们的公司对性能指标的数据有强要求,比如FCP必须在2秒以内诸如此类…,可以提一下,可以代表你在之前的公司是有完善的性能优化流程的。】