评价页面性能好坏的核心之一就是页面的加载速度,而页面加载速度的关键就是页面资源的加载。本文将从浏览器浏览器页面资源加载过程展开分析,来引出页面关键请求路径的概念,并给出如何优化该关键请求路径的一些方法。 下面相关内容,都是以 chrome 浏览器为例来进行介绍的。不同浏览器之间,可以会略有差异,但基本过程是一致的。
首先抛出两个问题:
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 文档中,例如。详细了解请查阅相关文档。 |
kMedia | 多媒体资源,video or audio 都属于该类资源 |
kManifest | HTML5 应用程序缓存资源 |
kMock | 预留的测试类型 |
网页安全政策(Content Security Policy,缩写 CSP)是由浏览器提供的一种白名单制度。开发者通过配置,来告诉浏览器各类外部资源的加载和执行限制,来提高网页的安全性。一种最常用的应用就是通过限制非信任域名脚本的加载来预防 XSS 攻击。 可以通过两种方式来配置 CSP。 第一种,就是通过页面 HTTP 请求头的 Content-Security-Policy 字段来限制。如下图所示,这是 www.google.com 页面的请求头:
第二种是,通过 标签来设置。 是以 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
- <meta http-equiv="Content-Secur****ity-Policy" content="upgrade-insecure-requests">
上面的
的意义,就如同字面意思一样:升级所有非安全请求。当加了这个 meta 标签以后,浏览器会将 https 页面中的所有 htttp 请自动升级到 https。例如,当我们需要进行全站 http 转 https 改造时,对于原有的大量 http 资源会直接强制以 https 或 wss 等 SSL 加密形式发送请求而不会报错。当然如果资源服务器不支持 https 等 SSL 加密,那么该资源还是不会载入。
- upgrade - insecure - requests
- <meta http-equiv="Content-Security-Policy" content="block-all-mixed-content">
混合内容 (Mixed Content) 就是第 2 个例子所说的,在 https 站点中,进行的 http 请求。这类在安全链接中混合了非安全请求内容就叫混合内容。出现这类请求时,我们可以在浏览器控制台中找到对应的警告信息,如下图所示。
混合内容会降低 HTTPS 网站的安全性和用户体验。不过让人略感放心的是,浏览器对于可能对安全性造成较大威胁的资源类型的混合模式请求都会直接拦截报错,例如脚本资源,如下图所示。但对于图片、音频、视频等资源只会警告,但不会阻止其加载。
对于安全性要求极高的网站,可以通过上面的标签来阻止所以类型的非安全链接请求,这样包括图片、音频、视频等资源也将会被拦截报错。 当然对于 Content-Security-Policy 的设置还有很多其他作用,大家可以通过
MDN来做进一步了解。
资源的优先级被分为 5 级。不同资料上,对这 5 级的命名描述上可能有所不同。主要是因为资料本身可能是从网络层面,浏览器内核或者用户端控制台显示这三个方向中的某一个来说的。这三个方向虽然对这 5 级的命名不同,但都是一一对应的。 网络层面,5 级分别为:Highest、Medium、Low、Lowest、Idle; 浏览器内核,5 级分别为:VeryHigh、High、Medium、Low、VeryLow; 用户端控制台显示,5 级分别为:Highest、High、Medium、Low、Lowest;
下面是以浏览器内核作为研究方向,来介绍浏览器的资源优先级计算过程:
上面详细介绍了浏览器的资源加载过程,其中核心在于资源的加载优先顺序的计算。我们可以通过优化资源的加载优先级顺序,来有效提高页面的加载响应速度。
首先来介绍下关键请求链(Critical-Request-Chains)的概念。可视区域渲染完毕(首屏),并对于用户来说可用时,必须加载的资源请求队列,就叫做关键请求链。这样,我们可以通过关键请求链,来确定优先加载的资源以及加载顺序,以实现浏览器尽可能快地加载页面。
优化关键请求链有很多方法,这里主要介绍两种。
Prefetch: Prefetch 包括资源预加载、DNS 预解析、http 预连接和页面预渲染。
- <link rel="preload" href="test.jpg">
那么 Prefetch 和 Preload 有什么区别呢? 具体来讲,Preload 来告诉浏览器预先请求当前页需要的资源,从而提高这些资源的请求优先级。比如,对于那些本来请求优先级较低的关键请求,我们可以通过设置 Prefetch 来提升这些请求的优先级。 Prefetch 来告诉浏览器用户将来可能在其他页面(非本页面)可能使用到的资源,那么浏览器会在空闲时,就去预先加载这些资源放在 http 缓存内,最常见的 dns-prefetch。比如,当我们在浏览 A 页面,如果会通过 A 页面中的链接跳转到 B 页面,而 B 页面中我们有些资源希望尽早提前加载,那么我们就可以在 A 页面里添加这些资源 Prefetch,那么当浏览器空闲时,就会去加载这些资源。 所以,对于那些可能在当前页面使用到的资源可以利用 Prefetch,而对一些可能在将来的某些页面中被使用的资源可以利用 Preload。如果从加载优先级上看,Prefetch 会提升请求优先级;而 Preload 会把资源的优先级放在最低,当浏览器空闲时才去预加载。
- 资源预加载:<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"> 将会预先加载链接文档的所有资源
PS:广告一波,网易考拉前端招人啦~ 有兴趣的 戳我投递简历
来源: https://juejin.im/post/5a4ed917f265da3e317df515