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

【Next.js 入门教程系列】09-优化技巧

原文链接

CSDN 的排版/样式可能有问题,去我的博客查看原文系列吧,觉得有用的话, 给我的库点个star,关注一下吧

上一篇【Next.js 入门教程系列】08-发送邮件

优化技巧

本篇包括以下内容:

  • Optimizing images
  • Using third-party JS libraries
  • Using custom fonts
  • Search engine optimizaion
  • Lazy loading

优化 image​

本章代码链接

在 Next.js 中需要加载静态图片时,可以使用 next/image 中的 Image 组件。其导入的图片也是以对象的形式 import 进来。同样也可以使用 url 的形式获取网络资源。在 Nextjs Image 页面可以看到它的更多用法

import Image from "next/image";
import RDR2 from "@/public/RDR2.png";export default async function Home() {const session = await getServerSession(authOptions);return (<>...<Image src={RDR2} alt="An image of RDR2" /><Image src="https://bit.ly/react-cover" alt="React cover" />...</>);
}

如果想要使用 url 的形式获取网络资源,出于安全原因,需要先在 next.config.js 中添加对应的域名才可以正常获取。添加好后需要重新运行项目就可以正常获取网络资源了

/** next.config.js*//** @type {import('next').NextConfig} */
const nextConfig = {images: {remotePatterns: [{protocol: "https",hostname: "bit.ly",},],},
};module.exports = nextConfig;

使用 <Image> 标签的好处是,可以将图片转为 webp 格式,极大的减少 Size,比如这张图原图大小为 2.08MB,可以看到实际上网页里的只有 28.1KB

Image Size

使用第三方脚本​

在使用第三方 js 脚本的时候,我们可以将其封装为一个 component,然后在对应的 layout.tsx 中直接使用即可。注意应使用 Next 的 <Script> 标签。若有识别不出 js 语法的问题,可以用 {``} 将 js 代码包裹起来

字体​

本章代码链接

网络字体​

想要使用其他的官方字体,我们只需要在 layout.tsx 中从 "next/font" 中导入,并在对应标签的 className 中设置即可。比如下面就是使用 Roboto 字体的演示。在Google Fonts这里可以找到各种 Google 字体。在使用这种官方字体库时,仅在第一次使用时会去下载这个字体文件,后面会一直使用下载好的文件,不必担心由于网络问题导致字体出错

# layout.tsximport "./globals.css";
import type { Metadata } from "next";
// import 字体
import { Inter, Roboto } from "next/font/google";
import NavBar from "./NavBar";
import AuthProvider from "./auth/Provider";const inter = Inter({ subsets: ["latin"] });
// 调用字体
const roboto = Roboto({ subsets: ["latin"], weight: ["400", "500"] });export const metadata: Metadata = {title: "Create Next App",description: "Generated by create next app",
};export default function RootLayout({children,
}: {children: React.ReactNode;
}) {return (<html lang="en" data-theme="winter">{/* 设置字体 */}<body className={roboto.className}><AuthProvider><NavBar /><main className="p-5">{children}</main></AuthProvider></body></html>);
}

本地字体​

同样的,我们也可以使用本地字体。这里以 poppings 字体为例。首先将下载好的文件放到 "public/fonts" 中。然后和官方字体一样,在 layout.tsx 中调用

# layout.tsximport "./globals.css";
import type { Metadata } from "next";
import { Inter, Roboto } from "next/font/google";
// import 字体
import localFont from "next/font/local";
import NavBar from "./NavBar";
import AuthProvider from "./auth/Provider";const inter = Inter({ subsets: ["latin"] });
const roboto = Roboto({ subsets: ["latin"], weight: ["400", "500"] });
// 设置source和变量名(用于TailWind)
const poppins = localFont({src: "../public/fonts/Poppins-Regular.ttf",variable: "--font-poppings",
});export const metadata: Metadata = {title: "Create Next App",description: "Generated by create next app",
};export default function RootLayout({children,
}: {children: React.ReactNode;
}) {return (<html lang="en" data-theme="winter">{/* 设置字体,注意使用 .variable 而不是 .className */}<body className={poppins.variable}><AuthProvider><NavBar /><main className="p-5">{children}</main></AuthProvider></body></html>);
}

除此之外,我们可以将自定义字体注册到 TailWind 中:

  # tailwind.config.tsimport type { Config } from "tailwindcss";const config: Config = {content: ["./pages/**/*.{js,ts,jsx,tsx,mdx}","./components/**/*.{js,ts,jsx,tsx,mdx}","./app/**/*.{js,ts,jsx,tsx,mdx}",],theme: {extend: {backgroundImage: {"gradient-radial": "radial-gradient(var(--tw-gradient-stops))","gradient-conic":"conic-gradient(from 180deg at 50% 50%, var(--tw-gradient-stops))",},// 注册字体,其 var 就是刚刚设置的 variable
+       fontFamily: {
+         poppins: "var(--font-poppings)",
+       },},},plugins: [require("daisyui")],daisyui: ["winter"],};export default config;

注册好之后,就可以像下面这样使用

<h1 className="font-poppins">Hello World!</h1>

同样也可以直接应用到 global.css 中 来覆盖所有的 h1 标签

@layer base {h1 {@apply font-extrabold text-2xl mb-3 font-poppins;}
}

搜索引擎优化​

本章代码链接

我们可以在每个 pag.tsx 中添加以下内容,包括每页的题目和描述等内容

import { Metadata } from "next";export const metadata: Metadata = {title: "...",description: "...",
};

我们也可以根据某些数据来自动生成 metadata,比如从 API 或者数据库中获取数据

import { Metadata } from "next";export async function generateMetada(): Promise<Metadata> {const metaData = await fetch("");return {title: "metaData.title",description: "...",};+
}

Lazy Loading​

本章代码链接

在某些页面可能存在过多的组件,而且这些组件并不是一进到页面就会显示的,比如点击某个 button 才会显示,此时如果组件的数据量过于庞大(比如一个富文本编辑器),就会导致加载十分缓慢,此时就可以用到 Lazy Loading。在下面的演示中,我们的 HeavyComponent 不用一开始就 import 进来,而是使用 dynamic 函数进行导入,会自动在需要的时候导入,我们还可以设置 loading 函数,让其在加载时有占位符

- import HeavyComponent from "./components/HeavyComponent";
+ import dynamic from "next/dynamic";
+ const HeavyComponent = dynamic(() => import("./components/HeavyComponent"), {
+   ssr: false,
+   loading: () => <p>Loading...</p>,
+ });export default async function Home() {const [show, setShow] = useState(false);return (...<button onClick={() => setShow(true)}>Show</button>Show && <HeavyComponent />...);}

同样的,比如我们需要用到某个函数,我们也可以使用 import 函数来进行 Lazy Loading

<button onClick={()=>{_ = import("./components/sort");const item = []_.sort(item,asec);
}}>Sort<>

 下一篇讲部署

下一篇【Next.js 入门教程系列】10-部署

相关文章:

【Next.js 入门教程系列】09-优化技巧

原文链接 CSDN 的排版/样式可能有问题&#xff0c;去我的博客查看原文系列吧&#xff0c;觉得有用的话&#xff0c; 给我的库点个star&#xff0c;关注一下吧 上一篇【Next.js 入门教程系列】08-发送邮件 优化技巧 本篇包括以下内容: Optimizing imagesUsing third-party JS…...

Windows 11 开发详解:工具与高级用法

1. 引言 Windows 11 是微软最新的操作系统&#xff0c;它不仅带来了全新的用户界面和设计理念&#xff0c;还为开发者提供了强大的开发工具和平台支持。在过去的几年中&#xff0c;开发工具和技术栈发生了巨大的变化&#xff0c;Windows 11 通过其集成的开发环境、虚拟化技术、…...

leetcode 292.Nim游戏

思路&#xff1a;数学 这有一点博弈论的味道&#xff0c;但是我们依然可以用数学的角度去思考。 我们的入手点在这里&#xff1a; 我们是先手的前提下&#xff0c;一共有4个石头&#xff0c;但是每个人只能一次拿其中的1-3个。在一共有4个石头的情况下&#xff0c;我们无论拿…...

《最优化方法》

课件是学习的核心内容 这门课&#xff0c;作业自己交&#xff0c;但是老师不做记录&#xff0c;上课不点名&#xff0c; 不记录平时成绩。 第一章 最优化问题的概述 1.1 概述&#xff08;和考试内容无关&#xff0c;了解内容&#xff09; 例题1.1.1运输问题 数学模型&#x…...

fork中的死锁问题

背景 当我们通过fork去创建子进程时&#xff0c;当父/子进程都涉及到锁的操作&#xff0c;可能会产生死锁。 代码样例 #include <iostream> #include <mutex> #include <unistd.h> std::mutex m; int main() {std::cout << "main process begi…...

Java面试题———SpringBoot篇

目录 1、项目中为什么选择SpringBoot 2、SpringBoot的自动装配原理 3、SpringBoot的核心注解是哪个 4、SpringBoot中的starter是干什么的 5、SpringBoot可以有哪些方式加载配置 6、bootstrap.yml和application.yml有何区别 7、SpringBoot读取配置的方式有几种 8、Spring…...

模块化沙箱:构建零信任架构的关键技术

在数字化时代&#xff0c;数据安全成为了企业和机构关注的焦点。模块化沙箱作为一种创新的数据安全解决方案&#xff0c;正逐渐成为保护敏感信息的有力工具。深信达模块化沙箱&#xff0c;凭借其高灵活性和高扩展性&#xff0c;为不同安全需求提供了定制化的解决方案。 模块化沙…...

10.14学习日志

一.矩阵 接上篇 11.伴随矩阵 设 A 是一个 nn 的方阵&#xff0c;其元素为 aij。伴随矩阵 adj(A)或A* 是一个 nn的矩阵&#xff0c;其第 i 行第 j 列的元素是 A 的余子式 Mji 的代数余子式 Cji&#xff0c;即&#xff1a; 其中 Mji是 A 的第j 行第i 列元素的余子式&#xff0…...

“我们为什么缺少科学精神”演讲内容拆解

演讲人张双南&#xff0c;视频链接&#xff1a; https://tv.cctv.com/2017/04/23/VIDEdqzdpmxStYXAmYBdgDP7170423.shtml...

openpyxl 3.0.7 中文教程

openpyxl 3.0.7 中文教程 python Execl 处理库教程 https://openpyxl-chinese-docs.readthedocs.io/zh-cn/latest/tutorial.html#id2 案例&#xff1a; 生成表格&#xff0c;设置单元格样式 from openpyxl import Workbook from openpyxl.styles import Font, Border, Side, …...

idea开发工具使用

idea开发工具使用 1.idea下载 2.idea设置 字体 编码格式 换行 忽略大小写 自动导包 各方法之间加横线 3.快捷键 4.导入工程 5.安装scala插件 6.运行代码 7.导入jar包 8.git托管 9.打jar包...

Android map 获取值

Android Map 获取值的完整指南 在Android开发中&#xff0c;使用Map&#xff08;映射&#xff09;来存储和检索数据是非常常见的需求。Map是一种键值对集合&#xff0c;能够快速而高效地根据特定的键获取值。在这篇文章中&#xff0c;我们将深入探讨如何在Android应用中使用Ma…...

Leetcode.13 罗马数字转整数

关键词&#xff1a;to_string, string.size(), string.length() 1.题目 2.解答思路及解答 解答思路&#xff1a; 首先&#xff0c;罗马数字表达中和常规数学表达类似&#xff0c;基本是按照从后往前&#xff0c;从小到大排列。因此&#xff0c;理论上只需要从后往前相加即可。…...

骨架提取(持续更新)

一 什么是骨架提取 1.1 简介 骨架提取是图像处理或计算机视觉中的一种技术&#xff0c;用于从二值化图像中提取物体的中心线或轮廓&#xff0c;通常称为“骨架”或“细化图像”。这一技术主要用于简化形状表示&#xff0c;同时保留物体的拓扑结构。 这里我们强调了&#xff…...

B3622 枚举子集

1. 注意dfs内&#xff0c;for循环的遍历&#xff0c;想清楚把什么赋值给a[x] 2.本题只需要把0或1赋值给a[x]所以 #include<bits/stdc.h> using namespace std; int n; int a[20]; int vis[20]; void pr() {for (int i 1; i < n; i) {if (a[i] 0)cout << N;els…...

git submodule add用法

背景 介绍 git submodule add 命令用于将一个 Git 仓库作为子模块添加到另一个 Git 仓库中。子模块是一个独立的 Git 仓库&#xff0c;但它被嵌套在另一个 Git 仓库中&#xff0c;并且可以通过主仓库进行管理。当你需要在主项目中引用另一个项目&#xff08;子模块&#xff09…...

计算机毕业设计 基于Python的汽车销售管理系统的设计与实现 Python毕业设计 Python毕业设计选题【附源码+安装调试】

博主介绍&#xff1a;✌从事软件开发10年之余&#xff0c;专注于Java技术领域、Python人工智能及数据挖掘、小程序项目开发和Android项目开发等。CSDN、掘金、华为云、InfoQ、阿里云等平台优质作者✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精…...

主流的安全测试工具知识点

1. 静态应用安全测试&#xff08;SAST&#xff09;工具 工具示例: SonarQube: 支持多种编程语言的代码质量和安全分析。Checkmarx: 提供全面的代码扫描和漏洞检测。知识点: 分析源代码或二进制代码以发现潜在的安全漏洞。早期发现和修复代码中的安全问题&#xff0c;减少修复成…...

如何接入实时期货行情数据 - 2024最新教程

期货市场通过标准化合约的交易&#xff0c;为投资者提供了在大宗商品、金融工具等方面进行风险对冲和投机的机会。量化交易以计算机模型为核心&#xff0c;通过历史数据和实时数据进行分析和策略执行&#xff0c;减少人为情绪对交易的干扰。由于期货市场的波动性强且价格变化迅…...

通义灵码:AI 编码的强大助力

一、通义灵码简介 通义灵码是阿里云推出的智能编码辅助工具&#xff0c;以通义大模型为基础&#xff0c;提供多种强大功能助力开发者高效编码。 通义灵码集成了行级 / 函数级实时续写、自然语言生成代码、单元测试生成、代码注释生成、代码解释、研发智能问答、异常报错排查等…...

Chapter03-Authentication vulnerabilities

文章目录 1. 身份验证简介1.1 What is authentication1.2 difference between authentication and authorization1.3 身份验证机制失效的原因1.4 身份验证机制失效的影响 2. 基于登录功能的漏洞2.1 密码爆破2.2 用户名枚举2.3 有缺陷的暴力破解防护2.3.1 如果用户登录尝试失败次…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻

在如今就业市场竞争日益激烈的背景下&#xff0c;越来越多的求职者将目光投向了日本及中日双语岗位。但是&#xff0c;一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧&#xff1f;面对生疏的日语交流环境&#xff0c;即便提前恶补了…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...

云原生玩法三问:构建自定义开发环境

云原生玩法三问&#xff1a;构建自定义开发环境 引言 临时运维一个古董项目&#xff0c;无文档&#xff0c;无环境&#xff0c;无交接人&#xff0c;俗称三无。 运行设备的环境老&#xff0c;本地环境版本高&#xff0c;ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

GitFlow 工作模式(详解)

今天再学项目的过程中遇到使用gitflow模式管理代码&#xff0c;因此进行学习并且发布关于gitflow的一些思考 Git与GitFlow模式 我们在写代码的时候通常会进行网上保存&#xff0c;无论是github还是gittee&#xff0c;都是一种基于git去保存代码的形式&#xff0c;这样保存代码…...

Go语言多线程问题

打印零与奇偶数&#xff08;leetcode 1116&#xff09; 方法1&#xff1a;使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...

go 里面的指针

指针 在 Go 中&#xff0c;指针&#xff08;pointer&#xff09;是一个变量的内存地址&#xff0c;就像 C 语言那样&#xff1a; a : 10 p : &a // p 是一个指向 a 的指针 fmt.Println(*p) // 输出 10&#xff0c;通过指针解引用• &a 表示获取变量 a 的地址 p 表示…...

【Kafka】Kafka从入门到实战:构建高吞吐量分布式消息系统

Kafka从入门到实战:构建高吞吐量分布式消息系统 一、Kafka概述 Apache Kafka是一个分布式流处理平台,最初由LinkedIn开发,后成为Apache顶级项目。它被设计用于高吞吐量、低延迟的消息处理,能够处理来自多个生产者的海量数据,并将这些数据实时传递给消费者。 Kafka核心特…...

leetcode_69.x的平方根

题目如下 &#xff1a; 看到题 &#xff0c;我们最原始的想法就是暴力解决: for(long long i 0;i<INT_MAX;i){if(i*ix){return i;}else if((i*i>x)&&((i-1)*(i-1)<x)){return i-1;}}我们直接开始遍历&#xff0c;我们是整数的平方根&#xff0c;所以我们分两…...