1. preload和prefetch区别
preload告诉浏览器立即加载资源,页面必定要的资源;
prefetch告诉浏览器等空闲的时候加载资源,页面不一定需要的资源;
二者仅仅只是会加载资源,不会执行
在vue ssr生成的页面中,首页资源均使用preload,路由对应的资源使用prefetch
使用 preload
和 prefetch
的逻辑可能不是写到一起,但一旦发生对用一资源 preload
或 prefetch
的话,会带来双倍的网络请求。
<link rel="preload" href="https://tiven.cn/js/test.js" as="javascript">
<link rel="prefetch" href="https://tiven.cn/js/test.js" as="javascript">
2. DOM全称,页面渲染的过程
document object model 文档页面模型
- 渲染进程将 HTML 内容转换为能够读懂的 DOM 树结构。
- 渲染引擎将 CSS 样式表转化为浏览器可以理解的 styleSheets,计算出 DOM 节点的样式。
- 创建布局树,并计算元素的布局信息。
- 对布局树进行分层,并生成分层树。
- 为每个图层生成绘制列表,并将其提交到合成线程。
- 合成线程将图层分成图块,并在光栅化线程池中将图块转换成位图。
- 合成线程发送绘制图块命令 DrawQuad 给浏览器进程。
- 浏览器进程根据 DrawQuad 消息生成页面,并显示到显示器上
3. 重绘和回流
回流
回流:DOM的变化影响了元素的集合属性(宽,高),浏览器会重新计算元素的几何属性,会使渲染树中受到影响的部分失效,浏览器会验证其他节点的visibility属性。因此回流是低效的。
回流的产生
当页面布局和几何属性改变时会触发回流
(1)DOM树的结构变化时:例如节点的增删、移动等。浏览器引擎布局的时候,类似于树的前序遍历,是一个从上到下从左到右的过程。通常在这个过程中,当前元素不会再影响其前面已经遍历过的元素。所以,如果在body最前面插入一个元素,会导致整个文档的重新渲染,而在其后插入一个元素,则不会影响到前面的元素。
(2)元素的尺寸改变:当DOM元素的几何属性变化时(边距、填充、边框、宽度和高度),渲染树中的相关节点就会失效,浏览器会根据DOM元素的变化重新构建渲染树中失效的节点。
(3)获取某些属性时:浏览器为取得正确的值也会触发重排。这些属性包括:offsetTop、offsetLeft、 offsetWidth、offsetHeight、scrollTop、scrollLeft、scrollWidth、scrollHeight、clientTop、clientLeft、clientWidth、clientHeight、getComputedStyle() (currentStyle in IE)。所以,在多次使用这些值时应进行缓存。
(4)页面内容改变
(5)页面初始化渲染
(6)浏览器窗口尺寸改变,如resize事件发生时。
重绘
重绘:重绘指的是当render tree中的一些元素需要更新属性,而这些属性只是影响元素的外观,风格,而不会影响布局的,比如background-color,visibility,outline等。
重绘不会带来重新布局,并不一定伴随回流(重排)。
减少重绘回流的方法
减少回流、重绘其实就是需要减少对render tree的操作(合并多次对DOM和样式的修改),并减少对一些style信息的请求,尽量利用好浏览器的优化策略。接下来介绍解决方法。
- 尽量不用内联样式style属性,操作元素样式的时候用添加去掉class类的方式,实现合并多次改变样式属性的操作
- 给元素加动画的时候,可以把该元素的定位设置成absolute或者fixed(动画元素脱离文档流),这样不会影响其他元素,减少回流的Render Tree的规模。
- 在需要经常获取那些引起浏览器重排的属性值时,要缓存到变量。
- 尽可能在DOM树的最末端改变class。
- 避免设置多层内联样式。
- 动画效果应用到position属性为absolute或fixed的元素上。
- 牺牲平滑度换取速度。
- 免使用table布局。
- 避免使用CSS的JavaScript表达式。
- 避免逐项更改样式。最好一次性更改style属性,或者将样式列表定义为class并一次性更改class属性。
- 避免循环操作DOM。创建一个documentFragment或div,在它上面应用所有DOM操作,最后再把它添加到window.document。
- 可以在一个display:none的元素上进行操作,最终把它显示出来。因为display:none上的DOM操作不会引发回流和重绘。
4. computed和watch的区别
computed
- 支持缓存,只有依赖数据发生改变,才会重新进行计算
- 不支持异步,当computed内有异步操作时无效,无法监听数据的变化
- computed 属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过或者父组件传递的props中的数据通过计算得到的值
- 如果一个属性是由其他属性计算而来的,这个属性依赖其他属性,是一个多对一或者一对一,一般用computed
- 如果computed属性属性值是函数,那么默认会走get方法;函数的返回值就是属性的属性值;在computed中的,属性都有一个get和一个set方法,当数据变化时,调用set方法。
watch
- 不支持缓存,数据变,直接会触发相应的操作。
- watch支持异步;监听的函数接收两个参数,第一个参数是最新的值;第二个参数是输入之前的值;
- 当一个属性发生变化时,需要执行对应的操作;一对多;
- 监听数据必须是data中声明过或者父组件传递过来的props中的数据,当数据变化时,触发其他操作,函数有两个参数
5. v-if和v-show的区别
v-if 不占位 生成或删除节点
v-show 占位 display:none
6. v-if为什么不能和v-for一起使用
v-if不能和v-for一起使用的原因是v-for的优先级比v-if高,一起使用会造成性能浪费 解决方案有两种,把v-if放在v-for的外层或者把需要v-for的属性先从计算属性中过滤一次 v-if和v-for的优先级问题在vue3中不需要考虑,vue3更新了v-if和v-for的优先级,使v-if的优先级高于v-for
7. scss和less的区别
相同点:
- LESS和SCSS都是css的预处理器,可以拥有变量,运算,继承,嵌套的功能,使用两者可以使代码更加的便于阅读和维护。
- 都可以通过自带的插件,转成相对应的css文件。
- 都可以参数混入,可以传递参数的class,就像函数一样
- 嵌套的规则相同,都是class嵌套class
不同点:
- 声明和使用变量:less用@ scss用$
- 变量插值:LESS采用@{XXXX}的形式,SCSS采用${XXXX}的形式
- scss支持条件语句,less不支持
- 引用外部css文件方式不同:SCSS应用的css文件名必须以‘_’开头(下划线),文件名如果以下划线开头的话,sass会认为改文件是一个应用文件,不会将它转成css文件
8. promise
promise有三个状态:pending、fulfilled、rejected
promise.all()
该方法用于将多个Promise实例,包装成一个新的Promise实例。
var p=Promise.all([p1,p2,p3]);
(1)只有p1、p2、p3的状态都变成fulfilled,p的状态才会变成fulfilled,此时p1、p2、p3的返回值组成一个数组,传递给p的回调函数。
(2)只要p1、p2、p3之中有一个被rejected,p的状态就变成rejected,此时第一个被reject的实例的返回值,会传递给p的回调函数。
promise.race( )
Promise.race是赛跑的意思,也就是说Promise.race([p1, p2, p3])里面的结果哪个获取的快,就返回哪个结果,不管结果本身是成功还是失败
使用场景: Promise.all和Promise.race都是有使用场景的。 有些时候我们做一个操作可能得同时需要不同的接口返回的数据,这时我们就可以使用Promise.all; 有时我们比如说有好几个服务器的好几个接口都提供同样的服务,我们不知道哪个接口更快,就可以使用Promise.race,哪个接口的数据先回来我们就用哪个接口的数据
9. array方法
10. 父子页面生命周期渲染顺序
结合父子组件之后 一个完整的父子组件生命周期: 父beforeCreate -> 父created -> 父beforeMount -> 子beforeCreate -> 子created -> 子beforeMount -> 子mounted -> 父mounted->父beforeUpdate->子beforeUpdate->子updated->父updated->父beforeDestroy->子beforeDestroy->子destroyed->父destroye
11. for in 和 for of的区别
for in可以遍历对象,for of 不能遍历对象,只能遍历带有iterator接口的,例如Set,Map,String,Array
二者都可以遍历数组,for in 输出的是数组的index下标,而for of 输出的是数组的每一项的值。
总结:for in适合遍历对象,for of适合遍历数组。for in遍历的是数组的索引,对象的属性,以及原型链上的属性。