Next.js加载异步组件 骨架屏

Next.js 中有两种处理页面加载的方式,一种是 Loading UI 一种是 Streaming。接下来我将介绍这两种的区别,以及实际的业务场景。

当我们进入某个页面时,需要获取页面数据,可能是从数据库读取也有可能是 API 服务,总之这是一个异步任务,我们可以在获取数据过程中提示用户数据正在加载,比如放置一些骨架屏,提升用户的体验。

如果不对这些进行处理,使用体验会大打折扣。

假设我们有一个场景,进入 /posts 页面后获取所有的文章数据。

app/posts/page.tsx

import Link from "next/link";const PostsPage = async () => {const posts = await fetch("https://jsonplaceholder.typicode.com/posts").then((response) => response.json());// await new Promise((resolve) => setTimeout(resolve, 2000));return (<div className="p-10 max-w-3xl mx-auto"><ul className="list-decimal">{posts.map((post) => (<li key={post.id} className=""><h2 className="text-xl font-semibold my-2"><Link href={`/posts/${post.id}`} className="hover:underline">{post.title}</Link></h2><p>{post.body}</p></li>))}</ul></div>);
};export default PostsPage;

可以解开上面的注释延长加载时间。

如果我们从首页进入到 /posts 页面,不会立即进入,需要等待 await 之后才会进入页面,这个等待时间就取决于我们的网络了,当网络较差时,可能很久才获取数据,这就大大影响了用户体验。

Loading UI

在 posts 同级目录创建 app/posts/loading.tsx 文件:
(ps:我项目使用的 TypeScript,如果是 JavaScript 则为 jsx 后缀)

const PostsLoading = () => {return <p>Loading...</p>;
};export default PostsLoading;

这样当我们进入 /posts 页面后不会等待数据加载完成后才进入页面,而是直接进入 /posts 页面,数据加载过程中显示的内容为 loading.tsx 文件的内容,我们就可以写一些文字提示或者骨架屏之类的内容。

Streaming (Suspense)

另一种方式,也是比较推荐的方式:Streaming (Suspense),流式传输。

比如我们一个页面有多个异步组件,有文章、评论等等,如果我们使用上述第一种方案,页面会等所有的数据加载完成才渲染,而通过 Suspense 可以对每一个组件异步渲染。

image.png

React 18 引入了 Suspense 组件,支持在组件树中展示异步组件。Next.js 利用这一特性,让开发者可以定义一个组件在加载期间显示的备选内容。

通过 Suspense,你可以在组件等待数据时显示一个备用 UI,这样用户就不会看到不完整的空白界面。一旦数据加载完毕,React 将渲染实际的组件。这种异步加载方式特别适用于大型组件或数据,它们可能需要长时间来加载和渲染。

新建 app/posts2/page.tsx 文件:

import Link from "next/link";
import { Suspense } from "react";const Posts2Page = () => {return (<div><Suspense fallback={<PostsSkeleton />}><PostList /></Suspense></div>);
};const PostsSkeleton = () => {return (<div className="p-10 max-w-3xl mx-auto"><ul className="space-y-2 list-decimal">{[...Array(5).keys()].map((i) => (<li key={i} className="space-y-2"><divclassName="animate-pulse h-7 w-1/2 bg-slate-200 rounded duration-1000"style={{animationDelay: `${i * 0.05}s`,}}></div><divclassName="animate-pulse h-5 w-full bg-slate-200 rounded duration-1000"style={{animationDelay: `${i * 0.05}s`,}}></div><divclassName="animate-pulse h-5 w-3/4 bg-slate-200 rounded duration-1000"style={{animationDelay: `${i * 0.05}s`,}}></div></li>))}</ul></div>);
};const PostList = async () => {const posts = await fetch("https://jsonplaceholder.typicode.com/posts").then((response) => response.json());await new Promise((resolve) => setTimeout(resolve, 1000));return (<div className="p-10 max-w-3xl mx-auto"><ul className="list-decimal">{posts.map((post) => (<li key={post.id} className=""><h2 className="text-xl font-semibold my-2"><Link href={`/posts/${post.id}`} className="hover:underline">{post.title}</Link></h2><p>{post.body}</p></li>))}</ul></div>);
};export default Posts2Page;

Posts2Page 使用 Suspense 组件包裹 PostList 组件。当 PostList 组件在加载数据时,Suspense 会显示它的 fallback 属性,也就是 PostsSkeleton 组件。

PostsSkeleton 是一个骨架屏组件,用于在数据加载时显示。它会显示5个文章的占位符。

PostList 是一个异步组件,从 https://jsonplaceholder.typicode.com/posts 这个 URL 获取文章数据,然后显示出来。

2023-12-13_15-38-10.gif

最后,如果文章对您有所帮助,还希望能够点赞、收藏、关注,您的每一次点击都会为我带来无穷的动力来写出更好的文章。

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

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

相关文章

【人工智能革命】:AIGC时代的到来 | 探索AI生成内容的未来

&#x1f3a5; 屿小夏 &#xff1a; 个人主页 &#x1f525;个人专栏 &#xff1a; IT杂谈 &#x1f304; 莫道桑榆晚&#xff0c;为霞尚满天&#xff01; 文章目录 &#x1f4d1;前言一. AIGC 技术的概述和发展趋势1.1 AIGC 技术的概述1.2 AIGC 技术的发展趋势 二. AIGC 与元宇…

【C语言(十)】

字符函数和字符串函数 一、字符分类函数 C语言中有⼀系列的函数是专门做字符分类的&#xff0c;也就是⼀个字符是属于什么类型的字符的。这些函数的使用都需要包含⼀个头文件是 ctype.h 这些函数的使用方法非常类似&#xff0c;我们就讲解⼀个函数的事情&#xff0c;其他的非…

华为OD机试真题-多段线数据压缩-2023年OD统一考试(C卷)

题目描述: 下图中,每个方块代表一个像素,每个像素用其行号和列号表示。 为简化处理,多段线的走向只能是水平、竖直、斜向45度。 上图中的多段线可以用下面的坐标串表示:(2, 8), (3, 7), (3, 6), (3, 5), (4, 4), (5, 3), (6, 2), (7, 3), (8, 4), (7, 5)。 但可以发现,这…

springboot整合webflux访问openai接口报错

报错信息: org.springframework.web.reactive.function.client.WebClientRequestException: 远程主机强迫关闭了一个现有的连接。; nested exception is java.io.IOException: 远程主机强迫关闭了一个现有的连接。at org.springframework.web.reactive.function.client.Excha…

栈和队列的实现(Java篇)

文章目录 一、栈的概念二、栈的实现2.1压栈(push)2.2出栈(pop)2.3获取栈顶元素(peek)2.4判断栈是否为空(isEmpty)栈的实现测试 三、队列的概念四、队列的实现4.1入队(offer)4.2出队(poll)4.3判断队列是否为空4.4获取对头元素队列的实现测试 五、循环队列5.1入队5.2出队5.3获取队…

MAMOS蓝图: 打造自己的质量工程

针对团队中存在的问题&#xff0c;构造MAMOS蓝图&#xff0c;从而以系统化的方式识别并解决问题。本文将针对减少等待时间这一问题举例说明MAMOS蓝图的组成和使用方式。原文: MAMOS Blueprint: Build your own for Quality at Speed 很难完全摆脱等待时间。 我认为没有必要争论…

vue脚手架安装及使用

准备工作 安装node安装cnpm cnpm是npm的“廉价平替” 提高安装速度 npm install -g cnpm --registryhttps://registry.npm.taobao.org 安装脚手架 安装Vue脚手架 cnpm install -g vue/cli 用vue脚手架创建vue项目 找好创建项目的位置 创建项目 vue create test (test为项…

用代码写uml并在线生成uml图

可以用PlantUml写uml,并在线生成uml图。 startuml start:登录系统; if (用户名和密码正确?) then (yes):进入系统首页;:展示主菜单; else (no):显示登录错误;stop endif:选择模块; partition "课程信息" {:查看课程列表;:查看课程详情; } partition "课程签到…

【计算机视觉】SIFT

在边缘提取的时候&#xff0c;用高斯一阶导对信号进行卷积&#xff0c;响应值最大的就是边界如果用高斯二阶导对信号进行卷积&#xff0c;0点就是边界点&#xff08;二阶导等于0的点&#xff0c;对应一阶导的极值点&#xff09; 如果用高斯二阶导在不同的信号上进行卷积&#x…

python requests.Session()的使用

cookies and jar 你可以把Session理解成为它内部提供了一系列方法&#xff0c;用来存储状态。这里所说的状态&#xff0c;其实大部分情况下指的就是cookies。 比如使用浏览器时候&#xff0c;你在一个标签页内登陆了&#xff0c;另一个标签页其实就可以读取cookies了&#xf…

口袋参谋:新品上架,如何获取更多免费流量?

​新品上架 如何获得更多的免费流量&#xff1f; 我相信 这是99.999%的商家&#xff0c;都关心的问题&#xff01; 今天我就来和大家好好说道说道。 01 流量的组成 新品本身是没有权重的&#xff0c;买家搜不到我们。 如果想要获得更多的免费流量&#xff0c;我们就要知道…

基础算法(1):排序(1):选择排序

今天对算法产生了兴趣&#xff0c;开始学习基础算法&#xff0c;比如排序&#xff0c;模拟&#xff0c;贪心&#xff0c;递推等内容&#xff0c;算法是很重要的&#xff0c;它是解决某个问题的特定方法&#xff0c;程序数据结构算法&#xff0c;所以对算法的学习是至关重要的&a…

出现 Error:Unable to access jarfile xxxx\target\nacos-server.jar 解决方法

目录 1. 问题所示2. 原理分析3. 解决方法1. 问题所示 执行Nacos中的startup.cmd的时候出现闪退,于是在该脚本的最后一行添加pause,查看因为什么原因闪退 出现的bug如下所示:Error:Unable to access jarfile xxxx\target\nacos-server.jar 截图如下所示: 查看内部文件夹,…

塑料检查井配套开发了注塑成型的井盖、井筒、井座

塑料检查井配套开发的注塑成型井盖、井筒、井座——城市基础设施的新选择 随着城市化进程的加快&#xff0c;城市基础设施建设的品质与效率日益受到重视。在这个背景下&#xff0c;塑料检查井及其配套开发的注塑成型井盖、井筒、井座以其独特的优势&#xff0c;正在逐渐取代传…

k8s debug 浅谈

一 k8s debug 浅谈 说明&#xff1a; 本文只是基于对kubectl debug浅显认识总结的知识点,后续实际使用再补充案例 Kubernetes 官方出品调试工具上手指南(无需安装&#xff0c;开箱即用) debug-application 简化 Pod 故障诊断: kubectl-debug 介绍 1.18 版本之前需要自己…

DevEco Studio自定义代码颜色

这里以ArkTS代码颜色举例 进入设置&#xff08;快捷键CtrlAltS&#xff09; 选择Editor > Color Scheme > JavaScript 由于之前用习惯VsCode了&#xff0c;这里以注释颜色举例&#xff0c;变为绿色。 上面说的不是以ArkTS代码颜色举例吗&#xff1f;为什么选择JavaScr…

054:vue工具 --- BASE64加密解密互相转换

第054个 查看专栏目录: VUE ------ element UI 专栏目标 在vue和element UI联合技术栈的操控下&#xff0c;本专栏提供行之有效的源代码示例和信息点介绍&#xff0c;做到灵活运用。 &#xff08;1&#xff09;提供vue2的一些基本操作&#xff1a;安装、引用&#xff0c;模板使…

探索泰勒级数在机器学习中的作用:从函数逼近到模型优化

一、介绍 泰勒级数是数学中的一个基本概念&#xff0c;在机器学习领域有着重要的应用。本文将探讨泰勒级数的基础知识、它在机器学习中的相关性以及一些具体应用。 揭开复杂性&#xff1a;利用泰勒级数增强机器学习应用的理解和效率。 二、理解泰勒级数 在数学中&#xff0c;泰…

物联网AI 物联网平台学习之概述

学物联网&#xff0c;来万物简单IoT物联网&#xff01;&#xff01; 万物简单IOT是一个集物联网教育、企业SaaS私有化部署的物联网服务平台&#xff0c;它集成了设备管理、数据安全通信、消息订阅、规则引擎等一系列物联网核心能力&#xff0c;支持设备数据上云以及海量设备数…

大 O 表示法在机器学习中的重要性

一、介绍 在不断发展的机器学习领域&#xff0c;算法的效率至关重要。大 O 表示法成为这方面的一个关键工具&#xff0c;它提供了一种描述算法性能或复杂性的语言&#xff0c;特别是在时间和空间方面。本文探讨了 Big O 表示法在机器学习中的重要性&#xff0c;阐明了它在算法选…