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

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

目录

😀首屏与操作速度

🤣时间切片的使用


😀首屏与操作速度

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

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

渲染页面:渲染页面(数据请求以及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 + 500
        for(; 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 + 500
        for(; 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 = 0
    const sliceChecked = () => {
        requestAnimationFrame(() => {
            let target = index + 500
            for(; index < target; index++) {
                checkedList.push(dateArr[index].id)
            }
            if (index < dateArr.length) {
                sliceChecked()
            }
        })
    }
    sliceChecked()
}
</script>

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

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

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python解决解析汉诺塔问题

&#x1f468;‍&#x1f4bb;个人主页&#xff1a;开发者-曼亿点 &#x1f468;‍&#x1f4bb; hallo 欢迎 点赞&#x1f44d; 收藏⭐ 留言&#x1f4dd; 加关注✅! &#x1f468;‍&#x1f4bb; 本文由 曼亿点 原创 &#x1f468;‍&#x1f4bb; 收录于专栏&#xff1a…

如何选择适合自己的IP地址切换器

在互联网活动中&#xff0c;IP地址切换器成为越来越多用户的必备工具。本文旨在帮助用户了解如何选择适合自己的IP地址切换器&#xff0c;以确保网络活动的顺利进行。 ​一、IP地址切换器的基本功能与优势 IP地址切换器&#xff0c;又称IP代理软件或IP更换器&#xff0c;是一种…

计算机通信与网络实验笔记

1.LINUX通过版本号判断是否为稳定版本 2.计网基础 &#xff08;CD&#xff09;&#xff0c;默认二层以太网交换机。 &#xff08;10&#xff09;物理层是均分&#xff08;除以&#xff09;&#xff0c;数据链路层及以上是不除的。 3.传输介质&#xff1a; &#xff08;1&…

IDEA 中的代码调试指南

目录 前言1. 为什么进行代码调试1.1 找出错误1.2 优化代码1.3 提高对代码的理解 2. 如何在 IDEA 中进行代码调试2.1 设置断点2.1.1 普通断点2.1.2 条件断点 2.2 开始调试2.3 调试控制2.3.1 单步调试&#xff08;Step Over&#xff09;2.3.2 进入方法&#xff08;Step Into&…

打印自然常数E

自然常数E 自然常数&#xff0c;符号e&#xff0c;为数学中一个常数&#xff0c;是一个无限不循环小数&#xff0c;且为超越数&#xff0c;其值约为2.718281828459045。它是自然对数函数的底数。 我们打印表达式(11/x)的x次方的值以及获取第一次大于2.718的正整数 新建C#控制…

今日指数项目集成SpringSecurity

项目集成SpringSecurity ​ 在第一章我们是基于SpringSecurity、JWT技术实现前后端无状态化认证授权&#xff0c;而我们当前的项目是前后端分离的架构&#xff0c;同样也可借助Security框架和Jwt实现前后端的无状态认证授权操作&#xff1b; 1、项目自定义认证过滤器 1.1 依…

DFF对比

第一种 单元1&#xff1a;电平触发触发器&#xff1a; 在CLK高电平时&#xff0c;输入D的变化才可以传递到输出Q&#xff1b;在CLK点评时&#xff0c;输出Q不变。 第一种的整体 将两个电平触发组合&#xff0c;得到单边沿触发 输出Q仅在CLK上升沿处发生变化。边沿触发 第二…

MySQL-27.多表查询-案例

一.数据准备 -- 分类表 create table category (id int unsigned primary key auto_increment comment 主键ID,name varchar(20) not null unique comment 分类名称,type tinyint unsigned not null comment 类型 1 菜品分类 2 套餐分类,sort …

Quartus Ⅱ仿真 1.半加器

真服了&#xff0c;csdn上一搜全是收费&#xff0c;服啦服啦&#xff0c;我就自己来写一个吧 仿真波形&#xff1a; 输出结果&#xff1a; 介绍&#xff1a; 半加器&#xff08;Half Adder&#xff09;是数字电路中的一种基本组件&#xff0c;用于实现两个一位二进制数的加…

AI 代写是变现最快的副业项目,没有之一

AI 时代可以做的副业项目很多&#xff0c;但是实事求是的讲&#xff0c;大部分副业变现周期都有点长&#xff0c;短则几个月&#xff0c;长则半年到一年。所以很多副业社群都强调要坚持&#xff0c;当一项副业你能坚持一个月&#xff0c;基本就熬走了 90% 的人。但是坚持这件事…

ubuntu 安装haproxy

####安装##### sudo apt update sudo apt install haproxy sudo haproxy -v sudo systemctl status haproxy sudo cp /etc/haproxy/haproxy.cfg /etc/haproxy/haproxy.cfg-org####配置站点##### nano /etc/haproxy/haproxy.cfgfrontend www-httpbind *:5001mode httpdefault_ba…

复旦大学全球供应链研究中心揭牌,合合信息共话大数据赋能

10月13日&#xff0c;复旦大学全球供应链研究中心&#xff08;以下简称“中心”&#xff09;揭牌仪式在复旦大学管理学院政立院区隆重举行。我国的供应链体系庞大复杂&#xff0c;在百年未有之大变局下&#xff0c;保障产业链供应链安全已成为我国的重要战略目标。中心的设立旨…

Netty无锁化设计之对象池实现

池化技术是比较常见的一种技术&#xff0c;在平时我们已经就接触很多了&#xff0c;比如线程池&#xff0c;数据库连接池等等。当我们要使用一个资源的时候从池中去获取&#xff0c;用完就放回池中以便其他线程可以使用&#xff0c;这样的目的就是为了减少资源开销&#xff0c;…

Python | Leetcode Python题解之第485题最大连续1的个数

题目&#xff1a; 题解&#xff1a; class Solution:def findMaxConsecutiveOnes(self, nums: List[int]) -> int:maxCount count 0for i, num in enumerate(nums):if num 1:count 1else:maxCount max(maxCount, count)count 0maxCount max(maxCount, count)return …

100 种下划线 / 覆盖层动画 | 终极 CSS(层叠样式表)集合

还在为你的菜单项和链接寻找动画效果而感到疲惫吗&#xff1f; 不用再找了&#xff01;这里列出了 100 多种不同的动画。从简单的到更复杂的&#xff0c;你肯定能找到自己想要的。 无需 SVG&#xff08;可缩放矢量图形&#xff09;&#xff0c;无需 JavaScript&#xff08;脚…

八股面试2(自用)

mysql存储引擎 存储引擎&#xff1a;定义数据的存储方式&#xff0c;以及数据读取的实现逻辑 在以前数据库5.5默认MyISAM引擎&#xff0c;之后默认InnoDB引擎 MyISAM引擎的数据和索引是分开存储的&#xff0c;InnoDb将索引和文件存储在同一个文件。 MyISAM不支持事务&#…

程序员的选择难题:Java和C++的核心差异解析

我是小米,一个喜欢分享技术的29岁程序员。如果你喜欢我的文章,欢迎关注我的微信公众号“软件求生”,获取更多技术干货! Hello,大家好!我是小米,一个喜欢分享技术干货的程序猿。今天我们来聊一聊Java和C++的区别。作为两种非常流行的编程语言,Java和C++在各自的领域中都有…

成本决定未来——AIGC 下半场,高成本阻碍发展,我们该怎么办?

你好&#xff0c;我是三桥君 你最近有没有觉得工作中用到的那些 AI 工具好像越来越便宜了呢&#xff1f;这可不是偶然哦。 今天&#xff0c;三桥君就来聊聊为啥 AIGC 的下半场成本这么重要&#xff1f; 你想想看&#xff0c;咱平时工作已经够累了&#xff0c;要是再加上用那些贵…

vue3项目在vue平台下添加nvue文件会报[plugin:vite:nvue-css]

项目运行是会报大量的[plugin:vite:nvue-css]作警告 解决办法&#xff1a;在app.vue引入公共css文件外添加#ifndef APP-PLUS-NVUE条件 // #ifndef APP-PLUS-NVUE import "uview-plus/index.scss"; /*每个页面公共css */ import "colorui/main.css"; //#en…

【Linux】< 条件变量等待>解决< 线程饥饿问题 >——【多线程同步问题】

前言 大家好吖&#xff0c;欢迎来到 YY 滴Linux系列 &#xff0c;热烈欢迎&#xff01; 本章主要内容面向接触过C的老铁 主要内容含&#xff1a; 欢迎订阅 YY滴C专栏&#xff01;更多干货持续更新&#xff01;以下是传送门&#xff01; YY的《C》专栏YY的《C11》专栏YY的《Lin…