提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
- 1 跨标签页通讯
- 2 浏览器架构
- 3渲染机制
- 3.1 步骤
- 3.2 图层
- 3.3 重绘与回流
- 3.3.1会触发回流的操作有
- 3.5 缩短白屏时长,可以有以下策略
- 4 跨域
- 5 浏览器缓存
- 浏览器
- 服务端
- 6.1强缓存
- `Cache-Control(HTTP1.1)`:
- 6.2 协商缓存(对比缓存)
- 资源标识
- 两者比较:
- 三种刷新操作对http缓存的影响
- 6.3缓存场景
- 6.4 对于304
- 6.5强缓存、协商缓存什么时候用哪个
- 6.6缓存小结
- 6.7 cookie和localStorage/session/indexDB的区别
- 6.8cookie
- 6.9 什么是Session
- 认证流程
- 6.10 Cookie和Session的区别
- 内存泄漏
1 跨标签页通讯
🍔不同标签页间的通讯,本质原理就是运用一些可以共享的中间介质
- 通过父页面
window.open()
和子页面postMessage
- 异步下,通过
window.open('about:blank')
和tab.location.href = '*'
- 设置同域下共享
localStorage
与监听window.onstorage
- 重复写入相同的值无法触发,会受到浏览器隐式模式的限制
- 设置共享
cookie
与不断轮询脏检查(setInterval) - 借助服务端或者中间层实现
2 浏览器架构
- 用户界面
- 主进程
- 内核(渲染引擎、js引擎、执行栈)
- 事件触发线程(消息队列、微任务、宏任务)
- 网络异步线程
- 定时器线程
3渲染机制
3.1 步骤
- 处理
HTML
并构建DOM
树 - 处理
CSS
构建CSSOM
树 - 将
DOM
与CSSOM
合并成一个渲染树 - 根据渲染树来布局,计算每个节点的位置
- 调用
GPU
绘制,合成图层,显示在屏幕上
3.2 图层
🥟一般来说,可以把普通文档流看成一个图层。特定的属性可以生成一个新的图层。不同的图层渲染互不影响,所以对于某些频繁需要渲染的建议单独生成一个新图层,提高性能。但也不能生成过多的图层,会引起反作用。
3.3 重绘与回流
🍔当元素的样式发生变化时,浏览器需要触发更新,重新绘制元素。此过程,有两种类型的操作,即重绘与回流。
重绘
(repaint):当元素样式的改变不影响布局时,浏览器将使用重绘对元素进行更新,此时由于只需要UI层面的重新像素绘制,因此 损耗较少。回流
(reflow):当元素的尺寸、结构或触发某些属性时,浏览器会重新渲染页面,称之为回流
。此时,浏览器需要重新经过计算,计算后还需要重新页面布局,因此是较重的操作。
3.3.1会触发回流的操作有
- 页面初次渲染
- 浏览器窗口大小改变
- 元素尺寸、位置、内容发生变化
- 元素字体大小变化
- 添加或删除可见的DOM元素
- 激活CSS伪类
- 查询某些属性或调用某些方法
- 回流必定触发重绘,重绘的开销较小,回流的代价较高。
3.5 缩短白屏时长,可以有以下策略
- 通过内联js、内联css来移除这两种类型的文件下载,这样获取到html文件之后就可以直接开始渲染流程了。
- 但并不是所有场合都时候内联,那么还可以尽量减少文件大小,比如通过webpack等工具移除一些不必要的注释,并压缩js文件。
- 还可以将一些不需要再解析html阶段使用的js标记上sync或defer
- 对于大的css文件,可通过媒体查询属性,将其拆分为多个不同用途的文件,这样只有在特定的场景下才会加载特定的css文件。
4 跨域
🥞 浏览器的安全考虑,有同源策略。需要协议、域名、端口都需要相同,否则就会报错。
5 浏览器缓存
🥙业务中的一些数据进行存储,通常分为短暂性存储
和`持久性储存
- 短暂性存储:需要将数据存在内存中,只在运行时可用。
- 持久性存储:分为浏览器端和服务端
浏览器
cookie
:通常用于存储用户身份,登录状态。http中自动携带,体积上限为4k
,可自行设置过期时间localStorage/sessionStorage
:长久储存、窗口关闭删除,体积限制为4-5M
- indexDB
服务端
- 分布式缓存
redis
- 数据库
🎉缓存分为强缓存
和协商缓存
。前者不过服务器,后者需要过服务器,后者返回的状态码是304。两类缓存可以同时存在,前者的优先级高于后者。当执行强缓存时,如若缓存命中,则直接使用缓存数据库中的数据,不再进行缓存协商。
6.1强缓存
🌯Expires(HTTP1.0):Exprires的值为服务端返回的数据到期时间。当再次请求的时间小于返回的时间,则直接使用缓存数据。但由于服务端时间和客户端时间可能有误差,这也将导致缓存命中的误差。
🧇另一方面,Exprires是HTTP1.0的产物,故现在大多数使用Cache-Control
替代
🚕缺点:使用的是绝对时间,如果服务端和客户端的时间产生偏差,那么会导致命中缓存产生偏差。
Cache-Control(HTTP1.1)
:
private
:客户端可以缓存public
:客户端和代理服务器都可以缓存max-age=t
:缓存内容将在t秒后失效no-cache
:需要使用协商缓存来验证缓存数据,可以在客户端储存资源,每次都必须去服务端做新鲜度校验,来决定从服务端获取新的资源还是使用客户端缓存no-store
:所有内容都不会缓存,永远都不要在客户端存储资源,永远都去原始服务器去获取资源。
6.2 协商缓存(对比缓存)
🍚协商缓存需要进行对比判断是否可以使用缓存。浏览器第一次请求数据时,服务器会将缓存标识与数据一起响应给客户端,客户端将它们备份至缓存中。
🍟再次请求时,客户端会将缓存中的标识发送给服务器,服务器根据此标识判断。若未失效,返回304状态码,浏览器拿到此状态码就可以直接使用缓存数据了。
Last-Modified
:服务器在响应请求时,会告诉浏览器资源的最后修改时间。if-Modified-Since
:浏览器再次请求服务器时,请求头会包含此字段,后面跟着缓存中获得的最后修改时间。服务端收到此请求头发现有if-Modified-Since
,则与被请求资源的最后修改时间进行对比,如果一致则返回304和响应报文头,浏览器只需要从缓存中获取信息即可。- 如果真的被修改:那么开始传输响应一个整体,服务器返回:200或者ok
- 如果没有被修改:那么只需传输响应
header
,服务器返回304 Not Modified
Etag
:服务器响应请求时,通过此字段告诉浏览器当前资源在服务器生成的唯一标识(生成规则由服务器决定)If-Match
:条件请求,携带上一次请求中资源的ETag
,服务器根据这个字段判断文件是否有新的修改If-None-Match
:再次请求服务器时,浏览器的请求报文头部会包含此字段,后面的值为在缓存中获取的标识。服务器接收到次报文后发现If-None-Match
则与被请求资源的唯一标识进行对比。- 但是实际应用中由于Etag的计算是使用算法来得出的,而算法会占用服务端计算的资源,所有服务端的资源都是宝贵的,所以就很少使用Etag了
🍿 浏览器地址栏写入url,回车浏览器发现缓存中有这个文件了,不用继续请求了,直接去缓存拿
🥞F5刷新是告诉浏览器,去服务器看看某个文件是否过期了。发送一个请求带上If-Modify-Since
🍕Ctrl+F5
告诉浏览器,先把缓存中的这个文件删除,再去服务器请求个完整的资源文件下来。 - 服务端判断客户端资源,是否和服务端资源一样
- 一致则返回
304
,否则返回200
和最新的资源
资源标识
- 在
Response Headers
中,有两种 Last-Modified
资源的最后修改时间Etag
:唯一标识(一个字符串)
🍖服务端拿到if-Modified-Since
之后拿到这个时间去和服务端资源最后修改时间做比较,如果一致则返回304
,不一致就返回200和新的资源及新的Last-Modified
🎉其实Etag
和Last-Modified
一样,只不过Etag
是服务端对资源按照一定方式计算出来的唯一标识,就像指纹一样,传给客户端之后,客户端再传过来时候,服务端会将其与现在的资源计算出来的唯一标识做比较,一致则返回 304,不一致就返回 200 和新的资源及新的 Etag
两者比较:
- 优先使用
Etag
Last-Modified
只能精确到秒级- 如果资源被重复生成,而内容不变,则
Etag
更精确
三种刷新操作对http缓存的影响
- 正常操作:地址栏输入
url
,跳转链接,前进后退等(强制缓存有效,协商缓存有效) - 手动刷新:
f5
,点击刷新按钮,右键菜单刷新(强制缓存失效,协商缓存有效) - 强制刷新:
f5+ctrl
,shift+command+r
(两者都失效)
6.3缓存场景
🍕大部分的场景都可以使用强缓存配合协商缓存解决,但是在一些特殊的地方可能需要选择特殊的缓存策略。
- 对于某些不需要缓存的资源,可以使用
Cache-control:no-store
,表示该资源不需要缓存 - 对于频繁变动的资源,可以使用
Cache-Control:no-cache
并配合ETag
使用,表示该资源已被缓存,但是每次都会发送询问资源是否更新 - 对于代码文件来说,通常使用
Cache-Control:max-age=31536000
并配合策略缓存使用,然后对文件进行指纹处理,一旦文件名变动就会立刻下载新的文件
6.4 对于304
🧇如果客户端发送了一个带条件的GET
请求且该请求已被允许,而文档的内容(自上次访问以来或者根据请求的条件)并没有改变,则服务器应当返回这个304
状态码
6.5强缓存、协商缓存什么时候用哪个
🥪服务器上的资源不是一直固定不变的,大多数情况下它会更新,此时如果我们还访问本地缓存,相当于资源没有更新,用户看到的还是旧的资源,使用强缓存;服务器上的资源更新了浏览器就请求新的资源,没有更新就使用本地的缓存,以最大程度的减少网络请求而产生的资源浪费。
6.6缓存小结
-强缓存和协商缓存, 根据响应的header
内容来决定。
- 强缓存相关字段有
expires,cache-control
。如果两者同时存在,cache-control
的优先级高于expires
。 - 协商缓存相关字段有
Last-Modified/If-Modified-Since,Etag/If-None-Match
6.7 cookie和localStorage/session/indexDB的区别
6.8cookie
HTTP是无状态的协议
,每次客户端和服务端会话完成时,服务端不会保存任何会话信息:每个请求都是完全独立的,服务端无法确认当前访问者的身份信息,所有服务器与浏览器为了进行会话跟踪,就必须去维护一个状态,用于告知服务端前后两个请求是否来自同一个浏览器。这个状态需要通过cookie
或者session
去实现cookie存储在客户端
:是服务器发送到用户端并保存在本地的一小块数据,它会在浏览器下次向同一个服务器再发起请求时被携带并发送到服务器。cookie是不可跨域的
:绑定单一的域名,无法在别的域名下获取使用,一级域名和二级域名之间是允许共享使用的
(靠的是domain
)
6.9 什么是Session
session
是另一种记录服务器和客户端会话状态的机制session
是基于cookie
实现的,session
存储在服务端,sessionId
会被存储到客户端cookie
认证流程
- 用户首次请求服务器的时候,服务器根据用户提交的相关信息,创建对应的
session
- 请求返回时将此
session
的唯一标识信息返回给浏览器 - 浏览器接收到服务器返回的
sessionID
信息后,会将信息存入到Cookie
中,同时Cookie
记录此SessionID
属于哪个域名。 - 当用户第二次访问服务器时,请求会自动判断此域名下是否存在
Cookie
信息,如果存在自动将Cookie
信息也发送到服务端,服务端会从Cookie
中获取SessionID
,再根据SessionID
查找对应的Session
信息,如果没有找到说明用户没有登录或者登录失效,如果找到Session
证明用户已经登录可执行后面操作。 SessionID
是连接Cookie
和Session
的一道桥梁,大部分系统也是根据此原理来验证用户登录状态。
6.10 Cookie和Session的区别
安全性
:Session
比Cookie
安全,前者是存储在服务器端的,后者是存储在客户端的。存取值的类型不同
:Cookie
只支持缓存字符串数据,想要设置其他类的数据,需要将其转换成字符串,Session
可以存任意数据类型有效期不同
:Cookie
可设置为长时间保持,比如经常使用的默认登录功能,Session
一般失效时间较短,客户端关闭或者Session
超时都会失效存储大小不同
:单个Cookie
保存的数据不能超过4k
,Session
可存储数据远高于4k
,但是当访问量过多时,会占用过多的服务器资源。
内存泄漏
- 意外的全局变量,无法被回收
- 定时器:未被正确关闭,导致所引用的外部变量无法被释放
- 事件监听:没有正确销毁
- 闭包:会导致父级中的变量无法被释放
dom
引用:dom
元素被删除时,内存中的引用未被正确清空