浏览器组成

# 浏览器组成

浏览器由一下几个部分组成:

  1. 用户界面(user interface) 用于呈现浏览器窗口部件 如:地址栏、前进后退、书签、顶部菜单等。
  2. 浏览器引擎(brower engine)用户在用户界面和渲染引擎之间传递指令,如点击了某个页面的某个按钮。
  3. 渲染引擎(rendering engine)负责解析HTML,CSS,并将解析的内容显式到屏幕上。(浏览器内核
  4. 网络(networking)用户网络调用,如 HTTP 请求
  5. 用户界面后端(UI backend)用于绘制基本的窗口小部件,如下拉列表,文本框,按钮等。向上提供公开的接口,向下调用操作系统的用户界面。
  6. JS 解释器(JavaScript interpreter)解释执行JS代码,JS引擎
  7. 数据存储(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值)

# 缓存读取规则

  1. 从 Service Worker中获取内容
  2. 查看 Memory Cache
  3. 查看 Disk Cache
    1. 强制缓存未失效,不请求服务器,且状态码 全是 200
    2. 强制缓存失效,使用协商缓存,比较后确定 304 还是 200
  4. 发送网络请求,等待网络响应
  5. 把响应那日容存入 Disk Cache(如果 Http 响应头有配置)
  6. 把响应内容的引用存入 Memory Cache (无视响应头信息)
  7. 把相应内容存入 Service Worker 的 Cache Storage (如果设置了 Service Worker)

# 浏览器行为

不同操作会触发不通的缓存读取策略

  • 打开网页,输入地址,查找 Disk Cache 中是否有匹配。有则用,没有就发送网络请求。
  • 普通刷新(F5):因为 TAB 没有关闭,因此 Memory Cache 是可用的,会被优先使用。其次才是 Disk Cache
  • 强制刷新(CTRL + F5):浏览器不适用缓存,因此发送的请求头均带有 Cache-Control:no-cache ,浏览器直接返回 200 和新内容。