浏览器加载网页资源的原理

  1、HTML支持的组要资源类型
  
  在浏览器内核有一个管理资源的对象CachedResource类,在CachedResource类下有很多子类来分工不同的资源管理,这些资源管理子类分别是:
  
  资源     资源管理类
  
  HTML     MainResource ===> CachedRawResource
  
  JavaScript     CachedScript
  
  CSS     CachedCSStyleSheet
  
  图片     CachedImage
  
  SVG     CachedSVGDocument
  
  CSS Shader     CachedShader
  
  视频、音频、字幕     CachedTextTrack
  
  字体文件     CachedFont
  
  XSL样式表     CachedXSLStyleSheet
  
  2、资源缓存
  
  资源的缓存机制是提高资源使用效率的有效方法。基本思想就是建立一个资源缓存池,当web需要请求资源时,会先从资源池中查找是否存在相应的资源,如果有的话就直接取缓存,如果没有就创建一个新的CachedResource子类的对象,并发送请求给服务器(由网络模块完成),请求回来的资源会被添加到资源池,并且将资源(数据信息:比如在资源池中的物理地址)设置到该资源的对象中去,以便下次使用。
  
  下面是一个缩减版的资源请求原理图:
  
  实质上的操作是在资源对象中找到对应资源的物理地址(url),然后返回给渲染引擎,渲染引擎在渲染页面时根据url获取物理内存中的资源数据。由于资源的唯一特性是url,所以当两个资源有不同的url,但是他们的内容完全相同时,也不会被认定是同一个资源。
  
  注:这里所说的缓存是内存,不是磁盘。
  
  3、资源加载器
  
  在WebKit中共有三种类型的资源加载器,分别是:
  
  3.1针对每种资源类型的特定加载器,用来加载某一类资源。例如“image”这个元素,该元素需要图片资源,对应的顶资源加载器是ImageLoader类。
  
  3.2资源缓存机制的资源加载器,特点是所有特定加载器都共享它来查找并插入缓存资源——CachedResourceLoader类。特定加载器是通过缓存机制的资源加载器来查找是否有缓存资源,它属于HTML的文档对象。
  
  3.3通用的资源加载器——ResourceLoader类,是在WebKit需要从网络或者文件系统获取资源的时候使用该类只负责获得资源的数据,因此被所有特定资源加载器所共享,它属于CachedResource类,与CachedResourceLoader类没有继承关系。
  
  如果说资源缓存和网络资源是浏览器要渲染页面的资源实体,那资源加载器就是为浏览器实现页面渲染提供资源数据的搬运工。前面的资源请求相当于就是资源地址寻址的过程,真正为渲染提供资源的过程是下面这样的:
  
  这个资源加载看起来很复杂,但是模块分工很明确,基于资源对象与内存资源缓存的对应关系(每个缓存资源在资源对象上有一个实例),当浏览器触发资源请求时先通过判断资源是否有缓存资源,如果有的话就就直接拿缓存资源给渲染引擎,如果没有就通过网络请求获取资源给渲染引擎,并且同时会将资源缓存到内存中。
  
  同CachedResourceLoader对象一样,资源池也属于HTML文档对象,所以资源池不能无限大,对于资源容量不能无限大的问题浏览器的解决方法有两种:第一种是采用LRU(Least Recent Rsed最近最少使用原则)算法。第二种方法是通过HTTP协议决定是否缓存,缓存多久,以及什么时候更新缓存,然后我们开发时还可决定资源如何拆分,拆分可以让我决定哪些资源缓存,哪些资源不缓存。
  
  当请求协议指定可以取缓存数据,请求资源会先判断内存中是否有资源,然后将资源的信息(版本,缓存时常等)通过HTTP报文一起发送给服务器,服务器通过报文判断缓存的资源是否是最新的,资源缓存是否超时来决定是否重新获取服务端的资源,如果不需要重新获取服务端的资源,服务器会返回状态码304,告诉浏览器取本地缓存资源。
  
  下面通过Chrome浏览器来请求饿了吗官网,在控制台查看数据请求的资源加载过程,并且通过刷新页面查看当页面刷新时浏览器在缓存中取了哪些信息:
  
  接着我们再来刷新页面看看取了哪些缓存数据:
  
  可以看到饿了吗官网的缓存机制是将document主文件和js文件做了缓存处理。这样的处理方式可以很大程度上提高页面性能和降低服务器请求压力,至于为什么就是接下来的内容了。
  
  二、解析HTML标签和CSS样式表、生成DOMTree和CSSTree
  
  前面介绍了浏览器资源请求与资源加载的基本原理,看上去好像是一个简单的线性步骤,但是实质上浏览器内部是多进程异步加载这些资源的,我们知道网页的效果是基于DOM结构和CSS样式表来完成基本的页面效果呈现,但是JS代码又可以对DOM节点进行增删该查操作,还可以修改DOM的CSS样式,那必然就是需要先有DOM结构,然后添加CSS样式,再就这两个资源的基础通过JS修改后才能呈现出来,但是什么时候加载(指的是下载资源,并不是前面的资源加载到页面上的整个过程)?什么时候执行?什么时候渲染页面?按照什么规则来完成这些工作呢。
  
  通常我们给某个服务器发送一个web请求时,首先返回的是一个HTML资源。假设这个资源的内部代码如下:
  
  复制代码
  
  <!DOCTYPE html>
  
  <html>
  
  <head>
  
  <meta charset="utf-8">
  
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  
  <title></title>
  
  <link rel="stylesheet" type="text/css" href=".../css/xxx.css">
  
  </head>
  
  <body>
  
  <div>
  
  <p>
  
  <span></span>
  
  </p>
  
  <ul>
  
  <li><img src=".../image/xxx.png" alt=""></li>
  
  <li><img src=".../image/xxx.png" alt=""></li>
  
  <li><img src=".../image/xxx.png" alt=""></li>
  
  </ul>
  
  </div>
  
  <script src=".../javascripts/xxx.js" type="text/javascript"></script>
  
  </body>
  
  </html>

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值