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

【前端】Next.js 服务器端渲染(SSR)与客户端渲染(CSR)的最佳实践

关于Next.js 服务器端渲染(SSR)与客户端渲染(CSR)的实践内容方面,我们按下面几点进行阐述。
在这里插入图片描述

1. 原理
  • 服务器端渲染 (SSR): 在服务器上生成完整的HTML页面,然后发送给客户端。这使得用户在首次访问时能够看到一个完整的页面,而不是等待JavaScript加载后再显示内容。
  • 客户端渲染 (CSR): 页面初始加载时通常是一个空壳或简单的HTML结构,所有内容通过JavaScript动态加载和渲染。
2. 构建方式
  • SSR:

    • getServerSideProps: 用于在每个请求时获取数据,并在服务器端渲染页面。适用于需要频繁更新的数据。
      // pages/index.js
      export async function getServerSideProps(context) {const res = await fetch(`https://api.example.com/data`);const data = await res.json();return {props: {data,},};
      }function HomePage({ data }) {return (<div><h1>Welcome to the Home Page</h1><p>Data: {JSON.stringify(data)}</p></div>);
      }export default HomePage;
      
    • getStaticProps: 用于在构建时预渲染页面,并且可以设置定时重新验证以更新静态生成的页面。适用于不经常变化的数据。
      // pages/about.js
      export async function getStaticProps() {const res = await fetch(`https://api.example.com/static-data`);const data = await res.json();return {props: {data,},revalidate: 60, // 每60秒重新验证一次};
      }function AboutPage({ data }) {return (<div><h1>About Us</h1><p>Data: {JSON.stringify(data)}</p></div>);
      }export default AboutPage;
      
    • getInitialProps: 用于自定义服务器端渲染逻辑,但建议使用getServerSidePropsgetStaticProps,因为它们提供了更好的性能和灵活性。
  • CSR:

    • 初始页面加载后,通过API调用或从本地存储中获取数据,并使用React或其他前端框架进行渲染。
    • 客户端需要支持JavaScript以正确显示页面内容。
      // pages/profile.js
      import { useEffect, useState } from 'react';function ProfilePage() {const [data, setData] = useState(null);useEffect(() => {fetch('/api/profile').then((res) => res.json()).then((data) => setData(data));}, []);if (!data) {return <div>Loading...</div>;}return (<div><h1>Profile Page</h1><p>Name: {data.name}</p><p>Email: {data.email}</p></div>);
      }export default ProfilePage;
      
3. 性能
  • SSR:
    • 优点:
      • 提供了更快的首屏加载时间,因为浏览器接收到的是完整的HTML页面。
      • 改善用户体验,特别是对于网络条件较差的用户。
      • 有利于SEO,搜索引擎可以直接读取到完整的HTML内容。
    • 缺点:
      • 每次请求都需要服务器处理,对于高并发场景可能造成性能瓶颈。
      • 需要更多的服务器资源来处理请求。
  • CSR:
    • 优点:
      • 一旦页面加载完成,后续的交互可以非常快,因为大部分工作由客户端承担。
      • 适合单页应用(SPA),提供流畅的用户体验。
    • 缺点:
      • 初始加载时间较长,特别是当应用依赖于大量JavaScript资源时。
      • 对于低性能设备或网络条件较差的用户,体验可能不佳。
4. 安全
  • SSR:
    • 更容易实现SEO优化,因为搜索引擎可以直接读取到完整的HTML内容。
    • 可以在服务器端对敏感操作进行安全检查,如身份验证、权限控制等。
    • 减少XSS攻击的风险,因为大部分内容是在服务器端生成的。
  • CSR:
    • 对于一些需要即时响应的应用来说,安全性可能更高,因为很多逻辑可以在客户端执行。
    • 但同时,也需要更加小心地处理客户端的安全问题,如XSS攻击、CSRF攻击等。
    • 需要确保API的安全性,防止未授权访问。
5. 学习成本
  • SSR:
    • 需要了解服务器端编程以及如何处理异步数据获取。
    • 如果使用Next.js,学习曲线相对较低,因为它提供了许多内置功能来简化开发过程。
    • 需要熟悉Node.js环境和服务器配置。
  • CSR:
    • 主要集中在前端技术栈的学习,如React、Vue等。
    • 对于初学者来说,可能更容易上手,尤其是那些已经熟悉JavaScript和现代前端框架的人。
    • 不需要深入了解服务器端编程,但需要掌握前端状态管理和路由管理。
6. 优势
  • SSR:
    • 良好的SEO表现。
    • 更快的首屏加载速度。
    • 支持更复杂的业务逻辑直接在服务器端处理。
    • 适合需要频繁更新数据的应用。
  • CSR:
    • 优秀的用户体验,特别是在单页应用(SPA)中。
    • 更加灵活的数据更新机制。
    • 简化了前后端分离的架构设计。
    • 适合需要复杂交互的应用。
7. 监测
  • SSR:
    • 可以利用传统的Web日志分析工具来监控服务器性能。
    • 需要注意服务器负载和响应时间。
    • 使用工具如New Relic、Datadog等进行性能监控。
  • CSR:
    • 侧重于前端性能监测,如页面加载时间、JavaScript执行效率等。
    • 可以使用Google Lighthouse等工具来进行综合评估。
    • 使用工具如Sentry、LogRocket等进行错误跟踪和用户体验监控。
8. 最佳实践
  • SSR:

    • 减少服务器端渲染的内容:只渲染必要的部分,避免不必要的计算和数据传输。
    • 合理使用缓存策略:使用getStaticProps结合revalidate选项来实现静态生成并按需更新。
    • 优化图片和其他静态资源的加载:使用CDN、压缩图片、懒加载等技术。
    • 避免阻塞渲染:确保关键路径上的资源尽快加载,例如CSS和JavaScript文件。
    • 代码分割:将代码分割成多个小块,按需加载,提高性能。
      // next.config.js
      module.exports = {experimental: {modern: true,},webpack(config) {config.optimization.splitChunks({chunks: 'all',});return config;},
      };
      
  • CSR:

    • 实现懒加载组件:只有当它们进入视口时才加载。
      // components/LazyImage.js
      import { useEffect, useState } from 'react';function LazyImage({ src, alt }) {const [isLoaded, setIsLoaded] = useState(false);useEffect(() => {const img = new Image();img.src = src;img.onload = () => setIsLoaded(true);}, [src]);return isLoaded ? <img src={src} alt={alt} /> : null;
      }export default LazyImage;
      
    • 使用代码分割:减少初始加载时间。
      // pages/lazy-loaded-page.js
      import dynamic from 'next/dynamic';const DynamicComponent = dynamic(() => import('../components/DynamicComponent'), {ssr: false,
      });function LazyLoadedPage() {return (<div><h1>Lazy Loaded Page</h1><DynamicComponent /></div>);
      }export default LazyLoadedPage;
      
    • 优化JavaScript打包大小:去除不必要的库和代码。
      // package.json
      "scripts": {"analyze": "cross-env ANALYZE=true next build"
      }
      
    • 使用性能分析工具:如Webpack Bundle Analyzer来分析和优化打包结果。
      npm run analyze
      
9. 结合使用
  • 在实际项目中,通常会根据需求结合使用SSR和CSR。例如,首页和其他重要页面可以采用SSR以提供更好的SEO和初始加载体验;而其他交互性较强的部分则可以使用CSR来提高用户体验。
  • 混合模式:在同一个页面中,可以部分使用SSR,部分使用CSR。
    // pages/mixed-mode.js
    import { useEffect, useState } from 'react';export async function getServerSideProps(context) {const res = await fetch(`https://api.example.com/initial-data`);const initialData = await res.json();return {props: {initialData,},};
    }function MixedModePage({ initialData }) {const [dynamicData, setDynamicData] = useState(initialData);useEffect(() => {fetch('/api/dynamic-data').then((res) => res.json()).then((data) => setDynamicData(data));}, []);return (<div><h1>Mixed Mode Page</h1><p>Initial Data: {JSON.stringify(initialData)}</p><p>Dynamic Data: {JSON.stringify(dynamicData)}</p></div>);
    }export default MixedModePage;
    

总结

通过上述详细说明和示例代码,我们可以更好地理解Next.js中的服务器端渲染(SSR)与客户端渲染(CSR)的区别及其最佳实践。选择合适的渲染方式取决于具体的应用场景和需求。在实际开发中,通常会结合使用两种方式,以达到最佳的性能和用户体验。此外,通过合理的架构设计、代码优化和性能监控,可以进一步提升应用的整体质量和用户体验。

相关文章:

【前端】Next.js 服务器端渲染(SSR)与客户端渲染(CSR)的最佳实践

关于Next.js 服务器端渲染&#xff08;SSR&#xff09;与客户端渲染&#xff08;CSR&#xff09;的实践内容方面&#xff0c;我们按下面几点进行阐述。 1. 原理 服务器端渲染 (SSR): 在服务器上生成完整的HTML页面&#xff0c;然后发送给客户端。这使得用户在首次访问时能够…...

路径规划之启发式算法之一:A-Star(A*)算法

A*算法是一种启发式搜索算法&#xff0c;常用于解决路径规划问题。 一、A*算法的定义与原理 A*算法是一种用于在图形或网格中查找最短路径的算法。它在搜索过程中综合考虑了每个节点的实际距离&#xff08;g值&#xff09;和预估距离&#xff08;h值&#xff09;&#xff0c;以…...

Android复习代码1-4章

public class RudioButton extends AppCompatActivity {Overrideprotected void onCreate(Nullable Bundle savedInstanceState) {super.onCreate(savedInstanceState);setContentView(R.layout.activity_rudio_button);// 找到RadioGroup和TextView的实例RadioGroup radioGrou…...

【问题】webdriver.Chrome()设置参数executable_path报不存在

场景1: 标红报错unresolved reference executable_path 场景2: 执行报错TypeError: __init__() got an unexpected keyword argument executable_path 原因&#xff1a; 上述两种场景是因为selenium4开始不再支持某些初始化参数。比如executable_path 解决&#xff1a; 方案…...

win10系统安装docker-desktop

1、开启Hyper-v ———————————————— Hyper-V 是微软提供的一种虚拟化技术&#xff0c;它允许你在同一台物理计算机上运行多个独立的操作系统实例。这种技术主要用于开发、测试、以及服务器虚拟化等领域。 —————————————————————— &#…...

小程序-基于java+SpringBoot+Vue的乡村研学旅行平台设计与实现

项目运行 1.运行环境&#xff1a;最好是java jdk 1.8&#xff0c;我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境&#xff1a;IDEA&#xff0c;Eclipse,Myeclipse都可以。推荐IDEA; 3.tomcat环境&#xff1a;Tomcat 7.x,8.x,9.x版本均可 4.硬件环境&#xff1a…...

组件A底部栏(position: fixed )事件使用$emit更新内容失败bug解决

今天遇到一个很离奇的bug&#xff0c;记录一下 问题&#xff1a;在组件内底部栏使用$emit触发按钮事件但打印出来的值是初始化的值&#xff0c;更新的值被重置导致更新失败 原因&#xff1a;组件内底部使用了 position: fixed; 固定&#xff0c; 导致组件内插槽 this 与 保存按…...

数据结构——排序第三幕(深究快排(非递归实现)、快排的优化、内省排序,排序总结)超详细!!!!

文章目录 前言一、非递归实现快排二、快排的优化版本三、内省排序四、排序算法复杂度以及稳定性的分析总结 前言 继上一篇博客基于递归的方式学习了快速排序和归并排序 今天我们来深究快速排序&#xff0c;使用栈的数据结构非递归实现快排&#xff0c;优化快排&#xff08;三路…...

C++的类功能整合

1. 类的基本概念 类是面向对象编程的核心&#xff0c;它封装了数据和操作数据的函数。 #include <iostream> using namespace std;class MyClass { public:int publicData;void publicFunction() {cout << "Public function" << endl;}private:i…...

《String类》

目录 一、定义与概述 二、创建字符串对象 2.1 直接赋值 2.2 使用构造函数 三、字符串的不可变性 四、常用方法 4.1 String对象的比较 4.1.1 比较是否引用同一个对象 4.1.2 boolean equals(Object anObject)方法&#xff1a;按照字典序比较 4.1.3 int compareTo(Strin…...

【docker】docker的起源与容器的由来、docker容器的隔离机制

Docker 的起源与容器的由来 1. 虚拟机的局限&#xff1a;容器的需求萌芽 在 Docker 出现之前&#xff0c;开发和部署软件主要依赖虚拟机&#xff08;VMs&#xff09;&#xff1a; 虚拟机通过模拟硬件运行操作系统&#xff0c;每个应用程序可以运行在自己的独立环境中。虽然虚…...

Window 安装 Nginx

参考链接 Windows 环境nginx安装使用及目录结构详解_windows 安装nginx-CSDN博客 Nginx 安装及配置教程&#xff08;Windows&#xff09;【安装】_nginx下载安装-CSDN博客 安装 1&#xff09;下载 nginx: download 2&#xff09;解压 3&#xff09;启动 3.1&#xff09;方…...

replace (regexp|substr, newSubstr|function)替换字符串中的指定部分

replace 方法用于替换字符串中的指定部分。它可以接受一个子字符串或正则表达式作为第一个参数&#xff0c;第二个参数是替换的内容。 用法示例 基本替换 let str "Hello, world!"; let newStr str.replace("world", "everyone"); console.lo…...

【ROS2】Ubuntu22.04安装ROS humble

一. ROS简介 1.1 什么是ROS ROS 是一个适用于机器人的开源的元操作系统。它提供了操作系统应有的服务&#xff0c;包括硬件抽象&#xff0c;底层设备控制&#xff0c;常用函数的实现&#xff0c;进程间消息传递&#xff0c;以及包管理。ROS的核心思想就是将机器人的软件功能做…...

cesium 3Dtiles变量

原本有一个变亮的属性luminanceAtZenith&#xff0c;但是新版本的cesium没有这个属性了。于是 let lightColor 3.0result._customShader new this.ffCesium.Cesium.CustomShader({fragmentShaderText:void fragmentMain(FragmentInput fsInput, inout czm_modelMaterial mate…...

配置泛微e9后端开发环境

配置泛微e9的后端开发环境 1.安装jdk1.8&#xff08;请自行安装并设置环境变量&#xff09; 2.将服务器上的WEARVER文件夹拷贝到开发环境下(其中要包含ecology和Resin目录) 3.通过idea创建一个基础Java项目,将jdk设置为1.8 4.添加依赖,需要将3个文件夹的所有jar包添加到项目中…...

【Stable Diffusion】安装教程

目录 一、python 安装教程 二、windows cuda安装教程 三、Stable Diffusion下载 四、Stable Diffusion部署&#xff08;重点&#xff09; 一、python 安装教程 &#xff08;1&#xff09;第一步下载 打开python下载页面&#xff0c;找到python3.10.9&#xff0c;点击右边…...

USB Type-C一线通扩展屏:多场景应用,重塑高效办公与极致娱乐体验

在追求高效与便捷的时代&#xff0c;启明智显USB Type-C一线通扩展屏方案正以其独特的优势&#xff0c;成为众多职场人士、娱乐爱好者和游戏玩家的首选。这款扩展屏不仅具备卓越的性能和广泛的兼容性&#xff0c;更能在多个应用场景中发挥出其独特的价值。 USB2.0显卡&#xff…...

【力扣】541.反转字符串2

问题描述 思路解析 每当字符达到2*k的时候&#xff0c;判断&#xff0c;同时若剩余字符>k,只对前k个进行判断&#xff08;这是重点&#xff09;因为字符串是不可变变量&#xff0c;所以将其转化为字符串数组&#xff0c;最后才将结果重新转变为字符串 字符串->字符数组 …...

什么是防抖与节流

防抖&#xff08;Debouncing&#xff09;与节流&#xff08;Throttling&#xff09; 在前端开发中&#xff0c;尤其是在处理用户输入、窗口调整大小、滚动事件等高频率触发的事件时&#xff0c;防抖和节流是两种常用的技术手段。它们可以帮助我们优化性能&#xff0c;减少不必…...

多场景 OkHttpClient 管理器 - Android 网络通信解决方案

下面是一个完整的 Android 实现&#xff0c;展示如何创建和管理多个 OkHttpClient 实例&#xff0c;分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端

&#x1f31f; 什么是 MCP&#xff1f; 模型控制协议 (MCP) 是一种创新的协议&#xff0c;旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议&#xff0c;它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

解锁数据库简洁之道:FastAPI与SQLModel实战指南

在构建现代Web应用程序时&#xff0c;与数据库的交互无疑是核心环节。虽然传统的数据库操作方式&#xff08;如直接编写SQL语句与psycopg2交互&#xff09;赋予了我们精细的控制权&#xff0c;但在面对日益复杂的业务逻辑和快速迭代的需求时&#xff0c;这种方式的开发效率和可…...

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

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

【服务器压力测试】本地PC电脑作为服务器运行时出现卡顿和资源紧张(Windows/Linux)

要让本地PC电脑作为服务器运行时出现卡顿和资源紧张的情况&#xff0c;可以通过以下几种方式模拟或触发&#xff1a; 1. 增加CPU负载 运行大量计算密集型任务&#xff0c;例如&#xff1a; 使用多线程循环执行复杂计算&#xff08;如数学运算、加密解密等&#xff09;。运行图…...

JS设计模式(4):观察者模式

JS设计模式(4):观察者模式 一、引入 在开发中&#xff0c;我们经常会遇到这样的场景&#xff1a;一个对象的状态变化需要自动通知其他对象&#xff0c;比如&#xff1a; 电商平台中&#xff0c;商品库存变化时需要通知所有订阅该商品的用户&#xff1b;新闻网站中&#xff0…...

NXP S32K146 T-Box 携手 SD NAND(贴片式TF卡):驱动汽车智能革新的黄金组合

在汽车智能化的汹涌浪潮中&#xff0c;车辆不再仅仅是传统的交通工具&#xff0c;而是逐步演变为高度智能的移动终端。这一转变的核心支撑&#xff0c;来自于车内关键技术的深度融合与协同创新。车载远程信息处理盒&#xff08;T-Box&#xff09;方案&#xff1a;NXP S32K146 与…...

云原生周刊:k0s 成为 CNCF 沙箱项目

开源项目推荐 HAMi HAMi&#xff08;原名 k8s‑vGPU‑scheduler&#xff09;是一款 CNCF Sandbox 级别的开源 K8s 中间件&#xff0c;通过虚拟化 GPU/NPU 等异构设备并支持内存、计算核心时间片隔离及共享调度&#xff0c;为容器提供统一接口&#xff0c;实现细粒度资源配额…...

Python常用模块:time、os、shutil与flask初探

一、Flask初探 & PyCharm终端配置 目的: 快速搭建小型Web服务器以提供数据。 工具: 第三方Web框架 Flask (需 pip install flask 安装)。 安装 Flask: 建议: 使用 PyCharm 内置的 Terminal (模拟命令行) 进行安装,避免频繁切换。 PyCharm Terminal 配置建议: 打开 Py…...

门静脉高压——表现

一、门静脉高压表现 00:01 1. 门静脉构成 00:13 组成结构&#xff1a;由肠系膜上静脉和脾静脉汇合构成&#xff0c;是肝脏血液供应的主要来源。淤血后果&#xff1a;门静脉淤血会同时导致脾静脉和肠系膜上静脉淤血&#xff0c;引发后续系列症状。 2. 脾大和脾功能亢进 00:46 …...