WebKit资源加载机制
1. 资源
HTML支持的类型主要包括:HTML、JavaScript、CSS样式表、图片、SVG、CSS Shader、视频音频和字幕、字体类型和XSL样式表。
资源类型前面加“Cached”字样,其实这是因为效率问题而引入的缓存机制,所有对资源的额请求都会先获取缓存中的信息,以决定是否向服务器提出资源请求。
2. 资源缓存
资源的缓存机制是提高资源使用效率的有效方法。它的基本思想是建立一个资源的缓冲池,当WebKit需要请求资源的时候,先从资源池中查找是否存在相应的资源。如果有,WebKit则取出使用,如果没有,WebKit创建一个新的CachedResource子类的对象,并发送真正的请求给服务器,WebKit收到资源之后将其设置到该资源类的对象中去,以便于缓存后下次使用。这里缓存指的是内存缓存。
WebKit从资源池中查找资源的关键字是URL
3. 资源加载器
资源加载器分为三种:
- 针对每种资源类型的特定加载器,特点是仅加载某一特定类型资源。
- 资源缓存机制的资源加载器,特点是所有特定加载器都共享它来查找并插入缓存资源。
- 通用的资源加载器,是在WebKit需要从网络或者文件系统获取资源的时候使用,该类只负责数据的获取,被特定加载器共享。
4. 过程
因为从网络获取资源是一个非常耗时的过程,通常一些资源的加载是异步执行的,也就是说资源的获取和加载不会阻碍当前WebKit的渲染过程,例如:图片、CSS文件。但是也存在阻碍主线程的渲染过程的资源,例如:JavaScript代码文件。
因为主线程被阻碍了,后面的解析工作没办法继续往下进行,所以对于HTML网页中后面使用的资源也没办法知道并发送下载请求。这时,WebKit会启动另外一个线程去遍历后面的HTML网页,收集需要的资源URL,然后发送请求,这样可以避免被阻碍。
5. 资源的生命周期
资源池中的资源声明周期是什么呢?资源池不能无限大,必须要使用相应的机制来替换其中的资源,从而加入新的资源。它采用的是LRU(Least Recent Used最近最少使用)算法。
WebKit的做法是,首先判断资源是否在资源池中,如果是,那么发送一个HTTP请求给服务器,说明该资源在本地的一些信息,例如该资源什么时间修改的,服务器则根据该信息作判断,如果没有更新,服务器则发送回状态码304,表明无需更新,那么直接利用资源池中原来的资源;否则,WebKit申请下载最新的资源内容。
网络栈
1. 代理
2. 域名解析(DNS)
一般在建立TCP连接之前要解析域名,为了考虑效率,使用HostCache类来保存解析后的域名,最多时会有多达1000个的域名和地址映射关系会被存储起来。
如果想要了解当前域名解析详情和HostCache中的信息,可以通过在Chrome浏览器的地址栏中输入chrome://net-internals/#dns来查看。
3. 磁盘本地缓存
可以通过在地址栏输入chrome://view-http-cache/来查看这些项。
4. Cookie机制
根据Cookie的时效性可以将Cookie分成两种类型:
- 第一种是会话型Cookie(Session Cookie),这些Cookie只是保存在内存中,当浏览器退出的时候即清除这些Cookie。
- 第二种是持续型Cookie(Persistent Cookie),也就是当浏览器退出的时候,仍然保留Cookie的内容。该类型的Cookie有一个有效期,在有效期内,每次访问该Cookie所属域的时候,都需要将该Cookie发送给服务器,这样服务器能够有效追踪用户的行为。
5. 安全机制
HTTP是一种使用明文来传输数据的应用层协议。构建在SSL之上的HTTPS提供了安全的网络传输机制,现已被广泛应用在网络上。
6. 高性能网络栈
Chromium 的网络模块有两个重要的目标,其一就是安全,其二就是速度。
- DNS预取和TCP预取连接(Preconnect)
- 一次DNS查询的平均时间大概是60~120ms之间或者更长,而TCP的三次握手时间大概也是几十毫秒或者更长。Chromium采用DNS预取和TCP预连接。
- 可以显示指定预取哪些域名来让Chromium解析,具体做法如下:<link rel="dns-prefetch" href="http://this-is-a-dns-preftch-example.com">
- 还有在用户地址中输入地址后,候选项同输入的地址很匹配的时候,在用户桥下回车键获取该网页之前,Chromium已经开始使用DNS预取技术解释该域名了。
- 可以在地址栏输入chrome://dns/查看Chromium的DNS预取的域名。
- HTTP管线化(Pipelining)
- HTTP管线化技术是一项同时将多个HTTP请求一次性提交给服务器的技术,因此无需等待服务器的回复,因为它可能将多个HTTP请求填充在一个TCP数据包内。
- 管线化需要通过永久连接(Persistent Connection)完成,并且只有GET和HEAD等请求可以进行管线化,使用场景有很大的限制。
- SPDY
SPDY就是为了解决网络延迟和安全性问题。根据Google的官方数据,使用SPDY协议的服务器和客户端可以将网络加载的时间减少64%,在HTTP2.0的草案中将引入SPDY协议,将其作为基础来编写。
SPDY所处的层次.png
7. 高效的资源使用策略
- DNS和TCP连接
- 减少链接的重定向
- 利用DNS预取机制
- 搭建支持SPDY协议的服务器
- 避免错误的链接请求
- 资源的数量
- 在HTML网页中内嵌小型的资源,也就是当资源比较小的时候,开发者可以将它们直接放在网页中,可能的资源如CSS、JavaScript和图片等。
- 合并一些资源,例如CSS、JavaScript和图片。
- 资源的数据量
- 使用浏览器本地磁盘缓存机制。
- 启用资源的压缩技术,比如图片资源,可以使用zip压缩技术,然后在HTTP消息头中说明该资源经过压缩。