zoukankan      html  css  js  c++  java
  • 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
    著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
  • 相关阅读:
    转Vtype扩展
    Can't connect to MySQL server on 'ip' (13)
    观察者+js 模式
    (转)ASP.NET架构分析
    sql得到时间
    Js+XML 操作 (转)
    js中的math对象
    property和attribute的区别
    CSS样式定义
    linux 开启 mount
  • 原文地址:https://www.cnblogs.com/susan-home/p/9117783.html
Copyright © 2011-2022 走看看