评价页面性能好坏的核心之一就是页面的加载速度,而页面加载速度的关键就是页面资源的加载。本文将从浏览器浏览器页面资源加载过程展开分析,来引出页面关键请求路径的概念,并给出如何优化该关键请求路径的一些方法。 下面相关内容,都是以chrome浏览器为例来进行介绍的。不一样浏览器之间,能够会略有差别,但基本过程是一致的。css
首先抛出两个问题:html
chrome浏览器会将资源分为14类,以下表所示。前端
类型 | 介绍 |
---|---|
kMainResource | 即主资源,html页面文件资源就属于该类型 |
kImage | 各类图片资源 |
kCSSStyleSheet | 顾名思义,就是层叠样式表css资源 |
kScript | 脚本资源,例如js资源 |
kFont | 字体资源,例如网页中经常使用的字体集.woff资源 |
kRaw | 混合类型资源,最多见的ajax请求就属于这类资源 |
kSVGDocument | SVG可缩放矢量图形文件资源 |
kXSLStyleSheet | 扩展样式表语言XSLT,是一种转换语言,关于该类型能够查阅w3c XSL来了解 |
kLinkPrefetch | HTML5页面的预读取资源(Link prefetch),例如dns-prefetch。下面会有详细介绍 |
kTextTrack | video的字幕资源,- 即<track> 标签 |
kImportResource | HTML Imports,将一个HTML文件导入到其余HTML文档中,例如<link href="import/post.html" rel="import" /> 。详细了解请查阅相关文档。 |
kMedia | 多媒体资源,video or audio都属于该类资源 |
kManifest | HTML5 应用程序缓存资源 |
kMock | 预留的测试类型 |
网页安全政策(Content Security Policy,缩写 CSP)是由浏览器提供的一种白名单制度。开发者经过配置,来告诉浏览器各种外部资源的加载和执行限制,来提升网页的安全性。一种最经常使用的应用就是经过限制非信任域名脚本的加载来预防XSS攻击。 能够经过两种方式来配置CSP。 第一种,就是经过页面HTTP请求头的Content-Security-Policy字段来限制。以下图所示,这是www.google.com页面的请求头: web
<meta>
标签来设置。
<meta>
是以key-value的方式来进行配置的。下面以几个具体的应用例子来介绍。
<meta http-equiv="Content-Security-Policy" content="script-src 'self'; style-src nos.netease.com kaola.com;">
复制代码
上面的script-src
表明脚本资源;style-src
表明样式资源;'self'
表明只信任当前域名下的外来资源,其余域下的资源所有会被拦截;nos.netease.com kaola.com
表明信任nos.netease.com和kaola.com这两个域名下的资源。 因此上面的标签的意义就是:对于脚本资源只信任本域下的,对于样式资源,除了本域还会加载nos.netease.com和kaola.com这两个域名下的。ajax
<meta http-equiv="Content-Secur****ity-Policy" content="upgrade-insecure-requests">
复制代码
上面的upgrade-insecure-requests
的意义,就如同字面意思同样:升级全部非安全请求。当加了这个meta标签之后,浏览器会将https页面中的全部htttp请自动升级到https。例如,当咱们须要进行全站http转https改造时,对于原有的大量http资源会直接强制以https或wss等SSL加密形式发送请求而不会报错。固然若是资源服务器不支持https等SSL加密,那么该资源仍是不会载入。chrome
<meta http-equiv="Content-Security-Policy" content="block-all-mixed-content">
复制代码
混合内容(Mixed Content)就是第2个例子所说的,在https站点中,进行的http请求。这类在安全连接中混合了非安全请求内容就叫混合内容。出现这类请求时,咱们能够在浏览器控制台中找到对应的警告信息,以下图所示。 json
资源的优先级被分为5级。不一样资料上,对这5级的命名描述上可能有所不一样。主要是由于资料自己多是从网络层面,浏览器内核或者用户端控制台显示这三个方向中的某一个来讲的。这三个方向虽然对这5级的命名不一样,但都是一一对应的。 网络层面,5级分别为:Highest、Medium、Low、Lowest、Idle; 浏览器内核,5级分别为:VeryHigh、High、Medium、Low、VeryLow; 用户端控制台显示,5级分别为:Highest、High、Medium、Low、Lowest;后端
下面是以浏览器内核做为研究方向,来介绍浏览器的资源优先级计算过程:浏览器
<link rel=“preload">
标签预加载)、script、xhr请求;(标记early**)
它会被定为High优先级,在以后的(标记late**)
会被设置为Medium优先级。 下图总结了资源优先级计算后各种资源的优先级状况,其中特别将上面讲的三种常见资源的状况框了出来。红框框中的为脚本类型、紫框的为图片类型、蓝框为XHR请求。图片来源点此。
上面详细介绍了浏览器的资源加载过程,其中核心在于资源的加载优先顺序的计算。咱们能够经过优化资源的加载优先级顺序,来有效提升页面的加载响应速度。缓存
首先来介绍下关键请求链(Critical-Request-Chains)的概念。可视区域渲染完毕(首屏),并对于用户来讲可用时,必须加载的资源请求队列,就叫作关键请求链。这样,咱们能够经过关键请求链,来肯定优先加载的资源以及加载顺序,以实现浏览器尽量快地加载页面。
优化关键请求链有不少方法,这里主要介绍两种。
第一种:利用Preload和Prefetch。
这两个标签在文章前面的介绍中就已经有所介绍,它们都属于预加载性能优化技术。对于开发人员,咱们可能比浏览器更加了解咱们的应用。从而可使用该技术来预先告知浏览器某些资源可能在未来会被使用到,让浏览器对这部分资源进行提早加载。 Preload:
<link rel="preload" href="test.jpg">
复制代码
Prefetch: Prefetch包括资源预加载、DNS预解析、http预链接和页面预渲染。
资源预加载:<link rel="prefetch" href="test.css">
DNS预解析:<link rel="dns-prefetch" href="//haitao.nos.netease.com">
http预链接:<link rel="prefetch" href="//www.kaola.com"> 将创建对该域名的TCP连接
页面预渲染:<link rel="prerender" href="//m.kaola.com"> 将会预先加载连接文档的全部资源
复制代码
那么Prefetch和Preload有什么区别呢? 具体来说,Preload来告诉浏览器预先请求当前页须要的资源,从而提升这些资源的请求优先级。好比,对于那些原本请求优先级较低的关键请求,咱们能够经过设置Prefetch来提高这些请求的优先级。 Prefetch来告诉浏览器用户未来可能在其余页面(非本页面)可能使用到的资源,那么浏览器会在空闲时,就去预先加载这些资源放在http缓存内,最多见的dns-prefetch。好比,当咱们在浏览A页面,若是会经过A页面中的连接跳转到B页面,而B页面中咱们有些资源但愿尽早提早加载,那么咱们就能够在A页面里添加这些资源Prefetch,那么当浏览器空闲时,就会去加载这些资源。 因此,对于那些可能在当前页面使用到的资源能够利用Prefetch,而对一些可能在未来的某些页面中被使用的资源能够利用Preload。若是从加载优先级上看,Prefetch会提高请求优先级;而Preload会把资源的优先级放在最低,当浏览器空闲时才去预加载。
第二种:利用LocalStorage。 既然第一种的预加载技术来进行资源缓存的支持性较差,那么一般能够利用LocalStorage来对部分请求的数据和结果进行缓存,省去发送http请求所消耗的时间,从而提升网页的响应速度。 这类作法在移动端应用已经十分普遍。下面分别介绍鹅、猫、狗三家页面是如何利用LS来进行请求缓存的。
微信:利用LS来对js文件进行缓存。 以下图所示,用浏览器打开一篇微信公众帐号文章,打开控制台,发现Network里居然一个js文件都不须要加载?一脸懵逼!
天猫:利用LS来对关键的XHR异步请求进行缓存。 以天猫超市首页为例: 以下图,查看LS,发现其对首屏中的轮播和10个分类入口的数据进行了缓存。
京东:利用LS来对非关键请求进行缓存。 以PC版的京东首页为例。京东反向思惟,另辟奇径地采用了另外一种方式来利用LS。那就是把非关键请求剥离出来存放在LS内。 具体来讲,对于首屏数据,仍是正常加载和展现。但为了非首屏数据的加载和渲染会阻塞和抢占资源,从而影响首屏页面渲染。因此将非首屏资源的HTML/CSS等资源抽出来放在LS内,当页面滚动到可视区域时再去LS中获取数据,插入到dom中。这点很相似于如今的模块懒加载。以下图所示,每一个LS里都包含了一个模块所须要的HTML/CSS的资源。
PS:广告一波,网易考拉前端招人啦~有兴趣的戳我投递简历