极速体验:实用的前端性能优化技巧

本文将深入探讨一系列实用的前端性能优化方案,从基础知识到高级技巧,我们将揭示如何让你的网站在瞬息万变的互联网中脱颖而出,无论你是经验丰富的开发者还是刚入行的新手,这篇文章都将为你提供宝贵的见解和实践建议。

目录

😀首屏与操作速度

🤣时间切片的使用


😀首屏与操作速度

在讲解首屏速度前,我们先分析一下对于前端来讲首屏速度的概念和组成,要知道当用户打开一个界面的时候它的组成部分包括俩方面,如下所示:

白屏时间:屏幕一片空白(请求服务器资源、加载代码)

渲染页面:渲染页面(数据请求以及DOM渲染)

加快首屏速度操作

1)压缩体积:减少编写代码体积、使用打包工具对代码进行压缩(框架一般都会处理)

2)异步加载:将与首屏加载无关的功能进行异步加载

3)合并接口:对小数据量接口可以合并到其他接口中,减少tcp握手的次数

4)批量渲染:页面包含大量dom可以进行分配随滚动渲染(例如:虚拟列表)

5)用骨架屏:使用骨架屏实现loading效果,先让屏幕不白屏,减少用户焦虑

操作速度:什么情况下会造成操作卡顿和渲染慢呢?一般这种情况基本上是由于下面原因造成的:

1)一次性操作大量dom

2)进行了复杂度很高的运算(常见于循环)

3)vue和react项目中,采用了不必要的渲染

🤣时间切片的使用

如果一个长时间运行的js操作可能会阻塞浏览器的渲染,这样我们页面就看不到反应导致页面长时间处于白屏状态或者页面不展示任何效果,这里我们可以把操作所经历的时间段切成一片一片的,我们可以先操作第一片并把结果交给页面去渲染,页面渲染完成之后再去操作下一片,如下图所示:

接下来我们就开始学习如何对js进行切片操作,这里我们需要用到一个API: requestAnimation。该API函数会在浏览器渲染完成后去执行,所以我们只需要把每个切片放到requestAnimation中,当其执行完一个之后会等着浏览器渲染完再执行下一个,这里通过如下的代码进行示例讲解:

<template><table><thead><td><input type="checkbox" @change="chooseAll">全选</td></thead><tbody><tr v-for="item in dateArr" :key="item.id"><td><input type="checkbox"></td><td>{{ item.name }}</td><td>{{ item.age }}</td><td><span v-if="item.status == 0">状态0</span><span v-if="item.status == 1">状态1</span><span v-if="item.status == 2">状态2</span></td></tr></tbody></table>
</template><script setup>
import { reactive } from 'vue'
let dateArr = reactive([])for(let i = 0; i < 50000; i++){dateArr.push({id: i,name: '张三' + Math.floor(Math.random() * 20),status: Math.floor(Math.random() * 3),checked: false,age: Math.floor(Math.random() * 18)})
}
</script>

通过上面的代码,我们在页面中循环渲染5万条数据,页面刚刷新的时候就会出现卡顿甚至是卡死的现象,网站一直处于刷新的状态中,直到很久页面才会加载出来:

接下来我们开始使用requestAnimationFrame函数先渲染500条数据,500条数据渲染完成之后再继续渲染剩下的数据,数据再悄咪咪的进行渲染,页面也不会有太大的卡顿效果,用户也不会感受到页面的卡顿而且能够及时的查看数据:

<template><table><thead><td><input type="checkbox" @change="chooseAll">全选</td></thead><tbody><tr v-for="item in dateArr" :key="item.id"><td><input type="checkbox"></td><td>{{ item.name }}</td><td>{{ item.age }}</td><td><span v-if="item.status == 0">状态0</span><span v-if="item.status == 1">状态1</span><span v-if="item.status == 2">状态2</span></td></tr></tbody></table>
</template><script setup>
import { reactive } from 'vue'
let dateArr = reactive([])let index = 0
const sliceRender = () => {requestAnimationFrame(() => {let target = index + 500for(; index < target; index++) {dateArr.push({id: index,name: '张三' + Math.floor(Math.random() * 20),status: Math.floor(Math.random() * 3),checked: false,age: Math.floor(Math.random() * 18)})}if (index < 50000) {sliceRender()}})
}
sliceRender()
</script>

从下图我们可以看到数据会随着页面的加载再逐步的进行渲染加载,页面也不会因为一次性加载太多的内容而产生卡顿的效果:

接下来我们再处理一下权限按钮的操作,当数据为5万条的时候我们再去勾选权限的话,页面很可能就会直接卡死,这里我们也是可以借助切片的方式对全选按钮进行操作,具体代码如下所示:

<template><table><thead><td><input type="checkbox" @change="chooseAll">全选</td></thead><tbody><tr v-for="item in dateArr" :key="item.id"><td><input type="checkbox" :checked="checkedList.indexOf(item.id) !== -1" :value="item.id"></td><td>{{ item.name }}</td><td>{{ item.age }}</td><td><span v-if="item.status == 0">状态0</span><span v-if="item.status == 1">状态1</span><span v-if="item.status == 2">状态2</span></td></tr></tbody></table>
</template><script setup>
import { reactive } from 'vue'
let dateArr = reactive([])
let checkedList = reactive([])let index = 0
const sliceRender = () => {requestAnimationFrame(() => {let target = index + 500for(; index < target; index++) {dateArr.push({id: index,name: '张三' + Math.floor(Math.random() * 20),status: Math.floor(Math.random() * 3),checked: false,age: Math.floor(Math.random() * 18)})}if (index < 50000) {sliceRender()}})
}
sliceRender()
const chooseAll = () => {let index = 0const sliceChecked = () => {requestAnimationFrame(() => {let target = index + 500for(; index < target; index++) {checkedList.push(dateArr[index].id)}if (index < dateArr.length) {sliceChecked()}})}sliceChecked()
}
</script>

从下图我们可以看到,当我们勾选全选按钮的时候,全选操作可谓是非常快速了:

其实我们要优化项目不只是去追求绝对的速度提升,我们在无法进一步提升速度的前提下我们可以想办法让体验更好,比如今天说的切片,比如我们对一些操作做异步加载,这些操作对于整体速度都没有提升。但是我们通过合理安排执行顺序,让体验更加好。

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

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

相关文章

基于SSM+微信小程序的打印室预约管理系统(打印2)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1、项目介绍 基于SSM微信小程序的打印室预约管理系统实现了管理员和用户两个角色。 1、管理员功能有个人中心&#xff0c;用户管理&#xff0c;附近打印店管理&#xff0c;文件打印管理&#xff0c;当…

rk3568 android11 单独烧写内核。

问题: 我现在 遇到一个问题,如果我单独 烧写boot.img 的话,就会进入 recovery 的模式。 如下图: 问题说明: 如果我烧写的 Update.img 是可以启动的。那么我再烧写一个 编译 update.img 顺带编译出来的 boot.img 是可以正常启动的。 问题出在 , 如果我 重新编译一遍 ,使…

LVGL-从入门到熟练使用

LVGL简介 LVGL&#xff08; Light and Versatile Graphics Library &#xff09;是一个轻量、多功能的开源图形库。 1、丰富且强大的模块化图形组件&#xff1a;按钮 、图表 、列表、滑动条、图片等 2、高级的图形引擎&#xff1a;动画、抗锯齿、透明度、平滑滚动、图层混合等…

WebGL编程指南 - WebGL入门

初识绘图流程、缓冲区、着色器、attribute和uniform变量 先画一个蓝色的正方形 html代码&#xff1a; <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta http-equiv"X-UA-Compatible" content&…

stm32 为什么有2个晶振?8mhz+32.768k

1个是系统时钟晶振是单片机内部系统的主时钟源&#xff0c;它负责控制整个系统的时钟频率。这个晶振的频率一般比较高&#xff0c;通常在几十MHz到几百MHz不等。它和CPU以及各种总线之间相互配合&#xff0c;从而协同工作。 另外一个是外设时钟晶振则通常用于单片机的内部外设…

【大模型问答测试】大模型问答测试脚本实现(第二版)——接入pytest与代码解耦

背景 接上一篇&#xff0c;【大模型问答测试】大模型问答测试脚本实现&#xff08;第一版&#xff09;。 在实现自动化的时候&#xff0c;原先把很多方法与request请求写在一块了&#xff0c;趁着目前实现接口数量较少&#xff0c;决定对代码进行解耦&#xff0c;并且清晰目录…

大数据-172 Elasticsearch 索引操作 与 IK 分词器 自定义停用词 Nginx 服务

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 目前已经更新到了&#xff1a; Hadoop&#xff08;已更完&#xff09;HDFS&#xff08;已更完&#xff09;MapReduce&#xff08;已更完&am…

[论文阅读]RGB-Depth Fusion GAN for Indoor Depth Completion

摘要 由于固有的限制&#xff0c;如无法感知透明物体和有限的距离范围&#xff0c;室内深度传感器捕获的原始深度图像通常会有大面积的深度值缺失。这种不完整的深度图给许多后续视觉任务带来了负担&#xff0c;尽管提出了很多深度补全方法来缓解这一问题。但是现有的大多数方…

解决k8s集群中安装ks3.4.1开启日志失败问题

问题 安装kubesphere v3.4.1时&#xff0c;开启了日志功能&#xff0c;部署时有三个pod报错了 Failed to pull image “busybox:latest”: rpc error: code Unknown desc failed to pull and unpack image “docker.io/library/busybox:latest”: failed to copy: httpRead…

字节跳动青训营——入营考核解答(持续更新中~~~)

考核内容&#xff1a; 在指定的题库中自主选择不少于 15 道算法题并完成解题&#xff0c;其中题目难度分配如下&#xff1a; 简单题不少于 10 道中等题不少于 4 道困难题不少于 1 道 解答代码 16.DNA 序列还原 &#xff08;简单&#xff09; 代码实现&#xff1a; public…

零基础Java第八期:一维数组(1)

目录 一、 一维数组的基本概念 1.1. 什么是数组 1.2. 数组的创建及初始化 1.3. 数组的使用 二、数组是引用类型 2.1. 初始JVM的内存分布 2.2. 基本类型变量与引用类型变量 2.3. 引用变量的理解 2.4. null 三、数组的应用场景 3.1. 作为函数的参数 3.2. 作为函数的返…

2024台州赛CTFwp

备注&#xff1a; 解题过程中&#xff0c;关键步骤不可省略&#xff0c;不可含糊其辞、一笔带过。解题过程中如是自己编写的脚本&#xff0c;不可省略&#xff0c;不可截图&#xff08;代码字体可以调小&#xff1b;而如果代码太长&#xff0c;则贴关键代码函数&#xff09;。…

【HarmonyOS NEXT】服务端向终端推送消息——获取Push Token

【需求】 获取Push Token 【文档】 https://developer.huawei.com/consumer/cn/doc/harmonyos-guides-V5/push-get-token-V5 【代码】 // EntryAbility.ets 文件 import { pushService } from kit.PushKit; export default class EntryAbility extends UIAbility {onCreat…

第T7周:咖啡豆识别

>- **&#x1f368; 本文为[&#x1f517;365天深度学习训练营](https://mp.weixin.qq.com/s/0dvHCaOoFnW8SCp3JpzKxg) 中的学习记录博客** >- **&#x1f356; 原作者&#xff1a;[K同学啊](https://mtyjkh.blog.csdn.net/)**难度&#xff1a;夯实基础⭐⭐语言&#xff…

Qt5.14.2 安装详细教程(图文版)

Qt 是一个跨平台的 C 应用程序开发框架&#xff0c;主要用于开发图形用户界面&#xff08;GUI&#xff09;程序&#xff0c;但也支持非 GUI 程序的开发。Qt 提供了丰富的功能库和工具&#xff0c;使开发者能够在不同平台上编写、编译和运行应用程序&#xff0c;而无需修改代码。…

如何通过CDN优化网站服务器访问速度?

CDN&#xff0c;即内容分发网络&#xff08;Content Delivery Network&#xff09;&#xff0c;在现代互联网中起着重要作用。它可以显著提升网站服务器的访问速度。以下是CDN在加速网站访问方面的主要优势及其工作原理。 1. 全球分布的服务器节点 CDN通过在全球范围内布设多个…

CANoe与C#联合仿真方案

引言 CANoe作为一款强大的网络仿真工具,能够模拟各种通信协议,尤其是在汽车领域的CAN、LIN、Ethernet等协议。而C#作为一种广泛使用的编程语言,能够为CANoe提供灵活的用户界面和逻辑控制。本文将探讨如何将CANoe与C#结合,实现高效的联合仿真方案。 1. 系统架构 联合仿真…

Python学习的自我理解和想法(16)

学的是b站的课程&#xff08;千锋教育&#xff09;&#xff0c;跟老师写程序&#xff0c;不是自创的代码&#xff01; 今天是学Python的第16天&#xff0c;从今天开始&#xff0c;每天一到两个常用模块&#xff0c;更完恢复到原来的。开学了&#xff0c;时间不多&#xff0c;写…

Bug:通过反射修改@Autowired注入Bean的字段,明确存在,报错 NoSuchFieldException

【BUG】通过Autowired注入了一个Bean SeqNo&#xff0c;测试的时候需要修改其中的字段。通过传统的反射&#xff0c;无论如何都拿不到信息&#xff0c;关键是一方面可以通过IDEA跳转&#xff0c;一方面debug也确实能看到这个字段。但是每次调用set方法报错&#xff1a;NoSuchFi…

Nuxt.js 应用中的 app:templatesGenerated 事件钩子详解

title: Nuxt.js 应用中的 app:templatesGenerated 事件钩子详解 date: 2024/10/19 updated: 2024/10/19 author: cmdragon excerpt: app:templatesGenerated 是 Nuxt.js 的一个生命周期钩子,在模板编译到虚拟文件系统(Virtual File System, VFS)之后被调用。这个钩子允许…