JavaScript 的性能分析与提升

news2024/11/27 5:28:25

JavaScript 的性能分析与提升

对于 JavaScript/前端来说,性能的提升主要有两大方面:

  1. 页面初始化的优化

    这一方面主要涉及到非代码结构上,但是能够提升用户体验感的优化,如,提升用户看到页面的速度、减少用户等待与页面交互的事件。

    如 lazy loading 就是一个比较知名的初始化上的优化,购物网站也好,视频网站也好,这种 2C 的页面会载入大量的数据,如果让用户等到所有的数据都加载成功,再和页面交互,那肯定是会因为使用体验感太差而造成用户流失。

    是否在页面初始化的时候存在太多的 HTTP 请求,以及 HTTP 请求的文件是否太大,这些都会导致加载速度变慢,从而影响用户体验感。

  2. 页面运行时的优化

    这块大部分涉及到结构和实现上的优化,影响到代码实际上的运行速度和性能。

    如页面上如果要使用 3D 功能,那 3D 的渲染是否流畅,是否会阻塞页面的渲染。如果用户点击页面上的可点击部分,是否会造成延迟等。代码的实现是否会造成内存泄露,导致 reference 无法被 GC 正常清理,导致使用的 cache 越来越大,最终页面加载、运行越来越缓慢等。

    有一个比较少提及,但是又的确是问题的方面就是,是不是做了太多的为优化(micro-optimizations)。以 React 为例,useMemouseCallback 是两个内置的 memoization 的 hooks,用这两个 hooks,React 会在每次渲染的时候去比较状态是否有变化,如果有的话,才会重新计算。当计算被 memoized 值的成本高于重新渲染时,那么 memoized 的过程就是没有必要的,这种 micro-optimizations 反而会降低整体页面渲染的效率。

顺便,如果 CSS 很花哨,或者无意义的 HTML 太多,那么有的时候降低页面渲染速度的可能不是 JS,而是 CSS 和 HTML。在不少用了比较炫的 CSS & CSS Animation 的页面,其实 CSS 吃渲染的比重还挺大的。

可选的 performance 工具

测试 performance 的话,除了 devtools 之外其实还有一些其他的工具,不过因为这里不会一一列出,只会大概提一下百度/Google 的范围:

  • JavaScript 自身提供的一些计算表现的函数

    具体可以查看一下 Performance API 和 PerformanceEntry Object,这个适用于开发环境下使用,因为有一些函数会产生 log,在开发环境下反而会影响 performance。

  • benchmar.js

    这个可能需要自己实现,不过在 Stack Overflow 上找到一个代替品:https://jsbench.me/

    本质上来说,这是一个网站可以接受两个 snippets,然后分别运行并且比较 performance。

    Stack Overflow 上面的回答是:

    jsperf is based on benchmarkjs so using an online code editor (like jsfiddle, jsbin, plunker etc…) and including benchmarkjs as a library will do.

    如果需要对大段的代码进行分析的话,可能说找一个相关的 node 包配置一下比较好。

  • 一些可以测试网站综合性能的 API 或是网页

    如 https://www.webpagetest.org/,看需求,这可能会是一个付费服务,pricing 如下:

    在这里插入图片描述

    这种网站唯一麻烦的地方就在于,要测试的服务必须要已经有 domain 才可以测试,如果是私网的 beta 版本,可能会有一定的局限性。

    另外,Google 也有对应的 API 可以进行测试,所以我猜国内的一些 cloud service 应该也会有吧

  • devtools

    下面会稍微详细介绍的部分,这里主要说的是 chrome devtools,目前来说最好用

    其他的浏览器也有提供相似的服务(我指的是 Firefox,常用的就这两种)

devtools

network snapshots

它看起来大概是这个样子的:

在这里插入图片描述

具体打开的方式是点击 capture screenshots,随后使用 ⌘ R 去录制,就会有上面的效果。

对于我来说,加载 csdn 的 html 文件就要一秒多:

在这里插入图片描述

1.31s 的时候一些 JS 的文件和海量的图片都下载好了:

在这里插入图片描述

诸如次来的,有 screenshots 看起来会方便一点,因为会有当前的 snapshots:

在这里插入图片描述

不然的话直接看 waterfall 也不是不可以。

network 还有另外一个功能就是对网页进行限速(throttling),这样可以模拟网速慢的情况,网站的表现如何。

performance

performance insight 好像是新推出的:

在这里插入图片描述

所以这里就优先使用 performance 了,其结果如下:

在这里插入图片描述

对于 performance 来说,除了 network throttle 之外还可以使用 cpu throttle,这样可以模拟并分析当前页面在比较老的设备上的性能。

当 record 一部分片段的时候,能够通过 performance 这块比较明显的看出当前页面的性能:

在这里插入图片描述

大致分析一下几个比较重要的时间点:

  • 在大概 700ms 的时候,浏览器开始 FP(First Paint),即浏览器开始渲染初始页面。
  • 在大概 800ms 的时候,浏览器开始 FCP(First Contentful Paint),即开始渲染页面上的第一个内容(有可能是文字、图片等)。
  • 在大概 1700ms 的时候,浏览器完成了 DCL(DomContentLoaded)。这个时候,浏览器已经完成了所有 DOM 节点的渲染,接下来就是依靠客户端去执行操作。
  • 在大概 2800ms 的时候,浏览器完成了 LCP(Largest Contentful Paint)的渲染。
  • 在大概 3000ms 的时候,浏览器完成了加载(load)

在这里插入图片描述

滑动窗口也能够看到在某个区间最耗时的部分是什么。

之前就有碰到一个情况,说是前端的页面渲染太慢,最后通过 profiling 看了一下,主要是 idle(XHR)的时间太长了,所以愉快的把锅甩给了后端(❓)

memory

这里可以查看并对比内存之间的 snapshots,如:

在这里插入图片描述

在这里插入图片描述

这是对比了两次 YouTube 首页刷新的状态,可以看到删除合新建的结点是一样的(YouTube 的首页布局肯定是不变的),因此相对变化为 0(# Delta)。在进行 DOM 节点操作的时候,就可以使用 memory 进行对比。

举个例子,如果删除了 list 一个结点,但是# Delta 变化过大,就有可能是整个 list 被删除了并重新渲染了,这个时候就可以考虑在这里做一些优化。

又或者是添加/删除的时候 # delta 没有变化,那就就代表了某个结点在未被创建的时候就存在了(添加的情况),或是应该被删除了 GC 却没有能够顺利地清理(删除的情况),二者都代表可能会出现内存泄露问题。

lighthouse

在这里插入图片描述

lighthouse 是一个可以跑 audit 的工具,基本上可以分析一下该页面的表现情况,以及在 Google 的 SEO 表现情况,如:

在这里插入图片描述

在这里插入图片描述

如果是 2C 的项目,可以根据这些问题进行修改。

reference

  • Performance API
  • PerformanceEntry Object
  • How to profile Javascript now that JSPerf is down? [closed]
  • Analyze runtime performance
  • Profile Site Speed With The DevTools Performance Tab

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

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

相关文章

一、枚举类型——使用接口来组织枚举

枚举类型无法被继承,这一点可能有时会让人沮丧。想要继承枚举的动机,一部分源自希望扩充原始枚举中的元素,另一部分源自想要使用子类型来创建不同的子分组。 你可以在一个接口内对元素进行分组,然后基于这个接口生成一个枚举&…

Python零基础入门(三)——基本输入与输出

系列文章目录 个人简介:机电专业在读研究生,CSDN内容合伙人,博主个人首页 Python入门专栏:《Python入门》欢迎阅读,一起进步!🌟🌟🌟 码字不易,如果觉得文章不…

关于 Vue3 响应式 API 以及 reactive 和 ref 的用法

文章目录 📋前言🎯关于响应式🎯reactive 的用法🎯ref 的用法📝最后 📋前言 这篇文章记录一下 Vue3 响应式的内容,其中还包括了 reactive 和 ref 的用法。响应式是一种允许以声明式的方式去适应…

VMware16虚拟机安装Ubuntu16.04 LTS

VMware14虚拟机安装Ubuntu16.04 LTS 一、基本介绍二、vmware下安装ubuntu系统2.1 下载ubuntu客户端镜像2.2 安装及配置2.2.1 安装2.2.2 配置 三、ubuntu系统使用 回到目录   回到末尾 一、基本介绍 对于ubuntu而言,就是linux操作系统的具体,而linux对…

S7-1200通过外部端子控制V20变频器启停+MODBUS读写频率的具体方法

S7-1200通过外部端子控制启停+MODBUS读写频率的具体方法 本例中是通过S7-1200PLC外部端子的方式控制变频器启停,用Mobus RTU通讯读写变频器频率。 硬件连接: 屏蔽双绞线将V20变频器P+,N-连接到CPU上CB1241 T/RA 和T/RB, T/RB接P+,T/RA接N-。TA和T/RA用短线连上,TB和T/RB用短…

jmeter函数助手

详解JMeter函数和变量 测试人员可以在JMeter的选项菜单中找到函数助手对话框("Function Helper"对话框),如图11-1所示。 图11-1 函数助手(Function Helper)对话框 使用函数助手,测试人员可以…

【Python】文件操作 ② ( 文件操作 | 读取文件 | read 函数 | readline 函数 | readlines 函数 )

文章目录 一、读取文件1、read 函数2、readline 函数3、readlines 函数 二、代码示例 - 读取文件1、代码示例 - read 函数读取文件 10 字节内容2、代码示例 - read 函数读取文件所有内容3、代码示例 - readline 函数读取文件一行内容4、代码示例 - readlines 函数读取文件所有内…

利用 AI 作图帮助理解知识

一、背景 人类对图形的接受和处理能力高于对文字和数字的处理能力。 如果我们学习某个知识的时候,能够找到配套的图,理解会好很多。 但,并不是所有的知识都有配图。 然而,人工智能的时代已经来临,为什么不尝试用 AI…

Flutter 项目创建、运行及结构分析

目录 开发工具 创建项目 1.New Flutter Project 1.1直接创建新项目 1.2 已有项目创建新项目 2.选择SDK,补充项目资料 3.Demo已生成 3.1 android 目录 3.2 ios目录 3.3 lib目录 3.4 test 目录(可先不管) 4.配置文件 4.1 pubspec.yaml文件 4.2 pubspec.lock 4…

chatgpt赋能python:Python报错重新执行技巧

Python报错重新执行技巧 如果你在使用Python编程时,经常遇到报错的情况,特别是在大量数据处理或者复杂算法实现时,报错更是常态。那么,你是否不知道该如何处理这些报错信息,或者对于重新执行代码有一些不确定的想法&a…

【Leetcode60天带刷】day15二叉树——102. 二叉树的层序遍历 ,226.翻转二叉树 ,101.对称二叉树 2

题目: 102. 二叉树的层序遍历 给你二叉树的根节点 root ,返回其节点值的 层序遍历 。 (即逐层地,从左到右访问所有节点)。 示例 1: 输入:root [3,9,20,null,null,15,7] 输出:[[3],…

嵌入式系统课程设计——温度记录仪

课程设计目录 一、嵌入式系统基础实验 二、项目需求分析 三、实验方案设计 四、实验程序设计 五、成本核算情况 八、完成情况与问题分析 九、学习心得 一、嵌入式系统基础实验 1.1实验平台的使用 图1 建立新工程图片 图2 选择lpc1114芯片图片 图3 选择头文件图片 图4 编译…

基于51单片机数字频率计的设计与实现

目录 第一章 系统原理与总体设计 1.1系统组成 1.2系统原理 1.3测量原理 1.4频率测量与总体设计 第二章 硬件电路设计 2.1硬件电路框图 2.2数字频率计原理图 2.3硬件电路设计 第三章 软件程序设计 3.1程序流程图 3.2显示电路程序设计 3.3 定时器初始化程序设计 3.4…

MeetingService重构和ParticipantList性能优化实践

​ 一丶背景 1.1 现状 最初Rooms客户端只支持加入Rcv meeting这个meeting type,RcvMeetingStateService里写了一些加会的状态机转换和Audio, Video, Share相关的功能代码。后续有新的业务,需要增加支持Webinar, Sip等各种Meeting,MeetingS…

Linux Shell 实现一键部署ovirt4

ovirt 前言 oVirt是一个开源分布式虚拟化解决方案,旨在管理您的整个企业基础设施。oVirt使用可信的KVM管理程序,并基于其他几个社区项目构建,包括libvirt、Gluster、PatternFly和Ansible。 Ovirt仅支持系统Centos / Redhat ovirt download…

npm利用verdaccio工具发布到私有仓库的教程

文章目录 概要安装方式运行方式相关的配置淘宝源修改开发访问地址设置用户删除用户更换源设置发布当前包 概要 提示:用于将可复制和常用的方法打包发布 例如: 可以将我们的公共组件和工具类以及SDK等核心的代码发布到外网中,需要我们常见私…

小白到运维工程师自学之路 第三十五集 (MongoDB的基本使用)

一、概述 MongoDB是一个非关系型数据库管理系统,它使用文档模型存储数据。MongoDB中的文档类似于JSON对象,可以包含键值对和嵌套文档。MongoDB提供了强大的查询语言、聚合框架、索引和直接在数据存储中运行的计算。 MongoDB被广泛应用于许多领域&#x…

MySQL开启远程访问权限

默认情况下,MySQL只允许本地登录,即只能在安装MySQL环境所在的主机下访问。 但是在日常开发和使用中,我们经常需要访问远端服务器的数据库,此时就需要开启服务器端MySQL的远程连接权限。1、生成环境,连接MySQL 2、查看…

STM32单片机(六)TIM定时器 -> 第七节:TIM编码器接口

❤️ 专栏简介:本专栏记录了从零学习单片机的过程,其中包括51单片机和STM32单片机两部分;建议先学习51单片机,其是STM32等高级单片机的基础;这样再学习STM32时才能融会贯通。 ☀️ 专栏适用人群 :适用于想要…

vue引入jszip下载多个图片并压缩下载

vue引入jszip下载多个图片并压缩下载 jszip官网地址 先进行jszip下载 npm install jszip然后废话不多说直接上代码 <template><div><button click"downloadImages">下载图片</button></div> </template><script> impo…