如何通过预加载器提升网页加载速度

预加载器(Pre-loader)可以说是提高浏览器性能最重要的举措。Mozilla 官方发布数据,通过预加载器技术网页的加载性能提升了19%,Chrome测试了 Alexa 排名前2000名网站,性能有20%的提升。

它并不是一门新技术,有人认为只有 Chrome 才具备这个功能。也有人认为它是有史以来提升浏览器性能最有效的方法。如果你第一次接触预加载器,也许心中已经有了无数个问号。什么是预加载器?它是如何提升浏览器性能的?

首先需要了解浏览器是如何加载网页的

一个网页的加载依赖于脚本文件、CSS样式文件。让我们看看浏览器加载网页的过程。

  • 首先,浏览器下载 HTML 并开始解析。如果浏览器发现外部CSS资源链接则发送下载请求。
  • 浏览器可以在下载CSS资源的同时,并行解析HTML文件,但是,一旦发现有脚本文件的引用,则必须等待脚本文件完成下载并且执行后才能继续解析。
  • 脚本文件完成下载并且执行后,浏览器可以继续解析HTML工作,如果遇到非阻塞资源 i.e. 图片浏览器会发送下载请求并且继续解析。

即使浏览器可以并行执行多个请求,但是无法与针对脚本文件的操作并行执行。

可以通过IE7打开链接中的网页进行测试。我们可以看到,网页head标签内包含2个样式文件和2个脚本文件。在body 中,包含3个图片、1个脚本文件。

通过瀑布流我们可以查看资源加载的过程:

脚本文件的下载和执行,会阻断其他资源文件的下载,无疑将大大降低浏览器性能。

预加载器如何提高网络利用率

2008 年,IE、WebKit和Mozilla都实现了预加载器功能,来提升网络的利用率,改善脚本文件对其他资源文件的阻塞现状。

当浏览器被脚本文件阻塞时,另一个轻量级的解析器会继续浏览剩余的标记,寻找需要下载的资源i.e. 样式文件, 脚本文件,图片 等。

一旦发现,预加载器既可以在后台开始接收这些资源,等待主解析器完成当前的脚本操作,其他资源已经完成下载,这样就减轻了脚本阻塞带来的性能损耗。

下面这个瀑布流是使用IE8打开链接中网页的结果,性能有显著的提升:IE8=7S > IE7=14S。

预加载功能仍然是各大浏览器厂商乐此不疲的实验领域。很多浏览器尝试设置资源下载的优先级。例如,Safari降低了不作用于当前视图区域样式文件的优先级。Chrome 则设置脚本文件的优先级高于图片,即使脚本文件位于HTML底部。

预加载器的陷阱

预加载器只能检索HTML标签中的URL,无法检测到使用脚本代码添加的URL,直至脚本代码执行时才可以获取这类资源。

我曾经遇到过一个通过javascript判断当前Window宽度,进而决策加载CSS样式文件的例子。预加载器无法识别此类资源。

<html>
<head>
 <script>
 var file = window.innerWidth < 1000 ? "mobile.css" : "desktop.css";  document.write('<link rel="stylesheet" type="text/css" href="css/' + file + '"/>');  </script>
 </head>
 <body>
 <img src="img/gallery-img1.jpg" />
 <img src="img/gallery-img2.jpg" />
 <img src="img/gallery-img3.jpg" />
 <img src="img/gallery-img4.jpg" />
 <img src="img/gallery-img5.jpg" />
 <img src="img/gallery-img6.jpg" />
 </body>
</html>

上面这段代码可以轻松的骗过IE9的预加载机制,在下面的瀑布流中我们可以看到,加载图片占用了所有的连接,直至第一个图片加载完成后,CSS文件才开始下载。

影响预加载器的加载顺序的因素

当前,有几种方式来控制预加载器的加载顺序(使用javacript隐藏资源文件既是其中一种),同时,W3C Resource Priorities中也提供两个特性来影响预加载器。

lazyload : 直至没有被标记为lazyload 资源下载完毕后才下载被标记资源。

postpone: 资源在对最终用户可见之后才开始下载。i.e. 标签的display属性被设置为 none。

预加载VS预读取

预读取(Pre-fetching)可以通知浏览器哪些资源可能会在未来的某一时机,在当前页面或者其他页面中使用。

下面是预读取的一个简单的应用,通知浏览器为将要访问的其他站点加载资源:

<link rel="dns-prefetch" href="other.hostname.com">

Chrome允许我们预先通知浏览器加载未来会用到的资源,被声明的资源将以较高的优先级被下载。

<link rel="subresource" href="/some_other_resource.js">

(Chromium 源码中提到,被标记为subresource的资源下载的优先级低于样式文件和脚本文件,但不低于图片加载优先级)

还有标记可以通知浏览器哪些文件是较低级别的预读取文件。

预读取未来将被使用的独立资源文件。

<link rel="prefetch" href="/some_other_resource.jpeg">

通过预读取方式,在后台渲染整个页面。

<link rel="prerender" href="//domain.com/next_page.html">

总结

预加载不是一门新技术,它对提高浏览器性能具有纪念意义,我们不需要做任何操作既可以使用预加载。

它广泛应用,我测试了以下浏览器,都具有预加载功能:

  • IE8 / 9 / 10
  • Firefox
  • Chrome (inc Android)
  • Safari (inc iOS)
  • Android 2.3

Bruce Lawson(Opera公司总裁)也宣布Opera Mini 同样支持预加载。

原文发布于微信公众号 - php(phpdaily)

原文发表时间:2015-10-24

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏IMWeb前端团队

npm 中如何下载特定的组件版本

本文作者:IMWeb helinjiang 原文出处:IMWeb社区 未经同意,禁止转载 本文详细讨论了 npm 中依赖版本的版本号配置写法及比较。 ...

1856
来自专栏后端技术探索

PHP实现即时将结果输出到浏览器

web开发中有没有碰到需要适时的将结果输出到浏览器页面而不刷新整个页面的需求呢?当你在处理一个过程需要耗时很长,但你又需要适时的知道程序当前的处理状况的时候,该...

593
来自专栏java架构学习交流

Java web开发,在一个jsp里放太多java代码的后果,摘自 java web轻量级开发面试教程

现要做一个简单的登录页面,如果用户通过验证,会显示Welcome用户名的欢迎词,反之则返回登录页面让用户再次输入 这部分的完整代码是JSPDemo项目里的log...

2087
来自专栏云计算教程系列

如何使用fail2ban防御SSH服务器的暴力破解攻击

对于SSH服务的常见的攻击就是暴力破解攻击——远程攻击者通过不同的密码来无限次地进行登录尝试。当然SSH可以设置使用非密码验证验证方式来对抗这种攻击,例如公钥验...

1203
来自专栏FreeBuf

如何开始对Android应用的逆向分析?

本文是我的关于如何开始Android逆向系列文章的第一部分。在文末提供了一个文档,你可以根据该文档说明部署同我一样的实验环境。

693
来自专栏开源项目

听说,你也在做日志分析? | 码云周刊第 37 期

— 01 — 项目名称:赛克蓝德日志分析软件 seci-log ? 项目简介: 赛克蓝德日志分析软件,主要对日志进行收集,格式化,然后进行分析,日志可以是系...

3539
来自专栏微信小程序开发

微信小程序开发常见问题(五)

知晓程序员,专注微信小程序开发的程序员! 一、微信小程序审核未通过,怎么办? 小程序审核不通过的原因很多,微信会给出相应审核不通过 的原因。今天连胜老师给大家...

3157
来自专栏北京马哥教育

Web性能压力测试工具http_load,webbench,ab,Siege详解

1. http_load http_load是基于linux平台的性能测试工具,它体积非常小,仅100KB。它以并行复用的方式运行,可以测试web服务器的吞吐量...

39211
来自专栏魏艾斯博客www.vpsss.net

如何使用 MAMP 快速搭建 php 环境

1885
来自专栏小特工作室

基于微软RDLC报表控件示例(含源码)

      五一放假,研究了下RDLC,之前一直有人说如何强大?研究之后才发现,确实很强大.微软的这套东西,感觉是借鉴了Sybase的数据窗口,配置方式大同小异...

18910

扫码关注云+社区