webkit的主资源与派生资源

我们使用浏览器上网时,首先会在地址栏输入一个网址,浏览器会依据网址向服务器发送资源请求,服务器解析请求,并将相关数据资源传回给浏览器,这些数据资源包括Page的描述文档、图片、Javascript脚本、CSS等。此后,浏览器引擎会对数据进行解码、解析、排版、绘制等操作,最终呈现出完整的页面。

前端性能优化中,减少HTTP请求可以提高页面的响应速度。

浏览器在第一次访问页面时向服务器请求资源,并缓存起来,下次再访问时会判断在缓存中是否已有该资源且有没有更新过,如果已有该资源且未更新过,则直接从浏览器缓存中读取。原理:通过HTTP 请求头中的 If-Modified-Since(If-No-Match) 和响应头中的Last-Modified(ETag)来实现,HTTP请求把 If-Modified-Since(If-No-Match)传给服务器,服务器将其与Last-Modified(ETag)对比,若相同,则文件没有被改动过,则返回304,直接浏览器缓存中读取资源即可。

问题:虽然该方法减少了已缓存资源的下载时间,但仍然发起了一次http请求。

解决:已缓存资源不再发起http请求,即HTTP的Expires和Cache-Control。对一个网站而言,CSS、JavaScript、图片等静态资源更新的频率都比较低,而这些文件又几乎是每次HTTP请求都需要的,如果将这些文件缓存在浏览器中,可以极好的改善性能。通过设置http头中的cache-control和expires的属性,可设定浏览器缓存,将静态内容设为永不过期,或者很长时间后才过期。

 

1、Cache-Control

Cache-Control属性是在服务器端配置的,不同的服务器有不同的配置,apache、nginx、IIS、tomcat等配置都不尽相同。

以Apache为例,在http.conf中做如下配置:

 

[plain] view plain copy
 
  1. <filesMatch ”.(jpg|jpeg|png|gif|ico)$”>  
  2.     Header set Cache Control max-age=16768000,public  
  3. </filesMatch>  
  4. <filesMatch ”.(css|js)$”>  
  5.     Header set Cache Control max-age=2628000,public  
  6. </filesMatch>  

问题:浏览器缓存的资源,若又想更新资源,如何实现?

解决:通过修改该资源的名称来实现。修改了资源名称,浏览器会当做不同的资源。

 

2、Expires

Expires属性也是在服务端配置的,具体的配置也根据服务器而定。

问题:可能存在客户端时间跟服务端时间不一致的问题。

解决:建议Expires结合Cache-Control一起使用。

 

3、测试实例:

1) 未使用expires和cache-control的测试demo:

打开网址:http://stevesouders.com/hpws/expiresoff.php (发送请求了,返回的是304)

2) 使用expires和cache-control的测试demo:

打开网址:http://stevesouders.com/hpws/expireson.php(连请求都没有发送)

在过去,Webkit资源分成两类,一类是主资源,比如HTML页面,或者下载项,一类是派生资源,比如HTML页面中内嵌的图片或者脚本、样式表链接,分别对应代码中两个类:MainResourceLoader和SubresourceLoader。这两类资源的加载过程颇有不同,比如对资源加载失败的处理,主资源下载失败会有报错提示,而派生资源如图片下载失败,往往只显示一个占位符。所以网络加载模块分别设计了MainResourceLoader和SubresourceLoader来处理它们。它们的公共基类ResourceLoader主要完成两种资源加载都需要进行的操作,如在资源加载过程中,反馈加载状态的回调等。

WebCore 把要加载的资源分成两类,一类是主资源,比如 HTML 页面,或者下载项,一类是派生资源,比如 HTML 页面中内嵌的图片或者脚本链接。这两类资源对于回调的处理有很大的不同,比如,同样是下载失败,主资源可能需要向用户报错,派生资源比如页面中的一张图下载失败,可能就是图不显示或者显示代替说明文字而已,不向用户报错。因此有了 MainResourceLoader 和 SubresourceLoader 之分。

WebCore 把要加载的资源分成两类,一类是主资源,比如 HTML 页面,或者下载项,一类是派生资源,比如 HTML 页面中内嵌的图片或者脚本链接。这两类资源对于回调的处理有很大的不同,比如,同样是下载失败,主资源可能需要向用户报错,派生资源比如页面中的一张图下载失败,可能就是图不显示或者显示代替说明文字而已,不向用户报错。因此有了 MainResourceLoader  SubresourceLoader 之分。它们的公共基类 ResourceLoader 则完成一些两种资源下载都需要完成的操作,比如通过回调将加载进程告知上层应用。

主资源的加载是立刻发起的,而派生资源则可能会为了优化网络,在队列中等待( 这里的立刻发起是 loader 层面的,不是 Network 层面的 )  ResourceScheduler 这个类就是用来管理资源加载的调度。主要调度对象就是派生资源,会根据 host 来影响资源加载的先后顺序。

主资源和派生资源的加载还有一个区别,主资源目前是没有缓存的,而派生资源是有缓存机制的。这里的缓存指的是 Resouce Cache ,用于保存原始数据(比如CSS  JS 等),以及解码过的图片数据,通过 Resource Cache 可以节省网络请求和图片解码的时候。不同于 Page Cache  Page Cache 存的是 DOM 树和 Render 树的数据结构,用来在前进后退的时候快速显示页面。

注:自从WebKit有了PageCache(主资源也可以缓存)的功能以后。WebKit资源加载已经不区分MainResourceLoader和SubresourceLoader,统一由CachedResourceLoader加载资源,而区分主资源和派生资源则是通过CachedResource类里面Type类型:

enum Type {

MainResource,

ImageResource,

CSSStyleSheet,

Script,

FontResource,

RawResource

};

可以看到加载主资源的时候,Type类型就为MainResource。由于目前我们使用的WebKit代码已经使用了比较新的代码,所以本章后面介绍的流程都与过去的流程不一样了。

正如概述所说,比较新的WebKit代码主资源已经加入了缓存机制,所以统一由CachedResourceLoader加载资源。

WebKit派生资源包含的类型主要如下:

Javascript脚本(CachedScript);

CSS样式文本(CachedCSSStyleSheet);

图片(CachedImage);

字体(CachedFont);

XSL样式表(CachedXSLStyleSheet);

可以说除了主资源剩下的网络资源都是派生资源。派生资源的WebKit中都有对应的类实现,它们有着共同的基类(CachedResource),下面是类图:

WebKit在加载主资源后,主资源会被解码,然后进行解析,生成DOM树。在解析的过程中,如果遇到派生资源的标签,会创建相应的HTMLElement类。

 

今天在做项目的优化的时候,使用chrome开发者工具的network发现了细节:

image

虽然这两个看起来都是从缓存中读取,但还是有一些不一样的!

webkit资源的分类

webkit的资源分类主要分为两大类:主资源和派生资源

http状态码

200 from memory cache

不访问服务器,直接读缓存,从内存中读取缓存。此时的数据时缓存到内存中的,当kill进程后,也就是浏览器关闭以后,数据将不存在。

但是这种方式只能缓存派生资源。

200 from disk cache

不访问服务器,直接读缓存,从磁盘中读取缓存,当kill进程时,数据还是存在。

这种方式也只能缓存派生资源

304 Not Modified

访问服务器,发现数据没有
更新,服务器返回此状态码。然后从缓存中读取数据。

但是这里有困惑,怎么判断from memory cache还是304

三级缓存原理

  1. 先去内存看,如果有,直接加载
  2. 如果内存没有,择取硬盘获取,如果有直接加载
  3. 如果硬盘也没有,那么就进行网络请求
  4. 加载到的资源缓存到硬盘和内存

所以我们可以来解释这个现象

图片为例:

访问-> 200 -> 退出浏览器
再进来-> 200(from disk cache) -> 刷新 -> 200(from memory cache)

http header

max-age

web中的文件被用户访问(请求)后的存活时间,是个相对的值,相对Request_time(请求时间)

Expires

Expires指定的时间根据服务器配置可能有两种:

  1. 文件最后访问时间
  2. 文件绝对修改时间

如果max-age和Expires同时存在,则被Cache-Control的max-age覆盖

last-modified

WEB 服务器认为对象的最后修改时间,比如文件的最后修改时间,动态页面的最后产生时间

ETag

对象(比如URL)的标志值,就一个对象而言,文件被修改,Etag也会修改

Cache-Control

简单理解,强缓存

最后结论

见图片(来源自网络)
image

cache control:max-age=0 表示 需要向服务器端发送请求,provisional headers are shown 表示向服务器的请求被浏览器拦截了,并没有发送请求

链接:https://www.jianshu.com/p/444f3b7fcc63
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
posted @ 2018-05-31 17:36  姗崽崽崽  阅读(648)  评论(0编辑  收藏  举报