1.骨架屏是什么
骨架屏是一种页面美化形式,常用于用户等待数据时候,给与一个模板样式,以免网站迟迟刷新不了,不让用户以为卡死了
2.浏览器的渲染过程(了解)
首先
从浏览器接受请求来的HTML,CSS ,JavaScript等,然后解析,构建树,渲染布局,绘制,最后呈现给用户看到的页面,这个就是整个过程
构建DOM树
当浏览器接收到服务器响应来的HTML文档后,会遍历文档节点,生成DOM树。
需要注意的是,DOM树的生成过程中可能会被CSS
和JS
的加载执行阻塞。渲染阻塞问题下文会讲。
构建CSSOM规则树
浏览器解析CSS文件并生成CSS规则树,每个CSS文件都被分析成一个StyleSheet
对象,每个对象都包含CSS规则。CSS规则对象包含对应于CSS语法的选择器和声明对象以及其他对象。
渲染阻塞
当浏览器遇到一个 script 标记时,DOM 构建将暂停,直至脚本完成执行,然后继续构建DOM。每次去执行JavaScript脚本都会严重地阻塞DOM树的构建,如果JavaScript脚本还操作了CSSOM,而正好这个CSSOM还没有下载和构建,浏览器甚至会延迟脚本执行和构建DOM,直至完成其CSSOM的下载和构建
。
所以,script 标签的位置很重要。实际使用时,可以遵循下面两个原则:
CSS 优先:引入顺序上,CSS 资源先于 JavaScript 资源。
JS置后:我们通常把JS代码放到页面底部,且JavaScript 应尽量少影响 DOM 的构建。
当解析html的时候,会把新来的元素插入dom树里面,同时去查找css,然后把对应的样式规则应用到元素上,查找样式表是按照从右到左的
顺序去匹配的。
例如: div p {font-size: 16px},会先寻找所有p标签并判断它的父标签是否为div之后才会决定要不要采用这个样式进行渲染)。
所以,我们平时写CSS时,尽量用id和class,千万不要过渡层叠
。会影响我们渲染效率
构建渲染树
通过DOM树和CSS规则树我们便可以构建渲染树。浏览器会先从DOM树的根节点开始遍历每个可见节点。对每个可见节点,找到其适配的CSS样式规则并应用。
渲染树构建完成后,每个节点都是可见节点并且都含有其内容和对应规则的样式。这也是渲染树与DOM树的最大区别所在。渲染树是用于显示,那些不可见的元素当然就不会在这棵树中出现了,譬如。除此之外,display等于none的也不会被显示在这棵树里头,但是visibility等于hidden的元素是会显示在这棵树里头的。
渲染树布局
布局阶段会从渲染树的根节点开始遍历,然后确定每个节点对象在页面上的确切大小与位置,布局阶段的输出是一个盒子模型
,它会精确地捕获每个元素在屏幕内的确切位置与大小。
渲染树绘制
在绘制阶段,遍历渲染树,调用渲染器的paint()方法在屏幕上显示其内容。渲染树的绘制工作是由浏览器的UI后端组件完成的。
reflow与repaint
:
根据渲染树布局,计算CSS样式,即每个节点在页面中的大小和位置等几何信息。HTML默认是流式布局的,CSS和js会打破这种布局,改变DOM的外观样式以及大小和位置。这时就要提到两个重要概念:replaint和reflow。
replaint(重绘):屏幕的一部分重画,不影响整体布局,比如某个CSS的背景色变了,但元素的几何尺寸和位置不变。
reflow(重排):意味着元件的几何尺寸变了,我们需要重新验证并计算渲染树。是渲染树的一部分或全部发生了变化。这就是Reflow,或是Layout。
所以我们应该尽量减少reflow和replaint,我想这也是为什么现在很少有用table布局
的原因之一。
display:none 会触发 reflow,visibility: hidden属性并不算是不可见属性,它的语义是隐藏元素,但元素仍然占据着布局空间,它会被渲染成一个空框,所以visibility:hidden 只会触发 repaint,因为没有发生位置变化。
有些情况下,比如修改了元素的样式,浏览器并不会立刻 reflow 或 repaint 一次,而是会把这样的操作积攒一批,然后做一次 reflow,这又叫异步 reflow 或增量异步 reflow。
有些情况下,比如 resize 窗口,改变了页面默认的字体等。对于这些操作,浏览器会马上进行 reflow。
3.cdn加速过程?为什么有时候需要直接引入cdn上面的库文件?
CDN网络是在用户和服务器之间增加Cache层,主要是通过接管DNS实现,将用户的请求引导到Cache上获得源服务器的数据,从而降低网络的访问时间。
可以优化网站的整个运行速度
4.图片懒加载?(代码)
懒加载是一种网页性能优化的方式,它能极大的提升用户体验。就比如说图片,图片一直是影响网页性能的主要元凶,现在一张图片超过几兆已经是很经常的事了。如果每次进入页面就请求所有的图片资源,那么可能等图片加载出来用户也早就走了。所以,我们需要懒加载,进入页面的时候,只请求可视区域的图片资源。
总结出来就两个点:
1.全部加载的话会影响用户体验
2.浪费用户的流量,有些用户并不像全部看完,全部加载会耗费大量流量。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>图片懒加载</title>
<style>
img {
display: block;
width: 100%;
height: 300px;
margin-bottom: 20px;
}
</style>
</head>
<body>
<img data-src="/img/img.jpg" alt="">
<img data-src="/img/timg.jpg" alt="">
<img data-src="/img/timg3.jpg" alt="">
</body>
<script>
var imgs = document.querySelectorAll('img');
//offsetTop是元素与offsetParent的距离,循环获取直到页面顶部
function getTop(e) {
var T = e.offsetTop;
while(e = e.offsetParent) {
T += e.offsetTop;
}
return T;
}
function lazyLoad(imgs) {
var H = document.documentElement.clientHeight;//获取可视区域高度
var S = document.documentElement.scrollTop || document.body.scrollTop;
for (var i = 0; i < imgs.length; i++) {
if (H + S > getTop(imgs[i])) {
imgs[i].src = imgs[i].getAttribute('data-src');
}
}
}
window.onload = window.onscroll = function () { //onscroll()在滚动条滚动的时候触发
lazyLoad(imgs);
}
</script>
</html>
知乎有张图挺不错,借鉴一下
5.数据发生了变化,但是视图为什么没有得到更新 this.arr[index]=“000”?
根据官方文档的说明
对于数组
Vue 不能检测以下数组的变动:
- 当你利用索引直接设置一个数组项时,例如:
vm.items[indexOfItem] = newValue
- 当你修改数组的长度时,例如:
vm.items.length = newLength
举个例子:
var vm = new Vue({
data: {
items: ['a', 'b', 'c']
}
})
vm.items[1] = 'x' // 不是响应性的
vm.items.length = 2 // 不是响应性的
为了解决第一类问题,以下两种方式都可以实现和 vm.items[indexOfItem] = newValue
相同的效果,同时也将在响应式系统内触发状态更新:
// Vue.set
Vue.set(vm.items, indexOfItem, newValue)
// Array.prototype.splice
vm.items.splice(indexOfItem, 1, newValue)
你也可以使用 vm.$set
实例方法,该方法是全局方法 Vue.set
的一个别名:
vm.$set(vm.items, indexOfItem, newValue)
为了解决第二类问题,你可以使用 splice
:
vm.items.splice(newLength)
结论
Vue 是可以实现对数组进行监听的,但是为了性能的提升,故意去这么设置的
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-41G3fYK7-1605510214237)(C:\Users\丁松\AppData\Roaming\Typora\typora-user-images\1600575776060.png)]
https://segmentfault.com/q/1010000015780995
作者的回答:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zjDrUofc-1605510214239)(C:\Users\丁松\Desktop\20191014100842118.jpg)]
6.虚拟dom? diff的算法?
虚拟DOM,也就是我们常说的虚拟节点,是用JS对象来模拟真实DOM中的节点,该对象包含了真实DOM的结构及其属性,用于对比虚拟DOM和真实DOM的差异,从而进行局部渲染来达到优化性能的目的。
所以虚拟DOM出现的主要目的就是为了减少频繁操作DOM而引起回流重绘所引发的性能问题的!
diff算法
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TDAyrnVp-1605510214240)(assets/aHR0cHM6Ly9wMy1qdWVqaW4uYnl0ZWltZy5jb20vdG9zLWNuLWktazN1MWZicGZjcC9iZmE4NTNiODhjYzk0ODc5YmZjZThjZDI4ZThmNDYwNX50cGx2LWszdTFmYnBmY3Atem9vbS0xLmltYWdl.png)]
在采取diff算法比较新旧节点的时候,比较只会在同层级进行, 不会跨层级比较。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-QSyYUBOd-1605510214240)(assets/998023-20180519212357826-1474719173.png)]
diff算法是实现双向绑定的重要步骤,我们一开始是通过observer对对象进行监听,当监听到的值发生了改变就会通知订阅者watcher 调用diff算法的实现方法patch来对新生成的虚拟dom和之前的虚拟dom进行比较,判断是否又差异,如果又差异就直接返回当前的虚拟dom不修改,如果又差异,就不断的进行匹配,进行深度判断。做出对应的处理
7.防抖,节流?
在这里我用同样的列子以做说明,以便区分
可用于验证用户的输入,比如注册账户的时候填写用户名
防抖:
我们没有必要每次文本框的值改变就去验证用户是否重复,这样太过于频繁的向服务器发送了请求。我们可以等待用户输入完了,比如我们规定文本框失去了焦点,我们再去验证用户名是否重复这样好点
节流:
但是,如果你的技术经理就是想让你,实现文本框没有失去焦点,还能节省性能消耗的,用节流一样可以实现。
其实很简单:我们可以设计一种类似控制阀门一样定期开放的函数,也就是让函数执行一次后,在某个时间段内暂时失效,过了这段时间后再重新激活
我们可以定义一个定时器,在文本框有焦点并且内容长度大于0,时候开启,失去焦点或者内容长度等于0时候关闭,
规定一个事件间隔,这样我们就可以实现对用户名的重复验证逻辑的节流
防抖与节流的总结
是一种算法,或者说是一种编程的思维,这两种方式对有助于我们在应当短时间触发大量的操作和事件
时候需要用到的