当前位置: 首页 > news >正文

你写的js性能有多差你知道吗 | js性能优化

性能的计算⽅式

确认⾃⼰需要关注的指标
常⻅的指标有:

  1. ⻚⾯总加载时间 load
  2. ⾸屏时间
  3. ⽩屏时间

代码 尝试⽤⼀个指令, 挂载在重要元素上, 当此元素inserted就上报

各个属性所代表的含义

  1. connectStart, connectEnd
    分别代表TCP建⽴连接和连接成功的时间节点。如果浏览器没有进⾏TCP连接(⽐如使⽤持久化连接webscoket),则两者都等于domainLookupEnd;
  2. domComplete
    Html⽂档完全解析完毕的时间节点;
  3. domContentLoadedEventEnd
    代表DOMContentLoaded事件触发的时间节点:⻚⾯⽂档完全加载并解析完毕之后,会触发DOMContentLoaded事件,HTML⽂档不会等待样式⽂件,图⽚⽂件,⼦框架⻚⾯的加载(load事件可以⽤来检测HTML⻚⾯是否完全加载完毕(fully-loaded))。
  4. domContentLoadedEventStart代表DOMContentLoaded事件完成的时间节点,此刻⽤⼾可以对⻚⾯进⾏操作,也就是jQuery中的domready时间;
  5. domInteractive
    代表浏览器解析html⽂档的状态为interactive时的时间节点。domInteractive并⾮DOMReady,它早于DOMReady触发,代表html⽂档解析完毕(即dom tree创建完成)但是内嵌资源(⽐如外链css、js等)还未加载的时间点;
  6. domLoading
    代表浏览器开始解析html⽂档的时间节点。我们知道IE浏览器下的document有readyState属性,domLoading的值就等于readyState改变为loading的时间节点;
  7. domainLookupStart domainLookupEnd
    分别代表DNS查询的开始和结束时间节点。如果浏览器没有进⾏DNS查询(⽐如使⽤了cache),则两者的值都等于fetchStart;
  8. fetchStart
    是指在浏览器发起任何请求之前的时间值。在fetchStart和domainLookupStart之间,浏览器会检查当前⽂档的缓存;
  9. loadEventStart, loadEventEnd
    分别代表onload事件触发和结束的时间节点
  10. navigationStart
  11. redirectStart, redirectEnd
    如果⻚⾯是由redirect⽽来,则redirectStart和redirectEnd分别代表redirect开始和结束的时间节点;
  12. requestStart
    代表浏览器发起请求的时间节点,请求的⽅式可以是请求服务器、缓存、本地资源等;
  13. responseStart, responseEnd
    分别代表浏览器收到从服务器端(或缓存、本地资源)响应回的第⼀个字节和最后⼀个字节数据的时刻;
  14. ecureConnectionStart
    可选。如果⻚⾯使⽤HTTPS,它的值是安全连接握⼿之前的时刻。如果该属性不可⽤,则返回undefined。如果该属性可⽤,但没有使⽤HTTPS,则返回0;
  15. unloadEventStart, unloadEventEnd
    如果前⼀个⽂档和请求的⽂档是同⼀个域的,则unloadEventStart和unloadEventEnd分别代表浏览器unload前⼀个⽂档的开始和结束时间节点。否则两者都等于0;

性能优化

  1. 加速或减少HTTP请求损耗:使⽤CDN加载公⽤库,使⽤强缓存和协商缓存,⼩图⽚使⽤Base64代替,⻚⾯内跳转其他域名或请求其他域名的资源时使⽤浏览器prefetch预解析等;
  2. 延迟加载:⾮重要的库、⾮⾸屏图⽚延迟加载,SPA的组件懒加载等;
  3. 减少请求内容的体积:开启服务器Gzip压缩,JS、CSS⽂件压缩合并,减少cookies⼤⼩,SSR直接输出渲染后的HTML等;
  4. 浏览器渲染原理:优化关键渲染路径,尽可能减少阻塞渲染的JS、CSS;
  5. 优化⽤⼾等待体验:⽩屏使⽤加载进度条、菊花图、⻣架屏代替等;

本地如何查看⻚⾯性能?

chrome performance
chrome-extension的请求混杂在⻚⾯请求中,难以分析filter中填写 -scheme:chrome-extension 即可过滤掉插件请求

webpack打包分析
webpack-bundle-analyzer插件,代码:vue.config.js + package.json

如何监控性能变化?

⽇志上报 阿⾥云演⽰

pagespeed https://developers.google.com/speed/pagespeed/insights/?hl=zh-cn
数据分析 90分位 50分位 TP50、TP90和TP99等指标常⽤于系统性能监控场景,指⾼于50%、90%、99%等百分线的情况。

具体的优化⽅式

浏览器渲染原理
和渲染息息相关的主要有

  1. GUI渲染线程
    GUI渲染线程负责渲染浏览器界⾯HTML元素,当界⾯需要重绘(Repaint)或由于某种操作引发回流(reflow)时,该线程就会执⾏。
    在Javascript引擎运⾏脚本期间,GUI渲染线程都是处于挂起状态的,也就是说被冻结了.
  2. Js引擎线程
    JS为处理⻚⾯中⽤⼾的交互,以及操作DOM树、CSS样式树来给⽤⼾呈现⼀份动态⽽丰富的交互体验和服务器逻辑的交互处理。
    GUI渲染线程与JS引擎线程互斥的,是由于JavaScript是可操纵DOM的,如果在修改这些元素属性同时渲染界⾯(即JavaScript线程和UI线程同时运⾏),那么渲染线程前后获得的元素数据就可能不⼀致。
    当JavaScript引擎执⾏时GUI线程会被挂起,GUI更新会被保存在⼀个队列中等到引擎线程空闲时⽴即被执⾏。
    由于GUI渲染线程与JS执⾏线程是互斥的关系,当浏览器在执⾏JS程序的时候,GUI渲染线程会被保存在⼀个队列中,直到JS程序执⾏完成,才会接着执⾏。
    因此如果JS执⾏的时间过⻓,这样就会造成⻚⾯的渲染不连贯,导致⻚⾯渲染加载阻塞的感觉。
  3. tips:
    回流(reflow):当浏览器发现某个部分发⽣了点变化影响了布局,需要倒回去重新渲染。reflow 会从这个 root frame 开始递归往下,依次计算所有的结点⼏何尺⼨和位置。reflow ⼏乎是⽆法避免的。现在界⾯上流⾏的⼀些效果,⽐如树状⽬录的折叠、展开(实质上是元素的显⽰与隐藏)等,都将引起浏览器的 reflow。⿏标滑过、点击……只要这些⾏为引起了⻚⾯上某些元素的占位⾯积、定位⽅式、边距等属性的变化,都会引起它内部、周围甚⾄整个⻚⾯的重新渲染。

重绘(repaint):改变某个元素的背景⾊、⽂字颜⾊、边框颜⾊等等不影响它周围或内部布局的属性时,屏幕的⼀部分要重画,但是元素的⼏何尺⼨没有变。


渲染流程主要分为以下4步:

  1. 解析HTML⽣成DOM树 - 渲染引擎⾸先解析HTML⽂档,⽣成DOM树
  2. 构建Render树 - 接下来不管是内联式,外联式还是嵌⼊式引⼊的CSS样式会被解析⽣成CSSOM树,根据DOM树与CSSOM树⽣成另外⼀棵⽤于渲染的树-渲染树(Render tree),
  3. 布局Render树 - 然后对渲染树的每个节点进⾏布局处理,确定其在屏幕上的显⽰位置
  4. 绘制Render树 - 最后遍历渲染树并⽤UI后端层将每⼀个节点绘制出来现代浏览器总是并⾏加载资源,例如,当 HTML 解析器(HTML Parser)被脚本阻塞时,解析器虽然会停⽌构建 DOM,但仍会识别该脚本后⾯的资源,并进⾏预加载。
    同时,由于下⾯两点:
  5. CSS 被视为渲染阻塞资源(包括JS),这意味着浏览器将不会渲染任何已处理的内容,直⾄CSSOM 构建完毕,才会进⾏下⼀阶段。
  6. JavaScript 被认为是解释器阻塞资源,HTML解析会被JS阻塞,它不仅可以读取和修改 DOM 属性,还可以读取和修改 CSSOM 属性。
    所以存在阻塞的 CSS 资源时,浏览器会延迟 JavaScript 的执⾏和 DOM 构建。另外:
  7. 当浏览器遇到⼀个 script 标记时,DOM 构建将暂停,直⾄脚本完成执⾏。
  8. JavaScript 可以查询和修改 DOM 与 CSSOM。
  9. CSSOM 构建时,JavaScript 执⾏将暂停,直⾄ CSSOM 就绪。css资源和js资源的放置位置
    所以,script 标签的位置很重要。实际使⽤时,可以遵循下⾯两个原则:
  10. CSS 优先:引⼊顺序上,CSS 资源先于 JavaScript 资源。
  11. JavaScript 应尽量少影响 DOM 的构建。

js的异步执⾏

defer async

都是异步加载js资源, 但是区别是async加载完资源后会⽴即开始执⾏, ⽽defer会在整个document解析完成后执⾏其他

⼀、图⽚资源优化

  1. 懒加载
    图⽚懒加载
    tips: 如何判断元素是否在可视区域内?
    原理:默认给图⽚设置⼀个兜底图, 监听⻚⾯滚动, 判断图⽚进⼊可视区域内后, 则给图⽚设置真实的src
  2. 预加载图⽚等资源
const img = new Image();
img.src= 'xxxxxx';
<img src="http://pic26.nipic.com/20121213/6168183 0044449030002.jpg" style="display:none"/>
  1. webp, 渐进式加载

https://help.aliyun.com/document_detail/171050.html?
spm=5176.10695662.1996646101.searchclickresult.2b9b75d6NiTHLQ
https://help.aliyun.com/document_detail/44704.html?
spm=a2c4g.11186623.6.1428.4acb1ecfHEUVE6

⼆、其他静态资源加载优化

  1. quickLink
    https://github.com/GoogleChromeLabs/quicklink
  2. prefetch
    link(rel=“dns-prefetch”, href=“//www.baidu.com”)
    link(rel=“preconnect”, href=“//www.baidu.com”)
    link(rel=“preload”, as=“script”, href=xxxxx)
    link(rel=“preload”, as=“image”, href=xxxxxx)
  3. 静态资源压缩
    gzip, Brotli https://help.aliyun.com/document_detail/27127.html?spm=a2c4g.11186623.6.645.70471769PeSCe6
  4. webpack
    打包优化 https://webpack.docschina.org/configuration/optimization/
  5. 服务端渲染
    同构渲染
    pug模板渲染
  6. 动态polyfill
    为了兼容低版本浏览器, 我们⼀般会引⼊polyfill。但是@babel/polyfill这个包⾮常⼤, gzip之后都有27.7k, ⾮常影响体积.
    https://polyfill.io/v3/api/
    阿⾥云cdn: https://polyfill.alicdn.com/polyfill.min.js?features=es6,es7,es2017,es2018&flags=gated
<script src="https://polyfill.io/v3/polyfill.js?features=es5,es6,es7,es2017,es2018&flags=gated&callback=invokeMain">
function invokeMain() {
var scriptElement = document.createElement('script');scriptElement.type = 'text/javascript';scriptElement.async = true;scriptElement.src = 'xxxxxxxxx';document.body.appendChild(scriptElement);
}
  1. 不重要的资源延迟加载
    可以放到window.addEventListener(‘load’, () => {})
  2. 节流 防抖
    节流函数:当持续触发事件时,保证⼀定时间段内只调⽤⼀次事件处理函数。
    防抖函数:当持续触发事件时,⼀定时间段内没有再触发事件,事件处理函数才会执⾏⼀次,如果设定的时间到来之前,⼜⼀次触发了事件,就重新开始延时。
    函数节流不管事件触发有多频繁,都会保证在规定时间内⼀定会执⾏⼀次真正的事件处理函数
    函数防抖只是在最后⼀次事件后才触发⼀次函数。
    ⽐如在⻚⾯的⽆限加载场景下,我们需要⽤⼾在滚动⻚⾯时,每隔⼀段时间发⼀次 Ajax 请求,⽽不是在⽤⼾停下滚动⻚⾯操作时才去请求数据。这样的场景,就适合⽤节流技术来实现。
    ⽽⽐如搜索框, 输⼊结束后才发起请求, 就适合⽤防抖

相关文章:

你写的js性能有多差你知道吗 | js性能优化

性能的计算⽅式 确认⾃⼰需要关注的指标 常⻅的指标有&#xff1a; ⻚⾯总加载时间 load⾸屏时间⽩屏时间 代码 尝试⽤⼀个指令, 挂载在重要元素上, 当此元素inserted就上报 各个属性所代表的含义 connectStart, connectEnd 分别代表TCP建⽴连接和连接成功的时间节点。如果浏…...

线程的状态、状态之间的相互转换

目录 一、线程的状态 1. NEW 2. TERMINATED 3. RUNNABLE 4. TIMED_WAITING 5. BLOCKED 6. WAITING 二、线程状态转换 1. 线程状态转换简图 一、线程的状态 线程的状态一共有 6 种&#xff1a; NEW&#xff1a;安排了工作&#xff0c;还未开始行动&#xff08;调用 st…...

Java8使用Lambda表达式(流式)快速实现List转map 、分组、过滤等操作

利用java8新特性&#xff0c;可以用简洁高效的代码来实现一些数据处理。1 数据准备1.1 定义1个Fruit对象package com.wkf.workrecord.work;import org.junit.Test;import java.math.BigDecimal; import java.util.ArrayList; import java.util.List;/*** author wuKeFan* date …...

C++之深浅拷贝

一、浅拷贝 我们看下以下代码 Test.h 文件 #pragma once #include<iostream> using namespace std; class Student { public:Student(){}~Student(){if (m_Id ! nullptr){delete m_Id;m_Id nullptr;}}Student(int id, string strName){m_Id new int[id];m_strName s…...

CoreLocation的一切

Overview 概述 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pgnvehxf-1678717852996)(./blog_cover.png)] Core Location 提供的服务可以确定设备的地理位置、高度和方向&#xff0c;或者它相对于附近 iBeacon 设备的位置。 该框架使用设备上的所…...

HashMap原理

初始化 从HashMap 源码中我们可以发现&#xff0c;HashMap的初始化有一下四种方式 //HashMap默认的初始容量大小 16&#xff0c;容量必须是2的幂 static final int DEFAULT_INITIAL_CAPACITY 1 << 4; // HashMap最大容量 static final int MAXIMUM_CAPACITY 1 <&…...

STM32入门笔记(02):独立看门狗(IWDG)和窗户看门狗(WWDG)(SPL库函数版)

1.IWDG狗简介 除了始终控制器的RCC_CSR寄存器的父为标志位和备份区域中的寄存器以外&#xff0c;系统复位 将复位所有寄存器至它们的复位状态。 当发生以下任一事件时&#xff0c;产生一个系统复位&#xff1a; 1.NRST引脚上的 低 电平&#xff0c;即 外部复位&#xff1b;2…...

javaSE系列之方法与数组的使用

[TOC] javaSE系列之方法与数组的使用 方法的定义 方法类似于C语言中的"函数"。 方法的种类 这里方法分为有参方法也分为无参方法&#xff0c; 形参和实参是两个实体&#xff08;这里相当于函数的传值调用和传址调用&#xff09; 1.非静态方法&#xff1a;普通方法/…...

常用命令总结

将常用命令汇集于此&#xff0c;以便在忘记的时候查询&#xff0c;持续更新…… Git Local changes 添加名字&#xff1a; git config --global user.name "<你的名字>"添加邮件&#xff1a; git config --globa user.email "<你的邮箱>"…...

【Linux:程序地址空间--原来操作系统也喜欢画大饼】

目录 1 代码感受 2 进程地址空间 3 扩展 1 代码感受 在正式讲程序地址空间前我们先来看一段简单的代码来分析分析&#xff1a; 1 #include<iostream>2 #include<unistd.h>3 using namespace std;4 5 int g_val100;6 7 int main()8 {9 pid_t idfork();10 if(i…...

Python实现简单信号滤波实战

在有些项目中需要对信号进行滤波处理&#xff0c;尤其是在医疗的设备中如心跳、脉搏等设备的采样后进行处理。滤波的目的就是除去某些频率的信号如噪声。常见的包括有低通滤波、高通滤波、带通滤波。 低通滤波指的是去除高于某一阈值频率的信号&#xff1b;高通滤波去除低于某…...

Java(110):非对称加密RSA的使用(KeyPair生成密钥)

Java(110)&#xff1a;非对称加密RSA的使用(KeyPair生成密钥) RSA 算法是一种非对称加解密算法。服务方生成一对 RSA 密钥&#xff0c;即公钥 私钥&#xff0c;将公钥提供给调用方&#xff0c;调用方使用公钥对数据进行加密后&#xff0c;服务方根据私钥进行解密。 1、RSA生…...

(Mybatis 学习【1】)整合 Mybatis 开发流程

Mybatis 整合流程 ① 添加MyBatis的依赖 ② 创建数据库表 ③ 编写pojo实体类 ④ 编写映射文件UserMapper.xml ⑤ 编写核心文件mybatis-config.xml ⑥ 编写测试类** 编写 pojo 实体类 (设计相应的数据库&#xff09; Data AllArgsConstructor NoArgsConstructor public class…...

一文搞懂Kerberos

Kerberos一词来源于古希腊神话中的Cerberus——守护地狱之门的三头犬&#xff0c;Kerberos是为TCP/IP 网络设计的可信第三方鉴别协议&#xff0c;最初是在麻省理工学院(MIT)为Athena 项目而开发的。Kerberos服务起着可信仲裁者的作用&#xff0c;可提供安全的网络鉴别&#xff…...

Go爬虫学习笔记(三)

day3 ‍ 04&#xff5c;敏捷之道&#xff1a;大型Go项目的开发流程是怎样的&#xff1f; 瀑布模式 流程&#xff1a; 市场调研需求分析产品设计研发实现集成与测试项目交付与维护 适用场景&#xff1a; 需求在规划和设计阶段就已经确定了&#xff0c;而且在项目开发周期内&…...

CASTEP参数设置(2)

虚拟试验&#xff08;分子模拟&#xff09; 在表征材料以及材料的相关性质时&#xff0c;只要是采用已有的理论加以解释 但是通常来说&#xff0c;需要采用已有的理论来进行设计和探索&#xff0c;伴随着工业软件的发展&#xff0c;应当选用仿真技术来缩小探索范围 传统试验V…...

浅谈对Promise的理解以及在工作中的应用

浅谈对Promise的理解以及在工作中的应用Promise的概念背景知识JavaScript的同步和异步JavaScript事件循环回调函数进行异步操作解决方案&#xff1a;PromisePromise 在工作中的运用创建PromisePromise封装AJAXPromise链式操作Promise.all()Promise.race()async和await总结Promi…...

开源|快速入门和理解并模拟实现GPS户外机器人的定位与导航

户外机器人的定位导航相对于需要建图的场景来说&#xff0c;是比较简单容易实现的&#xff0c;因为可以借助第三方地图完成定位&#xff0c;并在第三方地图中完成路径规划和下发航点等操作&#xff0c;实现的难题在于如何控制机器人完成步行和转弯。 这些在不引进RTK高精度定位…...

Java多线程系列--synchronized的原理

原文网址&#xff1a;Java多线程系列--synchronized的原理_IT利刃出鞘的博客-CSDN博客 简介 本文介绍Java的synchronized的原理。 反编译出字节码 Test.java public class Test {private static Object LOCK new Object();public static int main(String[] args) {synchro…...

QEMU启动ARM64 Linux内核

目录前言前置知识virt开发板ARM处理器家族简介安装qemu-system-aarch64安装交叉编译工具交叉编译ARM64 Linux内核交叉编译ARM64 Busybox使用busybox制作initramfs使用QEMU启动ARM64 Linux内核前言 本文介绍采用 qemu 模拟ARM-64bit开发板&#xff08;针对ARM-32bit的有另一篇文…...

C++_核心编程_多态案例二-制作饮品

#include <iostream> #include <string> using namespace std;/*制作饮品的大致流程为&#xff1a;煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例&#xff0c;提供抽象制作饮品基类&#xff0c;提供子类制作咖啡和茶叶*//*基类*/ class AbstractDr…...

简易版抽奖活动的设计技术方案

1.前言 本技术方案旨在设计一套完整且可靠的抽奖活动逻辑,确保抽奖活动能够公平、公正、公开地进行,同时满足高并发访问、数据安全存储与高效处理等需求,为用户提供流畅的抽奖体验,助力业务顺利开展。本方案将涵盖抽奖活动的整体架构设计、核心流程逻辑、关键功能实现以及…...

【SpringBoot】100、SpringBoot中使用自定义注解+AOP实现参数自动解密

在实际项目中,用户注册、登录、修改密码等操作,都涉及到参数传输安全问题。所以我们需要在前端对账户、密码等敏感信息加密传输,在后端接收到数据后能自动解密。 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId...

【大模型RAG】Docker 一键部署 Milvus 完整攻略

本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装&#xff1b;只需暴露 19530&#xff08;gRPC&#xff09;与 9091&#xff08;HTTP/WebUI&#xff09;两个端口&#xff0c;即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...

基于Uniapp开发HarmonyOS 5.0旅游应用技术实践

一、技术选型背景 1.跨平台优势 Uniapp采用Vue.js框架&#xff0c;支持"一次开发&#xff0c;多端部署"&#xff0c;可同步生成HarmonyOS、iOS、Android等多平台应用。 2.鸿蒙特性融合 HarmonyOS 5.0的分布式能力与原子化服务&#xff0c;为旅游应用带来&#xf…...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...

Maven 概述、安装、配置、仓库、私服详解

目录 1、Maven 概述 1.1 Maven 的定义 1.2 Maven 解决的问题 1.3 Maven 的核心特性与优势 2、Maven 安装 2.1 下载 Maven 2.2 安装配置 Maven 2.3 测试安装 2.4 修改 Maven 本地仓库的默认路径 3、Maven 配置 3.1 配置本地仓库 3.2 配置 JDK 3.3 IDEA 配置本地 Ma…...

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据

微软PowerBI考试 PL300-在 Power BI 中清理、转换和加载数据 Power Query 具有大量专门帮助您清理和准备数据以供分析的功能。 您将了解如何简化复杂模型、更改数据类型、重命名对象和透视数据。 您还将了解如何分析列&#xff0c;以便知晓哪些列包含有价值的数据&#xff0c;…...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...