一些准备

在开始这个话题之前,我们有必要简单回顾一下 浏览器(webkit)的网页渲染过程(如果想要详细了解这个过程,可以戳我几年前写的一篇文章。):

我们知道,浏览器在渲染过程中,如遇到节点需要依赖其他资源(比如:图片、CSS、JavaScript、video等),浏览器会通过网络去加载它们。这其中大部分的资源是异步加载的,不会阻塞渲染,除了 JavaScript(未被标记为异步的方式)。

网页的加载和渲染依赖网络与资源加载,网页本身是一种资源,它所依赖的 js、css、图片、视频等也是资源。而资源的加载涉及网络和资源的缓存等机制,而且它们充斥着整个渲染过程。

一、资源

HTML 中支持的资源主要包括以下类型:

  • HTML:HTML 页面,包括各种各样的 HTML 元素
  • JavaScript:JavaScript 代码,可以内嵌在 HTML 文件中,也能以单独的文件存在
  • CSS 样式表:CSS 样式资源,可内嵌在 HTML 文件中,也可以单独的单独文件形式存在
  • CSS Shader
  • 图片:各种编码格式的图片资源
  • SVG:用于绘制 SVG 的 2D 矢量图形表示
  • 视频、音频和字幕:多媒体资源和支持音视频的字幕文件(TextTrack)
  • 字体文件:CSS3 引入的自定义字体文件
  • XSL 样式表:使用 XSLT 语言编写的 XSLT 代码文件

在 webkit 内部,会使用不同的类去表示它们,其对应关系:

资源类型 内部表示类
HTML CachedRawResource
JavaScript CachedScript
CSS 样式表 CachedCSSStyleSheet
CSS Shader CachedShader
图片 CachedImage
SVG CachedSVGDocument
字幕 CachedTextTrack
字体文件 CachedFont
XSL 样式表 CachedXSLStyleSheet

以上内部表示类均继承自 CachedResource 类。 聪明的你一定发现了, 这些类名都是以 “Cached” 开头,这其实是考虑到效率问题二引入的缓存机制。所有对资源的请求都会先获取缓存中的信息,以决定是否向服务器发起资源请求。

二、资源缓存 

资源的缓存机制是提高资源使用效率的有效方法。在 webkit 内部,它的基本思想是建立一个资源的缓存池(内存缓存),当需要请求资源时,会先从资源池中查找是否存在响应的资源。如果存在,则直接使用缓存池中的资源。如果不存在,则发送真正的请求加载资源,收到响应的资源后,webkit 会将其设置到上面提的到资源类中去。

这些资源,在 webkit 内部是以 URL 作为 key 去查找的。因为 URL 是标记资源的唯一性的特征。

三、资源加载器

webkit 总共有 3 种资源加载器:

  • 针对每种资源类型的特定加载器,该类资源加载器只加载某一种资源。其内部表示有:ImageLoader、FontLoader 等
  • 资源缓存机制的资源加载器,特定资源加载器都共享它来插入和查找缓存资源。其内部表示为:CachedResourceLoader
  • 通用资源加载器,当浏览器需要从文件系统或网络加载资源时,会使用该类加载器,但它只负责获取资源的数据,正因为如此,它也被所有的特定资源加载器所共享。其内部表示为:ResourceLoader

以 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”。

四、过程

经过前面的介绍,我们建立起了对 资源、资源缓存、资源加载器 的认知。接下来详细聊聊资源的加载过程。还是以图片加载为例:

我们都知道,在网页加载时,如遇到 script 标签(未声明异步),会阻塞渲染。在这种情况下,webkit 会启动另外一个去遍历后面的 HTML 网页,收集需要的资源的 URL,然后发送请求,以此来避免阻塞。

回到资源缓存的话题,前面提到,在 webkit 内部是存在一个 “缓存池” 。为了保证在有限空间的缓存池内能够持续的插入新的缓存,它使用 LRU 算法来管理缓存。

聊聊浏览器(webkit)资源加载机制的更多相关文章

  1. WebKit资源加载和网络栈

    webkit笔记,主要来自 朱永盛 <WebKit技术内幕> 学习笔记,转载就注明原著,该书是国内仅有的Webkit内核的书籍,学习的好导师,推荐有兴趣的朋友可以购买 WebKit资源加载 ...

  2. 理解WebKit和Chromium: Chromium的多进程资源加载机制

    转载请注明原文地址:http://blog.csdn.net/milado_nju ##概述 前面介绍了WebKit中的资源加载机制,其实它只是一个框架性的东西,实际的资源加载依赖于各个WebKit移 ...

  3. 插件化框架解读之Android 资源加载机制详解(二)

    阿里P7移动互联网架构师进阶视频(每日更新中)免费学习请点击:https://space.bilibili.com/474380680Android提供了一种非常灵活的资源系统,可以根据不同的条件提供 ...

  4. Webkit之资源加载

    一.webkit资源分类 webkit中有多种资源,大致分为以下几种: HTML文本 CSS样式文本 - CachedCSSStyleSheet 字体 - CachedFont 图片 - Cached ...

  5. Chromium多进程资源加载

    webkit笔记,主要来自 朱永盛 <WebKit技术内幕> 学习笔记,转载就注明原著,该书是国内仅有的Webkit内核的书籍,学习的好导师,推荐有兴趣的朋友可以购买 多进程 资源的实际加 ...

  6. spring资源访问接口和资源加载接口

    spring 资源访问接口 JDK提供的资源访问类,如java.net.URL.File等,不能很好地满足各种资源的访问需求,比如缺少从类路径或者Web容器的上下文中获取资源的操作类. 鉴于此,spr ...

  7. Android之Android apk动态加载机制的研究(二):资源加载和activity生命周期管理

    转载请注明出处:http://blog.csdn.net/singwhatiwanna/article/details/23387079 (来自singwhatiwanna的csdn博客) 前言 为了 ...

  8. 在HTML中使用JavaScript(浏览器对js的加载机制分析)

    前言: 向HTML页面中插入JavaScrip的主要方法,就是使用<script>标签.主要探讨<script>标签的在HTML页面的渲染机制.对应的业务场景:从js的加载机制 ...

  9. High Performance Networking in Google Chrome 进程间通讯(IPC) 多进程资源加载

    小结: 1. 小文件存储于一个文件中: 在内部,磁盘缓存(disk cache)实现了它自己的一组数据结构, 它们被存储在一个单独的缓存目录里.其中有索引文件(在浏览器启动时加载到内存中),数据文件( ...

随机推荐

  1. js如何使用正则表达式验证电话号码(可选区号)和邮箱?(分步骤)

    js如何使用正则表达式验证电话号码(可选区号)和邮箱?(分步骤) 一.总结 js进阶正则表达式16电话号码和邮箱正则(分类解决邮箱验证)(分组加?解决电话号码区号选择问题)([\w\.-]中括号解决邮 ...

  2. 微服务学习笔记(2)——使用Consul 实现 MagicOnion(GRpc) 服务注册和发现

    原文:微服务学习笔记(2)--使用Consul 实现 MagicOnion(GRpc) 服务注册和发现 1.下载打开Consul 笔者是windows下面开发的(也可以使用Docker). 官网下载w ...

  3. 【t094】区间运算

    Time Limit: 1 second Memory Limit: 128 MB [问题描述] 区间运算是数学的一个领域.在区间运算中,常量和变量并不表示为一个单独.精确的值,而是表示为一个有着上界 ...

  4. 编写Linux中sh文件执行时出现莫名字符的问题

    今天在项目中需要编写一个sh,执行一些初始化操作,然后调取原来的执行文件,但是我在操作中主要到了首行需要加入#!/bin/sh 的表达式,但是在执行时总是报错,原因是每次执行,表达式后边都会添加一个莫 ...

  5. 【codeforces 791C】Bear and Different Names

    [题目链接]:http://codeforces.com/contest/791/problem/C [题意] 给你n-k+1个限制 要求 a[i]..a[i]+k-1里面有相同的元素,或全都不同; ...

  6. 手推机器学习公式(一) —— BP 反向传播算法

    方便起见,本文仅以三层的神经网络举例. f(⋅):表示激励函数 xi:表示输入层: yj:表示中间的隐层: yj=f(netj) netj=∑i=0nvijxi ok:表示输出层,dk 则表示期望输出 ...

  7. jQuery在线选座订座(高铁版)

    除了电影院在线选座,我们还会接触到飞机机舱选座,当然也有汽车票火车票选座的.假如有一天买火车票也提供在线选座,那么今天我来给大家介绍下如何使用jQuery选座插件完成高铁列车座位布置.选座.不同等级座 ...

  8. Formview单文档或对话框项目接受不到按键消息的解决办法

    当对话框或formview界面上有控件时,由于焦点在控件上,因此wm_char,wm_keydown等按键消息会被控件捕获,而导致对话框或formview无法接受该类按键消息.这时候通常的解决方法是在 ...

  9. dwc_otg驱动 "BUG: sleeping function called from invalid context at mm/page_alloc.c"

    方案商的开发板上otg功能只能做device,硬件看过后说没有5v供电,加上后能够识别U盘了,但是内核报了错 [ 3.264000] usb 2-1: new high-speed USB devic ...

  10. 使用带ParserContext参数的Xaml.Load方法

    原文:使用带ParserContext参数的Xaml.Load方法 如果一段XAML中存在一个标记需要从外部命名空间中解析, 就需要用到ParserContext类,  具体用法如下: Normal ...