浏览器预加载器如何使页面加载速度更快

预加载器(也称为推测或前瞻预解析器)可能是浏览器性能有史以来最大的改进。

那么什么是预加载器以及它如何提高性能呢?

浏览器如何加载网页

网页充满了依赖关系——在下载相关的CSS之前页面无法开始渲染,然后当遇到脚本时HTML解析器会暂停直到脚本执行(当然,如果脚本是外部的,它也需要下载)。

让我们考虑一下浏览器如何加载页面:

  • 首先下载 HTML,浏览器开始解析它。它找到对外部 CSS 资源的引用并发出下载它的请求。

  • 浏览器可以在下载 CSS 时继续解析 HTML,但随后它会找到带有外部 URL 的脚本标记,现在(除非脚本具有asyncdefer属性)它必须等到脚本下载并执行。

  • 一旦脚本下载并执行,浏览器就可以继续解析 HTML,当它发现图像等非阻塞资源时,它会请求它们并继续解析,但是当它发现脚本时,它必须停止并等待脚本执行。被检索并执行。

尽管浏览器能够并行发出多个请求,但具有这种行为的浏览器通常不会与脚本并行下载任何资源。

测试页有两个样式表,头部有两个脚本,然后在正文中有两个图像、一个脚本,最后是另一个图像。

在这里插入图片描述

通过瀑布可以很容易地看到在下载脚本时并行下载停止。

如果浏览器仍然这样工作,那么页面加载速度会更慢,因为每次遇到脚本时,浏览器都需要等待脚本下载并执行,然后才能发现更多资源。

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

Internet Explorer、WebKit 和 Mozilla 都在 2008 年实施了预加载器,作为克服等待脚本下载和执行时网络利用率低的问题的一种方法。

当浏览器在脚本上被阻止时,第二个轻量级解析器会扫描标记的其余部分,查找也需要检索的其他资源,例如样式表、脚本、图像等。

然后,预加载器开始在后台检索这些资源,目的是当主 HTML 解析器到达这些资源时,它们可能已经被下载,从而减少页面稍后的阻塞。

(当然如果资源已经在缓存中那么浏览器就不需要下载它)

使用 IE8 重复之前的测试表明,其他资源现在与脚本并行下载,为此测试用例带来了巨大的性能改进:7 秒 vs 14 秒。

在这里插入图片描述

预加载器的行为因浏览器而异,并且仍然是一个实验领域,一些浏览器似乎有幼稚的实现,它们按照发现的顺序下载资源,但其他浏览器会优先考虑下载,例如 Safari 提供的样式表不适用于当前视口的优先级较低,Chrome 会以比页面上大多数图像更高的优先级安排脚本(即使是页面底部的脚本)。

预加载器陷阱

预加载器从标记中提取 URL,并且不会/无法执行 javascript,因此使用 javascript 插入的任何 URL 对它来说都是不可见的,并且这些资源的下载将被延迟,直到 HTML 解析器发现并执行加载它们的 javascript。

在某些情况下,使用 JavaScript 插入资源也会导致某些预加载器出错。

示例:

<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 被延迟,直到其中一个图像完成并且连接变为可用的。

在这里插入图片描述

一些响应式图像方法使用后备图像,预加载器通常会在执行 javascript 以选择适当的图像之前启动后备图像下载,从而导致额外的下载。

影响预加载器

目前,我们影响预加载器优先级的方法有限(使用 javascript 隐藏资源就是其中之一),但W3C 资源优先级规范提出了两个属性来帮助表明我们的意图。

lazyload:在未标记为延迟加载的其他资源开始下载之前,不应下载资源

postpone:资源必须在用户可见(即在视口内并且显示不是无)之前才能下载。

预加载与预取

预取是向浏览器暗示将来肯定会或可能使用的资源的一种方式,一些提示适用于当前页面,其他提示适用于未来可能的页面。

在最简单的层面上,我们可以告诉浏览器将 DNS 解析为我们稍后将在页面上访问的另一个主机名:

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

Chrome 还允许我们暗示我们稍后将在当前页面中使用另一个资源,因此应该优先下载它:

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

(Chromium 的源代码表明它实际上下载的优先级低于样式表/脚本和字体,但优先级等于或高于图像)

还有两种链接类型允许我们推测性地暗示接下来会发生什么,并且将以比当前页面上的资源更低的优先级下载。

预取可能位于下一页的单个资源:


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

在后台选项卡中预取并渲染整个页面:

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

总结

预加载器并不是什么新鲜事,它提供了显着的性能提升,作为开发者,我们不需要做任何特殊的事情来利用它。

原文链接:https://andydavies.me/blog/2013/10/22/how-the-browser-pre-loader-makes-pages-load-faster/

相关推荐

  1. 前端开启gzip优化页面速度

    2024-04-30 18:52:03       32 阅读
  2. vue图片

    2024-04-30 18:52:03       12 阅读
  3. android 进程

    2024-04-30 18:52:03       8 阅读

最近更新

  1. TCP协议是安全的吗?

    2024-04-30 18:52:03       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-04-30 18:52:03       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-04-30 18:52:03       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-04-30 18:52:03       18 阅读

热门阅读

  1. leetcode942-Find the Shortest Superstring

    2024-04-30 18:52:03       8 阅读
  2. LeetCode 727. 菱形

    2024-04-30 18:52:03       9 阅读
  3. leetcode392--判断子序列

    2024-04-30 18:52:03       11 阅读
  4. 基于VMD-CNN-BiLSTM-Attention组合模型时间序列预测

    2024-04-30 18:52:03       9 阅读
  5. 自然语言转SQL 学习笔记

    2024-04-30 18:52:03       12 阅读
  6. Edge的使用心得与深度探索

    2024-04-30 18:52:03       12 阅读
  7. 嵌入式开发英文单词汇总(C++、Python、Shell)

    2024-04-30 18:52:03       11 阅读
  8. 【LeetCode刷题记录】简单篇-67-二进制求和

    2024-04-30 18:52:03       9 阅读
  9. 笨蛋学C++【C++基础第六弹】

    2024-04-30 18:52:03       10 阅读
  10. 介绍一下mybatis的基本配置(mybatis-config.xml)

    2024-04-30 18:52:03       10 阅读