浏览器组成
# 浏览器组成
浏览器由一下几个部分组成:
- 用户界面(user interface) 用于呈现浏览器窗口部件 如:地址栏、前进后退、书签、顶部菜单等。
- 浏览器引擎(brower engine)用户在用户界面和渲染引擎之间传递指令,如点击了某个页面的某个按钮。
- 渲染引擎(rendering engine)负责解析HTML,CSS,并将解析的内容显式到屏幕上。(浏览器内核)
- 网络(networking)用户网络调用,如 HTTP 请求
- 用户界面后端(UI backend)用于绘制基本的窗口小部件,如下拉列表,文本框,按钮等。向上提供公开的接口,向下调用操作系统的用户界面。
- JS 解释器(JavaScript interpreter)解释执行JS代码,JS引擎
- 数据存储(data storage)用户保存数据到磁盘中,如 cookie、localStorage等。
# 资源提示关键字
# defer 和 async
现代浏览器引入了 defer 和 async
都表示,js 不要阻塞 html 的解析,但是有部分不同 1、async async 表示的是下载 js 不会阻塞 DOM 树的构建,但是当执行 js 文件的时候,会阻塞 DOM 树的构建。
2、defer defer 表示下载 js 不会阻塞 DOM 树构建,等待 DOM 树构建完成才会执行 js
# preload
preload 预加载,它通过声明向浏览器声明一个需要提前加载的资源,当资源真正被使用的时候立即执行,就无需等待网络的消耗 使用 preload 需要 link 标签引入
<!-- 表示预加载 js 文件 -->
<link rel="preload" href="./1.js" as="script">
<!-- 表示预加载 css 文件 -->
<link rel="preload" href="./1.css" as="style">
优点:
- 允许浏览器设置资源优先级,从而允许 Web 开发人员优化某些资源的交付
- 使浏览器能够确定资源类型,因此它可以判断将来是否可以重用相同的资源
- 浏览器可以通过引用 as 属性中定义的内容来确定请求是否符合内容安全策略
- 浏览器可以根据资源类型发送何使的 Accept 头
# prefetch
prefetch 是一种利用浏览器的空闲时间加载非当前页面将来可能用到的资源,以便加快后续页面的首屏速度。
prefetch 加载的资源可以获取非当前页面所需资源,并将其放入缓存至少 5 分钟,当页面跳转时,未完成的 prefetch 请求不会被中断。
<!-- 表示预加载 js 文件 -->
<link rel="prefetch" href="./1.js" as="script">
<!-- 表示预加载 css 文件 -->
<link rel="prefetch" href="./1.css" as="style">
# DNS prefetch
DNS prefetch 允许浏览器在用户浏览时在后台对页面进行 DNS 查找,用户一旦点击链接就已经进行了 DNS 查找。
<link rel="dns-prefetch" href="//baidu.com">
# prerender
prerender 与 prefetch 很像,但是 prefetch 只是收集资源,当跳转到页面才会渲染, 而 prerender 是收集资源后,直接在后台渲染整个页面
<link rel="prerender" href="//baidu.com">
# preconnect
提前建立网络链接。
浏览器的缓存机制 也就是 http缓存机制,是根据 HTTP 报文的缓存标识进行的。
# 缓存位置
- service worker
- memory cache
- disk cache
- push cache
当依次查找缓存且都没有命中的时候,才会去请求网络
# Service Worker
Service Worker 是运行再浏览器背后的独立线程,一半可以用来实现缓存功能。
使用 Service Worker 必须使用 HTTPS 协议。
Service Worker的缓存与浏览器其他内建的缓存机制不同,它可以让我们自由控制缓存那些文件、如何匹配缓存、如何读取缓存,并且缓存是持续性的。
Service Worker缓存分为三步:
- 注册 Service Worker
- 监听到 install 事件后可以缓存需要的文件
- 下次用户访问可通过拦截请求的方式查询是否存在缓存,存在缓存直接读取文件,否则进行网络请求。
# Memory Cache
Memory Cache 即 内存中的缓存,。
内存缓存虽然读取高效,但是缓存的持续时间很短,会随着进程的释放而释放。(关闭tab页)
当我们访问国页面后,再次刷新页面,可以发现很多数据都来自于内存缓存。
但内存缓存,空间小,无法装太多东西。
内存缓存中有一块重要的缓存资源是 preloader 相关指令。
需要注意的是,内存缓存在缓存资源时并不关心返回资源的 HTTP 缓存 头 Cache-Control 是什么值,同时资源匹配也并非仅仅是对 URL 进行匹配,还可能回对 Content-Type,CORS 等其他特征做校验。
# Disk Cache
Disk Cache 存储在硬盘中的缓存,读取速度慢,但是容量大,且存储失效长。
Disk Cache 覆盖面基本是最大的,他会根据 HTTP Header 中的字段判断哪些资源需要缓存,哪些资源可以不请求,直接使用,哪些资源已经过期需要重新请求。并且,相同地址的资源一旦被硬盘缓存下来,就不会再次去请求数据。
对于大文件来说,大概率是不存储在内存中的,反之优先。
当前系统内存使用率高的话,文件优先存储进硬盘。
# Push Cache
Push Cache 是 HTTP/2中的内容,当以上三种缓存都没有命中,才会被使用。
Push Cache 只在会话中(session)存在,一旦会话结束,就被释放,且缓存时间短。
# 缓存类型
- 强制缓存
- 协商缓存
这两种类型都属于 disk cache 或者 http cache 里面的一种
# 强制缓存
当客户端请求后,会优先访问缓存数据库看缓存是否存在,如果存在,则直接返回,不存在则请求真的服务器,响应后再写入缓存。
产生强制缓存:Cache-Control 和 Expires
# 协商缓存
强制缓存到期后会发送一个带有缓存标识的请求,如果没有改变,则服务器认为可以继续使用,则返回 状态码 304 ,如果文件内容有改动,那么服务器将返回新的内容,浏览器再继续将响应内容进行缓存。 (Etag 是一个hash值)
# 缓存读取规则
- 从 Service Worker中获取内容
- 查看 Memory Cache
- 查看 Disk Cache
- 强制缓存未失效,不请求服务器,且状态码 全是 200
- 强制缓存失效,使用协商缓存,比较后确定 304 还是 200
- 发送网络请求,等待网络响应
- 把响应那日容存入 Disk Cache(如果 Http 响应头有配置)
- 把响应内容的引用存入 Memory Cache (无视响应头信息)
- 把相应内容存入 Service Worker 的 Cache Storage (如果设置了 Service Worker)
# 浏览器行为
不同操作会触发不通的缓存读取策略
- 打开网页,输入地址,查找 Disk Cache 中是否有匹配。有则用,没有就发送网络请求。
- 普通刷新(F5):因为 TAB 没有关闭,因此 Memory Cache 是可用的,会被优先使用。其次才是 Disk Cache
- 强制刷新(CTRL + F5):浏览器不适用缓存,因此发送的请求头均带有 Cache-Control:no-cache ,浏览器直接返回 200 和新内容。