前端性能优化--预加载技术

2023-11-01


当我们谈到前端的性能时,总是会提到比如合并、压缩、缓存或者在服务器上开启gzip之类的,目的都是为了让页面加载的更快。

资源预拉取(prefetch)则是另一种性能优化的技术。通过预拉取可以告诉浏览器用户在未来可能用到哪些资源。


Pre-fetching会提示浏览器那些未来一定或可能使用到的资源,有时在当前页面见效,有些则在未来可能打开的页面生效。 作为开发者,我们比浏览器更懂自己的应用。我们可以利用这些技术提前告知浏览器web中用到的核心资源。

以前这种实践也被称为『prebrowsing』。但这并不是一种单一的技术,实际上可以拆分成很多小点:dns-prefetch, subresource, prefetch, preconnect, 和 prerender.

DNS prefetch

DNS prefetching通过指定具体的URL来告知客户端未来会用到相关的资源,这样浏览器可以尽早的解析DNS。比如我们需要一个在example.com的图片或者视频文件。在<head>就可以这么写:

1

<linkrel="dns-prefetch"href="//example.com">

​当请求这个域名下的文件时就不需要等待DNS查询了。项目中有用到第三方的代码时这么做尤其有益(其他的使用场景,比如当静态资源和HTML不在一个域上,而在CDN上;又比如在重定向前可以加上DNS prefetch)。

Harry Roberts在他的前端性能优化文章中建议:

简单的一行就能让支持的浏览器提前解析DNS。也就是说在浏览器请求资源时,DNS查询就已经准备好了。

这可能看起来是个非常微不足道的性能提升,而且还不是必须的–Chrome总是会做类似的处理,用户只要在地址栏敲入一部分域名,如果命中了历史常用的网站,Chrome就会提前解析DNS、预拉取页面。(效果确实有限,但是聊胜于无)

caniuse

Preconnect

和DNS prefetch类似,preconnect不光会解析DNS,还会建立TCP握手连接和TLS协议(如果需要)。用法如下:

1

<linkrel="preconnect"href="http://css-tricks.com">

Ilya Grigorik写了一篇文章详细说明了这种技术:

现代浏览器竭尽所能的尝试预测网站可能需要哪些链接。通过提前连接,浏览器可以提前建立必要的通信,消除了实际请求中DNS、TCP和TLS的耗时。不过,即使是只能的现代浏览器,也没办法为每个网站可靠的预测所有连接。

幸运的是开发者可以告诉浏览器哪些通信需要在实际请求发起前就提前建立连接。

举个栗子: 上半张图显示了浏览器先拉html、再拉CSS并建立好CSSOM后,发现需要两个外链的字体(在fonts.gstatic.com上),然后浏览器开始发起两个请求,具体来说,需要对这个域进行DNS解析、TCP和TLS握手(一个建立后可以复用给另一个连接)。

1

2

<linkhref='https://fonts.gstatic.com'rel='preconnect'crossorigin>

<linkhref='https://fonts.googleapis.com/css?family=Roboto+Slab:700|Open+Sans'rel='stylesheet'>

下半张图增加了上面的代码来从fonts.gstatic.com preconnect资源。可以看到,浏览器在请求CSS的同时并行的建立字体资源需要的连接,等到真正开始需要字体时立刻就开始返回数据。

更多详细的内容可以参考Ilya Grigorik的文章。

目前只支持Firefox 39+和Chrome 46+,具体参见caniuse

Prefetch

当能确定网页在未来一定会使用到某个资源时,开发者可以让浏览器提前请求并且缓存好以供后续使用。prefetch支持预拉取图片、脚本或者任何可以被浏览器缓存的资源。

1

<linkrel="prefetch"href="image.png">

不同于DNS prefetch,上面的写法可是会去请求、下载资源并且缓存起来。当然也是有一些发生条件的。比如,客户端可能会在弱网络下不去请求较大的字体文件,Firefox则只会在浏览器空闲的时候prefetch资源(译者注:这里是MDN上对浏览器空闲的定义和一些FAQ,建议阅读)。

正如Bram Stein在他的文章中指出,prefetch很适用于优化webfonts的性能。以前,字体文件必须等DOM和CSSOM创建好后才能下载,可如果prefetch了字体,这个瓶颈就能轻松解决了。

注意:prefetch并没有同域的限制

caniuse

Subresource

subresource可以用来指定资源是最高优先级的。比如,在Chrome和Opera中我们可以加上下面的代码:

1

<linkrel="subresource"href="styles.css">

Chromium的文档这么解释:

和 "Link rel=prefetch"的语义不同,"Link rel=subresource"是一种新的连接关系。rel=prefetch指定了下载后续页面用到资源的低优先级,而rel=subresource则是指定当前页面资源的提前加载。

所以,如果资源是在当前页面需要,或者马上就会用到,则推荐用subresource,否则还是用prefetch。

Prerender

prerender是一个重量级的选项,它可以让浏览器提前加载指定页面的所有资源。

1

<linkrel="prerender"  href="/thenextpage.html"/>

Steve Souders的文章详细解释了这个技术:

prerender就像是在后台打开了一个隐藏的tab,会下载所有的资源、创建DOM、渲染页面、执行JS等等。如果用户进入指定的链接,隐藏的这个页面就会进入马上进入用户的视线。Google Search多年前就利用了这个特性实现了Instant Pages功能。微软最近也宣布会让Bing在IE11上用类似prerender的技术。

但是要注意,一定要在十分确定用户回点某个链接时才用这个特性,否则客户端就会无端的下载很多资源和渲染这个页面。

正如任何提前的动作一样,预判总是有一定风险出错。如果提前的动作是昂贵的(比如高CPU、耗电、占用带宽),就要谨慎使用了。虽然不容易预判用户会点进哪个页面,但还是存在一些典型的场景:

  • 如果用户搜索到了一个明显正确的结果时,那么这个页面就很有可能被点入

  • 如果用户在登录页面,那么登录成功后的页面就很可能接下来会被加载了

  • 如果用户在阅读一个多页面的文章或者有页码的内容时,下一页就很可能会马上被点击了

利用Page Visibility API可以用来防止页面在还没真正展示给用户时就触发了JS的执行。

caniuse

未来:Preload

以上是已有的技术,我们再谈谈未来。 preload草案建议允许始终预加载某些资源,不像prefetch有可能被浏览器忽略,浏览器必须请求preload标记的资源。

1

<linkrel="preload"href="image.png">

然而,这项草案还没有任何浏览器支持,不过值得关注。

 

总结

预判用户的操作虽然不易,而且还需要大量的设计和测试工作,但是性能的提升是值得我们孜孜不倦的去追求的。如果我们愿意试验这些预加载技术,我们肯定能显著地提升用户体验。

(译者补一句,文章说的大部分预加载技术移动端都不支持,PC支持有限,但我们显然应该知道这些技术的存在,并且持续的关注)

 

扩展阅读


本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

前端性能优化--预加载技术 的相关文章

  • url重定向

    不安全的url跳转 不安全的url跳转问题可能发生在一切执行了url地址跳转的地方 如果后端采用了前端传进来的 可能是用户传参 或者之前预埋在前端页面的url地址 参数作为了跳转的目的地 而又没有做判断的话 就可能发生 跳错对象 的问题 u
  • 大数据基础之Hbase——Hbase的shell基本操作

    目录 一 简介 二 Hbase重要概念 Hbase的表结构 表Table 命名空间namespace 行键Row Key 区域region 列簇column family 修饰符 列限定符 三 Hbase shell基本操作 1 创建简单表
  • linux的apache安装在哪个目录,在linux系统下apache的默认安装路径怎么看

    在linux系统下apache的默认安装路径怎么看 发布时间 2020 11 06 10 38 18 来源 亿速云 阅读 127 作者 小新 这篇文章将为大家详细讲解有关在linux系统下apache的默认安装路径怎么看 小编觉得挺实用的
  • Docker教程(三) - Docker 网络(上)- 桥接 Bridge

    本文章翻译自Docker的官方教程 有兴趣的同学可以上Docker官网进行play with docker学习 Docker的安装教程请参考这里 未定义 本文翻译自Docker官方教程Doing More With Docker Image
  • 【Unity项目实战】手把手教学:飞翔的小鸟(5)背景滚动

    承接上一篇 Unity项目实战 手把手教学 飞翔的小鸟 4 文本添加 我们已经使得主角小鸟接触到地面后跳转到Game Over状态 接下来我们将继续往下 讲解得分机制 一 重新进入游戏 根据上篇最后的描述 我们小鸟掉到草地就会立马被判断为游
  • 项目中Swagger2、lombok(小辣椒)、以及短信API的调用 简单介绍

    一 使用Swagger2实时生成接口文档 分布式系统使用 Swagger 是一个规范和完整的框架 用于生成 描述 调用和可视化 RESTful 风格的 Web 服务 总体目标是使客户端和文件系统作为服务器以同样的速度来更新 文件的方法 参数
  • 2021-05-27

    k8s 根据CPU利用率实现pod的弹性伸缩 一 概念 1 弹性伸缩的作用 让集群的配置可以根据计算需求 自动增加或者自动减少 在服务器访问量突然增多 算力吃紧的情况下增加节点配置数量 直到访问量下降 计算后减少节点数 保证业务平稳健康运行
  • 使用BP神经网络预测锂电池健康状态(附Matlab源码)

    使用BP神经网络预测锂电池健康状态 附Matlab源码 随着电动汽车的普及 电池技术得到了广泛的关注 其中 锂电池因其能量密度高 环保等优点被广泛应用于电动汽车和储能系统中 然而 锂电池的寿命问题一直是制约其应用和发展的重要因素之一 针对这
  • jQuery+Ajax+js请求json格式数据并渲染到html页面

    1 先给json格式的数据 id 1 name stan id 2 name jack id 3 name lucy id 4 name mary id 5 name jerry id 6 name tom 2 通过访问html页面 获取并
  • 虚幻4学习笔记(3)地形工具和植被

    地形工具和植被 地貌编辑器 生成斜坡 雕刻工具 编辑样条曲线 光照进行构建解决方法 导入灰度图 植被工具使用 植被碰撞 B站UP谌嘉诚课程 https www bilibili com video BV164411Y732 地貌编辑器 生成
  • 分布式一致性算法的重要原理:鸽巢原理

    在分布式BASE理论 数据一致性模型有哪些 中 我们谈到了BASE理论的最终一致性 以及简单介绍了数据一致性模型 但我们都是站在一个使用者的角度 在发出数据更新的请求给分布式系统之后 观察返回的数据是否更新 为了更好使用 理解分布式系统 不
  • C#入门学习-----制作AVI播放器

    本实例主要用到了Microsoft Animation Control Version 6 0 组件 该组件可以一帧一帧地播放AVI文件 用到该组件 必须将Microsoft Animation Control Version 6 0组件添
  • 如何在宝塔面板后的阿里云服务器运行Flask项目并公网可以访问?

    在你的服务器安装宝塔面板 宝塔面板是服务器运维管理系统 使用宝塔前 手工输入命令安装各类软件 操作起来费时费力并且容易出错 而且需要记住很多Linux的命令 非常复杂 使用宝塔后 2分钟装好面板 一键管理服务器 鼠标点几下就能替代以前的复杂
  • JVM类加载过程和编译器优化

    文章目录 1 加载 2 链接 2 1 验证 2 2 准备 2 3 解析 3 初始化 3 1 类初始化练习 3 2 懒汉式单例练习 4 类加载器 4 1 启动类加载器 4 2 扩展类加载器 4 3 双亲委派模式 4 4 线程上下文类加载器 4
  • PCL——VTK读取、保存.ply模型数据

    目录 一 读取 ply文件 1 代码示例 2 结果展示 一 保存 ply文件 1 代码示例 2 结果展示 一 读取 ply文件 ReadPLY 是VTK内置的mesh模型读取函数 该函数仅支持 ply格式的mesh网格数据不支持读取 ply
  • 【STM32】HAL库——ADC

    前期准备 STM32CubeMX STM32RCT6核心板 IDE Keil MDK ARM STM32CubeMX部分 1 配置时钟 选择STM32F103RCTx系列芯片 配置时钟的同时会自动配置IO口引脚 将HCLK设置为最大频率72

随机推荐

  • Altera FPGA PCIE 例程仿真

    由于刚开始学PCIE接口 所以按照官方给的例程进行仿真操作 下面主要介绍下仿真的具体步骤 该例子是采用Cyclone V器件进行仿真 PCIE为gen1X4 的 Quartus II 版本号为15 0 Modelsim为ModelsimSE
  • 小米商城网页制作大全-完结篇

    时隔多日 小米商城网页基本完成 跳转的第二页面没有做 在这过程中遇到了很多小而细的问题 例如浏览器兼容性 字符图标不显示 动画效果不起作用等 抽时间整理一下 再继续完善 效果图如下 实际右侧固定栏只有个人中心 购物车 联系客服 回到顶部四项
  • 【websocket定义和使用】

    文章目录 前言 一 websocket定义 2 websocket使用 总结 前言 websocket就是服务端和客户端建立长连接的一种方式 多在直播 弹幕 聊天业务中使用 具体的自己百度吧 一 websocket定义 代码如下 示例 fu
  • docker 服务编排

    一 docker 服务编排 微服务的应用系统中一般包含若干个微服务 每个微服务一般都会部署多个实例 如果每个微服务都要手动启停 维护的工作量会很大 要从dockerfile build image 或者去 dockerhub 拉取image
  • Flutter 指针事件原理&点击穿透

    隔离的这14天 慢慢的研究了Flutter的指针事件 在这个过程中 又重新梳理了一下Element和Render Tree的形成过程 这篇文章 主要对指针事件在Fluter中如何下发到各个组件的过程进行梳理 指针是指针 手势是手势 手势是指
  • 软件工程课件

    软件工程 考点概述 软件工程概述 能力成度模型 能力成熟度模型集成 软件过程模型 逆向工程 软件需求 需求获取 数据流图 需求定义 考点概述 重点章节 软件工程概述 之前老版教程的 之前考过 能力成度模型 记忆 能力等级 和 特点 能力成熟
  • (读书笔记)python数据处理-(python读取csv、excel文件)

    文章目录 python读取csv文件 python解析excel文件 1 查看工作表中的sheet名 2 查看工作表指定sheet的内容 3 查看sheet中每个元素 4 将提取信息以字典形式展示 python 判断excel文件是否存在
  • Java使用RabbitMQ

    一 简介 rabbitMQ是什么 怎么用 怎么安装 网上文档一大把 请自行百度 本文给出的代码是rabbitMQ的fanout交换机模式 最原生的java代码 如果需要使用其他模式的rabbitMQ 请自行更改相应部分代码 二 代码 rab
  • 浅学Oracles数据库

    一 Oracle数据库中的数据类型 1 1 关于mysql数据库中的数据类型 int 整数型 bigint 长整型 float 单精度浮点型 double 双精度浮点型 char 字符型 长度不可变 varchar 字符型 长度可变 dat
  • C 函数参数传递一级指针和二级指针的区别

    文章目录 一 概念 二 函数参数为一级指针例子 1 程序一 指针类型为基本数据 2 程序二 参数为结构体 不是指针类型 3 程序三 参数类型为结构体指针 三 函数参数为二级指针例子 1 程序四 二级指针类型为基本数据类型 2 程序五 二级指
  • Element UI DatePicker 监听年月切换按钮并获取变更

    需求 在每切换一次年月时调用接口获取数据 传参为当前切换成的年月 需要监听DatePicker是否显示 用input获得焦点时触发的focus事件 element自带 并绑定4个切换按钮的click事件 html
  • Vue3 优雅地监听 localStorage 变化

    最近在研究框架 也仔细用了Vue3一些功能 今天分享一次我的实践 Vue3如何监听localStorage的变化 为什么要这样做 原生的localStorage只能监听同源地址下不同页面的localStorage变化 作为单页面应用 显然不
  • Tip of the Week #10: Splitting Strings, not Hairs

    Tip of the Week 10 Splitting Strings not Hairs Originally published as totw 10 on 2012 08 16 By Greg Miller jgm google c
  • 前端面试题及答案(字节跳动)(一)

    目录 垂直居中 左侧固定 右侧自适应 如何判断一个值是数组 bigint 最大安全整数 如何判断某个字符串以 abc 开头 进程和线程的区别 tcp 与 udp 跨域问题的几种解决方案 option 预请求 跨域的同时携带 cookie 用
  • LeetCode 处理用时最长的那个任务的员工

    解题思路 把第一个一维数组的两个元素分别定义为最大值和id 之后遍历进行判断 class Solution public int hardestWorker int n int logs int max logs 0 1 int id lo
  • sql注入知识---堆叠注入

    MySQL手注之堆叠注入详解 一 堆叠注入产生原因 二 使用条件 三 堆叠注入语句 1 查看数据库 2 查看表格 3 查看列 4 查看数据 四 16进制类型 绕过 五 堆叠应用 一 堆叠注入产生原因 平常我们注入时都是通过对原来sql语句传
  • 数组元素交叉排列的算法题(a1 a2 a3 .. an b1 b2 b3 .. bn -->a 1 b1, a2 b2, a3 b3, .. an bn ) 概论思想(perfect shuffle 算法)

    perfect shuffle 算法 今天又发现一个关于完美洗牌的算法 这个比较简单一些 由 microsoft的Peiyush Jain提出 原论文 A Simple In Place Algorithm for In Shuffle P
  • 沪胶期货全称(沪胶期货全称叫什么)

    什么是黄金期货 上海黄金交易所和上海期货交易所是一家单位吗 1 以前的期货市场上没有黄金期货 黄金期货是在08年1月9日刚刚开始的 2 上海黄金交易所和上海期货交易所不是同一个单位 上海期交所只做各种期货交易 上海金交所只做黄金现货交易 3
  • Fabric1.4源码解析:链码实例化过程

    之前说完了链码的安装过程 接下来说一下链码的实例化过程好了 再然后是链码的调用过程 其实这几个过程内容已经很相似了 都是涉及到Proposal 不过整体流程还是要说一下的 同样 切入点仍然是fabric peer main go文件中的ma
  • 前端性能优化--预加载技术

    当我们谈到前端的性能时 总是会提到比如合并 压缩 缓存或者在服务器上开启gzip之类的 目的都是为了让页面加载的更快 资源预拉取 prefetch 则是另一种性能优化的技术 通过预拉取可以告诉浏览器用户在未来可能用到哪些资源 Pre fet