浏览器简介
目前的主流浏览器有五个:IE、Firefox、Safari、Chrome 和 Opera
浏览器的主要功能是向服务器发出请求,然后在浏览器窗口中呈现返回的资源
浏览器的主要组件有:
- 用户界面
- 浏览器引擎
- 渲染引擎
- 网络
- UI 后端
- JavaScript 解释器
- 数据存储
进程与线程
- 进程:资源(CPU、内存)分配的最小单位
- 线程:是在进程内部的程序运行单位
每打开一个新的标签页就新建了一个进程(如果后期标签页过多可能会合并进程)
浏览器中的主要进程
浏览器进程、第三方插件进程、GPU 进程、渲染进程
- 多进程的优点:某一页面进程出问题不会影响其他页面,避免不同页面的权限问题,以及第三方插件的问题
- 多进程的缺点:内存消耗大,不同进程中常常包含相同内容
死锁
在多个进程执行过程中因资源争夺而造成的僵持状态,此时若没有干预这些线程就都将无法向前推进。
-
产生死锁的必要条件
- 互斥条件:进程要求对所分配的资源进行排它性控制
- 请求和保持条件:当进程因请求资源而阻塞时,对已经获得的资源保持不放
- 不剥夺条件:进程已获得的资源在未使用完之前,不能剥夺,只能在使用完时由自己释放
- 环路等待条件:在发生死锁时,必然存在一个进程-资源的环形链
-
解决死锁的方法
-
预防死锁
- 一次性分配所有资源,这样就不会再请求资源了
- 如果某进程获得了部分资源,但得不到剩下的资源,则释放已有资源(超时放弃)
- 给资源编号,有序分配
-
避免死锁
- 在进行资源分配前先计算安全性,若安全才进行分配,否则进程等待
- 银行家算法
-
解除死锁
- 从其他进程中剥夺资源给死锁进程,以解除死锁状态
- 直接撤销死锁进程,或撤销代价最小的进程直到资源足够接触死锁进程为止
-
渲染进程(浏览器内核)
渲染进程也就是我们说的浏览器内核
GUI 渲染线程
作用:负责渲染页面
渲染流程
- 构建 DOM :根据 HTML 渲染 DOM(同一个 HTML 文件得到的DOM 树并不总是一样,浏览器会按照自己的规范来构建)
- 加载次级资源:请求下载图片,CSS,JS 等资源
- JS 的下载与执行:<script>
- 样式计算:基于 CSS 选择器解析 CSS 计算每个节点的具体样式值
- 获取布局:遍历 DOM 以及相关元素的计算样式,构建出布局树
- 绘制各元素:遍历布局树,创建绘制记录
- 合成帧:遍历布局树,创建层树,合成器将每一层栅格化然后合成帧(合成器是独立工作的,与主线程无关,非常流畅)
JS 引擎线程
作用:负责解析执行 JS 脚本
JS 引擎线程是单线程,容易引发的阻塞问题, HTML5 提出了 Web Worker 解决此问题,允许主线程创建 Worker 线程,将一些任务分配给该线程在后台运行。JS 引擎线程与 Worker 线程之间通过 postMessage API 进行通信
JS 引擎线程与 GUI 渲染线程互斥,无法同时进行,因为 JS 也可以操作 DOM,会影响渲染结果
事件触发线程
作用:控制事件循环
事件循环
同步任务直接放入 JS 引擎线程中的执行栈中处理,异步任务放入事件触发线程中的事件队列中等待。
当 JS 引擎线程上的执行栈为空时,JS 引擎线程会询问事件触发线程,如果事件队列中有异步任务,就会被添加到执行栈中开始执行。
定时触发器线程
作用:执行 setInterval 与 setTimesout,计时完毕后通知事件触发线程
异步http请求线程
作用:在 XMLHttpRequest 连接后通过浏览器新开一个线程请求。当检测到状态变更时,如果设置有回调函数,异步线程就会产生状态变更事件,将回调放入事件队列中,再由 JS 引擎执行。
浏览器缓存
浏览器会把通过 HTTP 获取的所有资源保存到本地
缓存位置
Service Worker:
内存缓存 memory cache | 硬盘缓存 disk cache |
---|---|
读取速度快 | 读取速度慢 |
退出进程时数据会被清除 | 退出进程时数据不会被清除 |
通常 memory cache 保存 JS、字体、图片等文件,disk cache 保存 CSS 文件
访问缓存优先级
- 在内存中查找
- 在硬盘中查找
- 进行网络请求
- 把获取的资源缓存到本地
强制缓存 和 协商缓存
浏览器在请求某一资源时,会先获取该资源缓存的 header 信息,判断是否命中强缓存,若命中则直接从缓存中获取资源信息,不会与服务器进行通信。若没有命中强缓存,浏览器会向服务器发送携带之前获取到的有关缓存的 header 信息,服务器对比相关 header 信息看是否命中协商缓存,若命中则服务器返回新的响应 header 信息更新缓存中对应的 header 信息,告知浏览器可以直接从缓存中获取资源信息,若没有命中协商缓存,则会直接返回最新的资源内容
HTTP 报文中的缓存相关字段
-
Cache-Control
http 1.1 出现的 header 字段,可以定义资源什么时候被缓存、如何被缓存以及缓存多长时间等
-
Last-Modify
标识资源的最后修改时间,浏览器第一次请求一个资源的时候,服务器返回的 header 中会加上 Last-Modify。当浏览器再次请求该资源时,服务器会根据资源的最后修改时间判断是否命中缓存。如果命中缓存,则返回 304,并且不会返回资源内容,如果未命中,返回 200 和新的资源,并带上新的修改时间 Last-Modify。
缺点:短时间内如果资源发生变化,Last-Modified 并不会变化,可以用 Etag 处理
-
Etag
服务器针对资源计算出一串校验码,通过 Etag 返回给客户端,客户端下次请求时带上该值,服务器对比校验,如果相同则返回 304,不返回资源,不一致则返回 412 和新的资源。
参考资料
最后修改于 2021-10-02