从前端角度浅谈性能 | 京东物流技术团队(转载)

1 前言

自网站诞生以来,页面白屏时间、用户交互的响应速度等一直都是开发者关心的问题,这直接影响了一个网站能否为用户的浏览提供舒适的服务,而这种舒适度,直接关系着对用户的吸引力,毕竟谁都不能忍受一个页面长达10秒的空白屏时间,更别说点击按钮后,页面长时间的毫无反应。

web 的性能一定程度上影响了用户留存率,Google DoubleClick 研究表明:如果一个移动端页面加载时长超过 3 秒,用户就会放弃浏览。BBC 发现网页加载时长每增 1 秒,用户就会流失 10%。在2006年,Amazon曾做过一个报道,响应时间每提高100ms,他们便会增加1%的收入。从中可以看出,页面性能的重要性,但是到底多快才是快呢。

Google 开发者提出了一种RAIL模型来衡量应用性能,这是一种以用户为中心的性能模型,它提供了一种考虑性能的结构。该模型将用户体验分解为关键操作(例如,点击、滚动、加载),并帮助您为每个操作定义性能目标。

2 RAIL模型

RAIL代表着 web 应用生命周期的四个不同方面,即:Response(响应)、Animation(动画)、Idle(空闲)、Load(加载)。

最好的性能指标是:100ms 内响应用户输入;动画或者滚动需在 10ms 内生成每一帧;最大化空闲时间;页面加载时长不超过 5秒。

不同的用户对RAIL中的每一个都有不同的性能期望,因此性能指标是根据上下文和关于用户如何感知延迟的用户体验研究来定义的。

2.1 用户感知性能延迟的关键指标
alt

用户对性能延迟的感知有所不同,具体取决于网络条件和硬件。例如,通过快速 Wi-Fi 连接,在功能强大的台式机上加载站点时,通常只需不到 1 秒时间,用户已经习以为常。通过速度较慢的 3G 网络连接,在移动设备上加载站点则需要更长的时间,因此,移动用户通常会更有耐心。在移动设备上,5 秒钟内完成加载是更现实的目标。

以上,我们了解了用户是如何感知性能延迟的,下面介绍关于RAIL模型中的关键性能指标。

2.2 Response:100毫秒内响应用户交互
  • 为了确保在100毫秒内产生可见响应,需要在 50 毫秒内处理完成用户的交互事件,例如单击按钮、切换表单控件或启动动画。
  • 在部分情况下,即时响应用户的交互行为并不一定是正确的做法。可以使用这100 毫秒的时间来执行其他需要消耗大量时间的工作,但要注意不要妨碍用户。如果可能,应在后台工作。
  • 对于需要超过50毫秒才能完成的操作,需要为用户随时提供反馈。
2.3 Animation:在10毫秒内生成一帧
  • 在 10 毫秒或更短的时间内生成动画中的每一帧。从技术上讲,每帧的最大预算是 16 毫秒(1000 毫秒/每秒 60 帧≈16 毫秒),但是,浏览器需要大约 6 毫秒来渲染每帧,因此准则为每帧 10 毫秒。
  • 以视觉平滑为目标。用户会注意到帧速率何时发生变化。

2.4 Idle:最大限度利用空闲时间

  • 利用空闲时间完成延缓的工作。例如,对于初始页面的加载,应加载尽可能少的数据,然后利用空闲时间加载其余数据。
  • 在空闲时间被利用期间,如果用户与页面交互,则应中断对空闲时间的利用,用户交互始终具有最高优先性。
2.5 Load:在5秒内交互内容并实现可交互

当页面加载缓慢时,用户注意力会分散,他们会认为任务已中断。加载速度快的网站具有更长的平均会话时间、更低的跳出率和更高的广告可见性。

根据用户的设备和网络能力优化相关的快速加载性能。目前,对于首次加载,在使用速度较慢 3G 连接的移动设备上,理想的目标是在 5 秒或更短的时间内实现可交互。
对于后续加载,理想的目标是在 2 秒内加载页面。

以上,提供了一种以用户为中心的性能模型,详细的将用户体验分解到了按键操作(例如点击、滚动、加载)中,为每个操作自定义性能目标。

接下来,我们看一下关于每一个web页面的核心指标。

3 核心web指标

2020年Google 定义的核心Web指标阈值,旨在为网络质量指标提供统一指导,这些指标对于提供出色的网络用户体验至关重要。

3.1 三大核心指标
  • LCP(Largest Contentful Paint,最大内容绘制,测量加载性能):根据页面首次开始加载的时间点,报告可视区域内可见的最大图像或文本块完成渲染的相对时间。
  • FID(First Input Delay,首次输入延迟,测量交互性):测量从用户第一次与页面交互(例如当他们单击链接、点按按钮或使用由 JavaScript 驱动的自定义控件)到浏览器对交互作出响应,并实际能够开始处理事件处理程序所经过的时间。
  • CLS( Cumulative Layout Shift,累积布局偏移,测量视觉稳定性):测量整个页面生命周期内发生的所有意外布局偏移中最大一连串的布局偏移分数。每当一个可见元素的位置从一个已渲染帧变更到下一个已渲染帧时,就发生了布局偏移。计算方式为:布局偏移分数 = 影响分数 * 距离分数
alt
alt
3.2 其他指标
  • FCP(First Contentful Paint,首次内容绘制):首次内容绘制 (FCP) 指标测量页面从开始加载到页面内容的任何部分在屏幕上完成渲染的时间。对于该指标,”内容”指的是文本、图像(包括背景图像)、
alt

以上,我们完成了对用户性能体验指标、web性能核心指标的介绍,那么你是否想再稍微深入的了解一下一个web页面从输入网址到可交互的过程呢。

4 web加载全过程

从输入url到用户可以使用页面的全过程时间统计,会返回一个PerformanceTiming对象,单位均为毫秒

alt

按触发顺序排列所有属性:

  • navigationStart:在同一个浏览器上下文中,前一个网页(与当前页面不一定同域)unload 的时间戳,如果无前一个网页 unload ,则与 fetchStart 值相等
  • redirectStart:第一个 HTTP 重定向发生时的时间。有跳转且是同域名内的重定向才算,否则值为 0
  • unloadEventStart:前一个网页(与当前页面同域)unload 的时间戳,如果无前一个网页 unload 或者前一个网页与当前页面不同域,则值为 0
  • redirectEnd:最后一个 HTTP 重定向完成时的时间。有跳转且是同域名内的重定向才算,否则值为 0
  • unloadEventEnd:和 unloadEventStart 相对应,返回前一个网页 unload 事件绑定的回调函数执行完毕的时间戳

注意:开始页面请求

  • fetchStart:浏览器准备好使用 HTTP 请求抓取文档的时间,这发生在检查本地缓存之前
  • domainLookupStart:DNS 域名查询开始的时间,如果使用了本地缓存(即无 DNS 查询)或持久连接,则与 fetchStart 值相等
  • domainLookupEnd:DNS 域名查询完成的时间,如果使用了本地缓存(即无 DNS 查询)或持久连接,则与 fetchStart 值相等
  • connectStart:HTTP(TCP) 开始建立连接的时间,如果是持久连接,则与 fetchStart 值相等,如果在传输层发生了错误且重新建立连接,则这里显示的是新建立的连接开始的时间
  • secureConnectionStart:HTTPS 连接开始的时间,如果不是安全连接,则值为 0
  • connectEnd:HTTP(TCP) 完成建立连接的时间(完成握手),如果是持久连接,则与 fetchStart 值相等,如果在传输层发生了错误且重新建立连接,则这里显示的是新建立的连接完成的时间

注意:这里握手结束,包括安全连接建立完成、SOCKS 授权通过

  • requestStart:HTTP 请求读取真实文档开始的时间(完成建立连接),包括从本地读取缓存,连接错误重连时,这里显示的也是新建立连接的时间
  • responseStart:HTTP 开始接收响应的时间(获取到第一个字节),包括从本地读取缓存
  • responseEnd:HTTP 响应全部接收完成的时间(获取到最后一个字节),包括从本地读取缓存
  • domLoading:开始解析渲染 DOM 树的时间,此时 Document.readyState 变为 loading,并将抛出 readystatechange 相关事件
  • domInteractive:完成解析 DOM 树的时间,Document.readyState 变为 interactive,并将抛出 readystatechange 相关事件

注意:只是 DOM 树解析完成,这时候并没有开始加载网页内的资源

  • domContentLoadedEventStart:DOM 解析完成后,网页内资源加载开始的时间,文档发生 DOMContentLoaded事件的时间
  • domContentLoadedEventEnd:DOM 解析完成后,网页内资源加载完成的时间(如 JS 脚本加载执行完毕),文档的DOMContentLoaded 事件的结束时间
  • domComplete:DOM 树解析完成,且资源也准备就绪的时间,Document.readyState 变为 complete,并将抛出 readystatechange 相关事件
  • loadEventStart:load 事件发送给文档,也即 load 回调函数开始执行的时间,如果没有绑定 load 事件,值为 0
  • loadEventEnd:load 事件的回调函数执行完毕的时间,如果没有绑定 load 事件,值为 0

5 各指标计算方式

alt

6 总结

在优化网站性能时,我们发现这些标准有时会相互冲突。例如,一个阈值始终可实现和该阈值始终能提供良好的用户体验之间可能存在矛盾。此外,鉴于人类感知研究通常提供一个范围值,而用户行为指标又显示了行为的逐渐变化,我们发现通常没有唯一”正确”的指标阈值。因此,我们在优化网站的性能时可以参考上诉范围阈值,同时认识到没有一个完美的阈值,毕竟“尽信书不如无书”,并且我们有时可能需要从多个合理的候选阈值中进行选择。我们不是要弄清”完美的阈值是多少”,相反地,我们应该要专注于认清”哪一个候选阈值最符合我们的网站”。

7 后续

本文从前端角度,讲述了用户性能体验的几种核心指标,并总结了相应的标准。同时从输入网址到页面完全加载完毕,系统的介绍了一个web页面的加载全流程。但是这只是作为一个开发者,评估一个页面性能所需要的基础理论知识,后续将努力为大家提供一些实际工作中的实践应用,如性能检测的应用方案,如lighthouse等工具的实际使用;web页面性能优化要知道的二三事。

作者:京东物流 李菲菲

来源:京东云开发者社区 自猿其说 Tech 转载请注明来源 alt

本文由 mdnice 多平台发布

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/632452.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

webassembly003 whisper.cpp的项目结构CMakeLists.txt

注:带星号的为非重要部分 基础配置 cmake_minimum_required (VERSION 3.5)project(whisper.cpp VERSION 1.5.0)# Add path to modules list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/") # 在\cmake文件夹下还有BuildTypes.cmake&a…

Uboot-5(U-Boot源码分析1-启动第一阶段)

来源:朱有鹏老师的嵌入式linux核心教程 1、start.S引入 1.1、u-boot.lds中找到start.S入口 (1)、在C语言中整个项目的入口就是main函数(这是C语言规定的),所以譬如说一个有10000个.c文件的项目,第一个要分析的文件就…

Go 中 slice 的 In 功能实现探索

文章目录 遍历二分查找map key性能总结 之前在知乎看到一个问题:为什么 Golang 没有像 Python 中 in 一样的功能?于是,搜了下这个问题,发现还是有不少人有这样的疑问。 补充:本文写于 2019 年。GO 现在已经支持泛型&am…

腾讯云 腾讯云服务器 - 腾讯云 产业智变·云启未来

腾讯云服务器CVM提供安全可靠的弹性计算服务,腾讯云明星级云服务器,弹性计算实时扩展或缩减计算资源,支持包年包月、按量计费和竞价实例计费模式,CVM提供多种CPU、内存、硬盘和带宽可以灵活调整的实例规格,提供9个9的数…

【工作记录】基于springboot3+springsecurity6实现多种登录方式(一)

前言 springboot3已经推出有一段时间了,近期公司里面的小项目使用的都是springboot3版本的,安全框架还是以springsecurity为主,毕竟亲生的。 本文针对基于springboot3和springsecurity实现用户登录认证访问以及异常处理做个记录总结&#x…

Linux miniGUI移植分析

框架介绍 常用GUI程序对比 https://www.cnblogs.com/zyly/p/17378659.html MiniGUI分为底层的GAL(图形抽象层)和IAL(输入抽象层),向上为基于标准POSIX接口中pthread库的Mini-Thread架构和基于Server/Client的Mini-L…

JSONObject - 用最通俗的讲解,教你玩转 JSON 数据的解析和修改

目录 一、JSONObject 1.1、为什么要使用他? 1.2、应用 1.2.1、依赖 1.2.2、JSON 数据示例 1.2.3、JSON 数据的构建 1.2.4、JSON 数据的解析 一、JSONObject 1.1、为什么要使用他? 在还没有接触过这个东西的时候,一直是通过 ObjectMap…

Spring 核心之 IOC 容器学习二

基于 Annotation 的 IOC 初始化 Annotation 的前世今生 从 Spring2.0 以后的版本中,Spring 也引入了基于注解(Annotation)方式的配置,注解(Annotation)是 JDK1.5 中引入的一个新特性,用于简化 Bean 的配置,可以取代 XML 配置文件…

深度学习记录--归—化输入特征

归化 归化输入(normalizing inputs),对特征值进行一定的处理,可以加速神经网络训练速度 步骤 零均值化 通过x值更新让均值稳定在零附近,即为零均值化 归化方差 适当减小变量方差 解释 归化可以让原本狭长的数据图像变得规整,梯度下降的…

Electron中苹果支付 Apple Pay inAppPurchase 内购支付

正在开发中,开发好了,写一个完整详细的过程,保证无脑集成即可 一、先创建一个App 一般情况下,在你看这篇文章的时候,说明你已经开发的app差不多了。 但是要上架app到Mac App Store,则要在appstoreconnect…

WPF中Image控件Source的多种指定方式

XAML中 1、直接绝对路径直接给Source 2、将图片放到项目里面,设置图片为资源;Source写法为: (1)Source"pack://application:,,,/label里面的Content;component/folder/test.png" (2&…

HBase学习六:LSM树算法

1、简介 HBase是基于LSM树架构实现的,天生适合写多读少的应用场景。 LSM树本质上和B+树一样,是一种磁盘数据的索引结构。但和B+树不同的是,LSM树的索引对写入请求更友好。因为无论是何种写入请求,LSM树都会将写入操作处理为一次顺序写,而HDFS擅长的正是顺序写(且HDFS不…

鸿蒙应用开发横空出世:是否应该换赛道

鸿蒙应用开发横空出世:互联网寒冬的希望? 大家好,我是demo.最近相信大家最近也收到了这样的消息,网上大肆宣传明年未来的趋势是鸿蒙应用开发,这里呢我也确实被这些信息所覆盖.最近几年确实互联网行业不是很景气,许多公司大量裁员,很多人都因此丢了工作.大龄程序员一直是互联网…

5408. 保险箱

5408. 保险箱 - AcWing题库 #include <iostream> #include <string> #include <algorithm> #include <cstring> using namespace std;const int N 1e5 10; string x, y; int f[N][3], n; int main() {cin >> n >> x >> y;memset(…

Linux第31步_了解STM32MP157的TF-A

了解STM32MP157的TF-A&#xff0c;为后期移植服务。 一、指令集 ARMV8提供了两种指令集:AAarch64和AArch32&#xff0c;根据字面意思就是64位和32位。 ARMV7提供的指令集是AArch32。 二、TF-A 指令集是AArch64的芯片&#xff0c;TF-A有&#xff1a;bl1、bl2、bl31、bl32 和…

drive souls to hell

​ a man forgot to put his phone on silent (/ˈsaɪlənt/), and it rang so loud in the church during preaching, the pastor scolded him,the worshippers admonished him after the sermon for interrupting ,his wife kept to lecturing on his carelessness all the …

用Python判断节假日,以及节假日的SQL数据文件

为什么要判断节假日&#xff1f; 在我们的日常生活中&#xff0c;节假日是一个重要的组成部分。无论是个人计划还是商业活动&#xff0c;了解特定日期是否为节假日都是非常有用的。在Python中&#xff0c;我们可以使用一些内置的日期和时间模块来判断一个日期是否是法定节假日…

再见了RDM,Redis官方GUI才是最好的!

1 简介 直观高效的 Redis GUI 管理工具&#xff0c;它可以对 Redis 的内存、连接数、命中率以及正常运行时间进行监控&#xff0c;并且可以在界面上使用 CLI 和连接的 Redis 进行交互&#xff08;RedisInsight 内置对 Redis 模块支持&#xff09;&#xff0c;官方下载地址。 使…

Power Designer 连接 PostgreSQL 逆向工程生成pd表结构操作步骤以及过程中出现的问题解决

一、使用PowerDesigner16.5 链接pg数据库 1.1、启动PD.选择Create Model…。 1.2、选择Model types / Physical Data Model Physical Diagram&#xff1a;选择pgsql直接【ok】 1.3、选择connect 在工具栏选择Database-Connect… 快捷键&#xff1a;ctrlshiftN.如下图&#xff…

查询数据库表字段具有某些特征的表

目录 引言举例总结 引言 当我们把一个项目做完以后&#xff0c;客户要求我们把系统中所有的电话&#xff0c;证件号等进行加密处理时&#xff0c;我们难道要一个表一表去查看那些字段是电话和证件号码吗&#xff1f; 这种办法有点费劲&#xff0c;下面我们来探索如何找到想要的…