一些准备css
在开始这个话题以前,咱们有必要简单回顾一下 浏览器(webkit)的网页渲染过程(若是想要详细了解这个过程,能够戳我几年前写的一篇文章。):html
咱们知道,浏览器在渲染过程当中,如遇到节点须要依赖其余资源(好比:图片、CSS、JavaScript、video等),浏览器会经过网络去加载它们。这其中大部分的资源是异步加载的,不会阻塞渲染,除了 JavaScript(未被标记为异步的方式)。web
网页的加载和渲染依赖网络与资源加载,网页自己是一种资源,它所依赖的 js、css、图片、视频等也是资源。而资源的加载涉及网络和资源的缓存等机制,并且它们充斥着整个渲染过程。算法
1、资源chrome
HTML 中支持的资源主要包括如下类型:浏览器
在 webkit 内部,会使用不一样的类去表示它们,其对应关系:缓存
资源类型 | 内部表示类 |
HTML | CachedRawResource |
JavaScript | CachedScript |
CSS 样式表 | CachedCSSStyleSheet |
CSS Shader | CachedShader |
图片 | CachedImage |
SVG | CachedSVGDocument |
字幕 | CachedTextTrack |
字体文件 | CachedFont |
XSL 样式表 | CachedXSLStyleSheet |
以上内部表示类均继承自 CachedResource 类。 聪明的你必定发现了, 这些类名都是以 “Cached” 开头,这实际上是考虑到效率问题二引入的缓存机制。全部对资源的请求都会先获取缓存中的信息,以决定是否向服务器发起资源请求。服务器
2、资源缓存 网络
资源的缓存机制是提升资源使用效率的有效方法。在 webkit 内部,它的基本思想是创建一个资源的缓存池(内存缓存),当须要请求资源时,会先从资源池中查找是否存在响应的资源。若是存在,则直接使用缓存池中的资源。若是不存在,则发送真正的请求加载资源,收到响应的资源后,webkit 会将其设置到上面提的到资源类中去。异步
这些资源,在 webkit 内部是以 URL 做为 key 去查找的。由于 URL 是标记资源的惟一性的特征。
3、资源加载器
webkit 总共有 3 种资源加载器:
以 ImageLoader 这个特定资源加载器为例,大体可用下图描述:
结合 chrome 浏览器调试工具,以访问百度首页为例,来观察百度 logo 的请求状况。为防止以前的缓存,采用 “清除缓存并硬性从新加载” 方式访问。表现以下:
再正常不过的 200, 没有 from * cache 标识意味着来源于网络。新开 tab, 再次访问百度首页:
发如今 size 列(倒数第二列)多了 “(from disk cache)” 字样。在此基础上(不关闭 tab),正常刷新该页面:
聪明的你必定发现 了原来 size 列的 “from disk cache” 变为了 “from memory cache”。顾名思义,两张图片的加载方式由从 磁盘缓存读取 变为了 从内存缓存读取。摘一段官网上的文档(文档地址):
简单翻译:Chrome 使用两种缓存:磁盘缓存和高速的内存缓存。内存缓存(memory cache)依附于渲染进程,咱们能够大体认为一个渲染进程就等于一个 tab。
所以,“from memory cache” 只有在正常刷新的状况下,才会命中。这也解释了前面示例中新打开的 tab 访问百度首页,获得的是 “from disk cache”。
4、过程
通过前面的介绍,咱们创建起了对 资源、资源缓存、资源加载器 的认知。接下来详细聊聊资源的加载过程。仍是以图片加载为例:
咱们都知道,在网页加载时,如遇到 script 标签(未声明异步),会阻塞渲染。在这种状况下,webkit 会启动另一个去遍历后面的 HTML 网页,收集须要的资源的 URL,而后发送请求,以此来避免阻塞。
回到资源缓存的话题,前面提到,在 webkit 内部是存在一个 “缓存池” 。为了保证在有限空间的缓存池内可以持续的插入新的缓存,它使用 LRU 算法来管理缓存。