9.20总结

一、http缓存

你了解http缓存吗?http请求在什么状态下会返回304状态码?

下面5张图,花了一晚上整理画出来🙈,图画的不太好看,但意思十分明确,不要太嫌弃喔。相信看完后,能让你对http缓存有比较深刻🤔的了解。

Http 缓存机制作为 web性能优化的重要手段,对于从事 Web开发的同学们来说,应该是知识体系库中的一个基础且重要的环节,同时对于有追求的前端童鞋来说也是必备的知识技能。

知识铺垫 了解浏览器和服务器间通信时的请求报文及响应报文,HTTP报文就是浏览器和服务器间通信时发送及响应的数据块。 参考

缓存命中规则 我们都知道前端发送请求时,命中缓存会直接返回缓存数据。那么缓存到底从哪里来的?其实我们可以认为浏览器存在这么一个缓存数据库,用于存储缓存信息。

在客户端首次请求数据时,缓存数据库中没有对应的缓存数据,需要请求服务器,服务器返回后, 将数据及缓存规则存储至缓存数据库中。 1 2 3 4

HTTP缓存有多种规则,根据是否需要重新向服务器发起请求来分类,一般将其分为两大类(强制缓存,对比缓存)

强制缓存如果生效,不需要再和服务器发生交互,而对比缓存不管是否生效,都需要与服务端发生交互。 1 强制缓存 响应头中一定有cache-control或expires属性。 其http的状态码返回:Status Code: 200 (from disk cache),说明强制缓存已被命中使用。

Expires为服务端返回的到期时间。即下一次请求时,请求时间小于服务端返回的到期时间,直接使用缓存数据。作为HTTP 1.0的作品,所以它基本可以忽略。

另一个问题是,到期时间是由服务端生成的,但是客户端时间可能跟服务端时间有误差,这就会导致缓存命中的误差。 所以HTTP 1.1的版本,使用Cache-Control替代。

Cache-Control是最重要的规则。常见的取值有no-cache、no-store、max-age、private、public、,默认为private。见下表:

字段值 作用 no-cache 防止从缓存中返回过期的资源,所以使用之前,需要和源服务器发起请求比对过期时间 no-store 这个指令才是真正的不进行缓存,暗示请求报文中可能含有机密信息,不可缓存 max-age 在指定时间内,缓存服务器不再对资源的有效性进行确认,可以使用 private 只有某个在通过缓存服务器的时候,得到缓存资源 public 所有的用户在通过缓存服务器的时候,都可以缓存这个资源。 在Cache-Control中,这些值可以自由组合,多个值如果冲突时,也是有优先级的,而no-store优先级最高。如下图:

 

强制缓存的缓存机制,如下图:

 

 

对比缓存 顾名思义,需要进行比较判断是否可以使用缓存。 响应头中一定有etag或last-modified属性。 其http的状态码返回传说中的:Status Code: 304

last-modified:

服务器第一次响应请求时,告诉浏览器资源的最后修改时间,并存储到浏览器端。 再次请求时,请求头中携带If-Modified-Since字段,将上次请求服务器资源的最后修改时间传到服务器与被请求资源的最后修改时间进行比对。 若资源的最后修改时间大于If-Modified-Since的值,说明资源又被改动过,则响应整片资源内容,返回状态码200。 若资源的最后修改时间小于或等于If-Modified-Since,说明资源无新修改,则响应HTTP 304,告知浏览器继续使用所保存的cache。 etag:

服务器资源是否被修改的唯一标志。首次请求唯一标志被存到客户端数据库。 同理,再次请求时,请求头中携带If-None-Match字段。与被请求资源的唯一标识进行比对 若不同,说明资源又被改动过,则响应整片资源内容,返回状态码200; 若不同,说明资源没有被改动过,则响应HTTP 304,告知浏览器继续使用所保存的cache。 对比缓存的缓存机制,如下图:

 

 

http缓存优先级 强制缓存优先级 高于 对比缓存。 也就是说,当执行强制缓存的规则时,如果缓存生效,直接使用缓存,不再执行对比缓存规则。

强制缓存: cache-control (http1.1) > expires(http1.0)、 对比缓存: etag(传送If-None-Match) > last-modified (传送If-Modified-Since)

总结 总的来说,http缓存的概念是比较抽象的。这里提供一个方法,可以让大家能更好的消化、吸收:我们可以通过nodejs框架快速生成接口,在接口中设置不同的缓存机制,通过 budo 、 anywhere 、 http-server 的方式快速生成静态文件服务器,去调用接口,然后在请求后对有无缓存的情况做对比。只要我们真正的动手实践,才能更快更准确的掌握知识点。顺便我们还可以通过服务实践一下http 301 和 302 状态码的区别。

原文链接:https://blog.csdn.net/tager168/article/details/120921783

二、重绘和重排

重绘: 更新了元素的绘制属性,但没有改变布局,重新把元素外观绘制出来的过程叫做重绘。例如更改元素的背景颜色。和重排(回流)相比,重绘省去了布局和分层阶段,所以执行效率比重排(回流)高。 引起重绘的操作: color border-style visibility text-decoration background-image outline box-shadow 重排(回流)一定触发重绘,重绘不一定触发重排(回流)。

重排(回流): 更新了元素的几何属性,那么浏览器需要重新计算元素的几何属性,将其安放在正确位置,这个过程叫做重排(回流)。重排(回流)意味着节点的几何属性发生改变,需重新计算并生成渲染树。 重排(回流)需要更新完整的渲染流水线,开销最大。 常见的引起重排(回流)的属性和方法: 任何改变元素位置或者大小的操作(display:none): 1.添加或删除可见的DOM元素 2.元素尺寸改变 3.内容变化,例如在input中输入文字 4.浏览器窗口尺寸改变 5.设置style属性的值 6.激活CSS伪类 7.查询某些属性或调用某些方法 几何属性: 布局:display float flex… 尺寸:margin,padding,border,width,height 获取布局信息的属性或者方法: offsetTop, offsetLeft,offsetWidth,offsetHeight,scrollTop,scrollLeft 获取布局信息,并没有改变几何属性怎么会触发重排(回流)? 大多数浏览器都会通过队列化修改并批量执行来优化重排(回流)过程。浏览器将修改操作放到队列里,当到达一个阈值,才清空队列。但是,获取布局信息的操作会强制清空队列。因为队列中,可能会有影响这些值的操作,为了给我们最精确的数据,浏览器会立即重排(回流)+重绘。 范围分为:全局,局部。

性能优化: 1.尽量使用visibility:hidden替换display:none; visibility:hidden;触发重绘;占据空间; display:none; 触发重排;不占据空间; 2.避免使用table布局 table布局可能很小一个改变就造成整个table重排。 可用ul li span等标签替代table系列标签生成表格。 3.避免设置多层内联样式 样式层级过多会影响重绘重排效率。 4.动态改变类(className)而不改变样式 5.批量修改DOM:让元素脱离文本流,对其进行多次修改,然后再把元素带回文档。 6.读写操作分离

原文链接:https://blog.csdn.net/qq_56392992/article/details/121445460

 

三、vue watch

 

Watch和computed的区别 computed支持缓存,只有依赖数据发生改变,才会重新进行计算;而watch不支持缓存,数据变,直接会触发相应的操作 computed不支持异步,当computed内有异步操作时无效,无法监听数据的变化,而watch支持异步 computed属性值会默认走缓存,计算属性是基于它们的响应式依赖进行缓存的,也就是基于data中声明过或者父组件传递的props中的数据通过计算得到的值;而watch监听的函数接收两个参数,第一个参数是最新的值,第二个参数是输入之前的值 如果一个属性是由其它属性计算而来的,这个属性依赖其它属性,多对一或者一对一,一般用computed;而当一个属性发生变化时,需要执行对应的操作,一对多,一般用watch

原文链接:https://blog.csdn.net/fu983531588/article/details/89454446

 

四、HTTP1.0和HTTP1.1和HTTP2.0的区别

1 HTTP1.0和HTTP1.1的区别 1.1 长连接(Persistent Connection) HTTP1.1支持长连接和请求的流水线处理,在一个TCP连接上可以传送多个HTTP请求和响应,减少了建立和关闭连接的消耗和延迟,在HTTP1.1中默认开启长连接keep-alive,一定程度上弥补了HTTP1.0每次请求都要创建连接的缺点。HTTP1.0需要使用keep-alive参数来告知服务器端要建立一个长连接。

1.2 节约带宽 HTTP1.0中存在一些浪费带宽的现象,例如客户端只是需要某个对象的一部分,而服务器却将整个对象送过来了,并且不支持断点续传功能。HTTP1.1支持只发送header信息(不带任何body信息),如果服务器认为客户端有权限请求服务器,则返回100,客户端接收到100才开始把请求body发送到服务器;如果返回401,客户端就可以不用发送请求body了节约了带宽。

1.3 HOST域 在HTTP1.0中认为每台服务器都绑定一个唯一的IP地址,因此,请求消息中的URL并没有传递主机名(hostname),HTTP1.0没有host域。随着虚拟主机技术的发展,在一台物理服务器上可以存在多个虚拟主机(Multi-homed Web Servers),并且它们共享一个IP地址。HTTP1.1的请求消息和响应消息都支持host域,且请求消息中如果没有host域会报告一个错误(400 Bad Request)。

1.4缓存处理 在HTTP1.0中主要使用header里的If-Modified-Since,Expires来做为缓存判断的标准,HTTP1.1则引入了更多的缓存控制策略例如Entity tag,If-Unmodified-Since, If-Match, If-None-Match等更多可供选择的缓存头来控制缓存策略。

1.5错误通知的管理 在HTTP1.1中新增了24个错误状态响应码,如409(Conflict)表示请求的资源与资源的当前状态发生冲突;410(Gone)表示服务器上的某个资源被永久性的删除。

2 HTTP1.1和HTTP2.0的区别 2.1 多路复用 HTTP2.0使用了多路复用的技术,做到同一个连接并发处理多个请求,而且并发请求的数量比HTTP1.1大了好几个数量级。HTTP1.1也可以多建立几个TCP连接,来支持处理更多并发的请求,但是创建TCP连接本身也是有开销的。

 

2.2 头部数据压缩 在HTTP1.1中,HTTP请求和响应都是由状态行、请求/响应头部、消息主体三部分组成。一般而言,消息主体都会经过gzip压缩,或者本身传输的就是压缩过后的二进制文件,但状态行和头部却没有经过任何压缩,直接以纯文本传输。随着Web功能越来越复杂,每个页面产生的请求数也越来越多,导致消耗在头部的流量越来越多,尤其是每次都要传输UserAgent、Cookie这类不会频繁变动的内容,完全是一种浪费。

   HTTP1.1不支持header数据的压缩,HTTP2.0使用HPACK算法对header的数据进行压缩,这样数据体积小了,在网络上传输就会更快。

2.3 服务器推送 服务端推送是一种在客户端请求之前发送数据的机制。网页使用了许多资源:HTML、样式表、脚本、图片等等。在HTTP1.1中这些资源每一个都必须明确地请求。这是一个很慢的过程。浏览器从获取HTML开始,然后在它解析和评估页面的时候,增量地获取更多的资源。因为服务器必须等待浏览器做每一个请求,网络经常是空闲的和未充分使用的。

   为了改善延迟,HTTP2.0引入了server push,它允许服务端推送资源给浏览器,在浏览器明确地请求之前,免得客户端再次创建连接发送请求到服务器端获取。这样客户端可以直接从本地加载这些资源,不用再通过网络。

 

参考:

    https://juejin.im/entry/5981c5df518825359a2b9476

————————————————

原文链接:https://blog.csdn.net/ailunlee/article/details/97831912

 

 

五、vue2和vue3的区别

vue经历从2.0到3.0更新之后,简⽽⾔之就是变得更轻,更快,使⽤起来更加⽅便,每⼀次的版本迭代都是对上⼀个版本的升级优化,不管 是对于我们开发者还是对于⽤户体验都是不断地在越来越⽅便,接下来我会着重于开发者来说⼀下两个不同版本的区别,

详解

1.vue2.0和3.0的初始化就存在着⼀定区别,⽐如vue3.0可以在安装脚⼿架同时提前安装好⼀些项⽬开发必备的插件,并且3.0提供了可视 化创建脚⼿架,可以更加⽅便的对插件和依赖进⾏管理和配置,同时两个版本的⽬录结构也是有些许差别的。

2.在开发过程中两个版本的使⽤⽅法虽然在表⾯上没有太⼤的⼀个区别,但是在他的底层⽅⾯去看的话区别还是很⼤的,其中就包括渲染⽅ 式,数据监听,双向绑定,⽣命周期,vue3更精准变更通知,

这⾥着重说⼀下关于双向绑定的更新,

vue2 的双向数据绑定是利⽤ES5 的⼀个 API ,Object.definePropert()对数据进⾏劫持 结合 发布订阅模式的⽅式来实现的。

vue3 中使⽤了 es6 的 ProxyAPI 对数据代理,通过 reactive() 函数给每⼀个对象都包⼀层 Proxy,通过 Proxy 监听属性的变化,从⽽ 实现对数据的监控。

这⾥是引相⽐于vue2版本,使⽤proxy的优势如下



1.defineProperty只能监听某个属性,不能对全对象监听



可以省去for in、闭包等内容来提升效率(直接绑定整个对象即可)



2.可以监听数组,不⽤再去单独的对数组做特异性操作,通过Proxy可以直接拦截所有对象类型数据的操作,完美⽀持对数组的监听。







复制代码

3.另外vue3还新增了⼀些内置组件和⽅法,⽐如vue3可以默认进⾏懒观察,使⽤Function-based API,setup函数,对与插件或对象的⼀ 个按需引⼊,Computed Value ,新加⼊了 TypeScript 以及 PWA 的⽀持等等… 这⾥着重说⼀下vue3的⼀个按需引⼊

Vue2.x中new出的实例对象,所有的东西都在这个vue对象上,这样其实⽆论你⽤到还是没⽤到,都会跑⼀遍,这样不仅提⾼了性能消耗, 也⽆疑增加了⽤户加载时间。

⽽vue3.0中可以⽤ES module imports按需引⼊,如:keep-alive内置组件、v-model指令,等等,不仅我们开发起来更加的便捷,减少 了内存消耗,也同时减少了⽤户加载时间,优化⽤户体验。

创建vue2和vue3项目的文件发生的变化

1.main.js中

img

核心代码 createApp(App).mount('#app') = createApp(根组件).mount('public/index.html中的div容器')

1.vue2.0中是直接创建了一个vue实例 2.vue3.0中按需导出了一个createApp (ceateApp做了什么) 3.vue3中的app单文件不再强制要求必须有根元素 也就是说 在vue2.0中必须要有一个根元素,在vue3中没这个要求

<template>



 <img alt="Vue logo" src="./assets/logo.png">



 <HelloWorld msg="Welcome to Your Vue.js App"/>



</template>



复制代码

数据双向绑定原理

Vue2使⽤的是Object.defineProperty()进⾏数据劫持,结合发布订阅的⽅式实现。

Vue3使⽤的是Proxy代理,使⽤ref或者reactive将数据转化为响应式数据

数据和方法的定义

Vue2使⽤的是选项类型API(Options API),Vue3使⽤的是合成型API(Composition API)

Vue2:

data() { return {}; }, methods:{ }



复制代码

Vue3:

数据和⽅法都定义在setup中,并统⼀进⾏return{}

生命周期

img

获取props

vue2:console.log(‘props’,this.xxx) vue3:setup(props,context){ console.log(‘props’,props) }

给父组件传值emit

vue2:this.$emit() vue3:setup(props,context){context.emit()}

 

六:type和interface的区别

 

type和interface都可以用来表示接口,但实际用的时候会有写差异。

1.type和interface的相同点:都是用来定义对象或函数的形状。

interface example { name: string age: number }

interface exampleFunc { (name:string,age:number): void } type example = { name: string age: number } type example = (name:string,age:number) => { } 它俩也支持继承,并且可以互相继承。但是具体的形式稍有差别。

interface是通过extends实现的,type是通过&实现的。

type aa = {
  name: string
}

interface bb {
  name: string
}

 

type cc = aa & {
  age: number
}

type cc = bb & {
  age: number
}

interface dd extends aa {
  age: number
}

interface dd extends bb {
  age: number
}

2.type和interface的不同点

typeof

type可以定义 基本类型的别名,如 type myString = string

type可以通过 typeof 操作符来定义,如 type myType = typeof someObj

type可以申明 联合类型,如 type unionType = myType1 | myType2

type可以申明 元组类型,如 type yuanzu = [myType1, myType2]

interface

interface可以 声明合并,这种情况下,如果是type的话,就会报 重复定义 的警告,因此是无法实现 声明合并 的。

interface test {
name: string
}

interface test {
age: number
}

/*
test实际为 {
name: string
age: number
}

———————————————— 版权声明:本文为CSDN博主「星期五の夜」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/weixin_43550562/article/details/123546720

posted @ 2022-09-28 17:32  青Fire  阅读(28)  评论(0编辑  收藏  举报