服务端渲染 SSR 原理和实现

文章目录

  • CSR 优缺点
  • SSR
  • Server + Client 同构
  • Hydrate 水合(客户端激活)
  • 数据的获取和初始化
  • 预加载资源
  • 避免应用单例
  • 避免全局副作用代码

CSR 优缺点

优点

  • 整个网站打包进 JavaScript 里,当 JavaScript 下载完毕后,相当于网站的页面资源都被下载好了。这样在跳转新页面的时候,不需要向服务器再次请求资源( JavaScript 会直接操作 DOM 进行页面渲染),从而让整个网站的使用体验上更加流畅

缺点

  • 在 JavaScript 体积较大的情况下,会有白屏问题
  • 因为会先下载一个空的 HTML,然后才通过 JavaScript 进行渲染,这个空的 HTML 会导致某些搜索引擎无法通过爬虫正确获取网站信息,从而影响网站的搜索引擎排名

SSR

优点

  • HTML 在服务器端就已经渲染好了,浏览器拿到就可以渲染,减少白屏时间
  • 服务器端渲染拥有良好的首屏性能和 SEO

缺点

  • 每次跳转页面都要向服务器重新请求,意味着用户每次切换页面都要等待一小段时间
  • SSR 相比 CSR 会占用较多的服务器端资源
// 以 vue 为例
import { renderToString } from 'vue/server-renderer'
import { createSSRApp } from 'vue'// 一个计数的 vue 组件
function createApp() {// 通过 createSSRApp 创建一个vue实例return createSSRApp({data: () => ({ count: 1 }),template: `<button @click="count++">{{ count }}</button>`,});
}const app = createApp();// 通过 renderToString 将 vue 实例渲染成字符串
renderToString(app).then((html) => {// 将字符串插入到 html 模板中const htmlStr = `<!DOCTYPE html><html><head><title>Vue SSR Example</title></head><body><div id="app">${html}</div></body></html>`;console.log(htmlStr);
});

Server + Client 同构

  • 开始的步骤和 SSR 相同,将生成的 HTML 字符串返回给客户端,同时将 CSR 需要的 JavaScript 也一并发送给客户端
  • 客户端在接收到 SSR 生成的 HTML 后,页面还会再执行一次 CSR 的流程
  • 客户端只有请求的第一个页面是在服务器端渲染的,其它页面则都是在客户端进行的
  • 这样就同时兼顾首屏、SEO和用户体验的网站
    在这里插入图片描述

Hydrate 水合(客户端激活)

  • 服务器执行应用的初始渲染,生成静态 HTML,并将其发送给客户端,这一步其实发送的是静态的模版( Dehydrate 脱水)
  • 客户端加载额外的 JavaScript 代码,并在已有的静态 HTML 上绑定事件监听器等,使页面变得可交互
  • SSR 的瓶颈也就取决于 Hydrate 的过程

数据的获取和初始化

  • 挂载到 window 上或者 Vuex、Pinia 等其它方案
const htmlStr = `<!DOCTYPE html><html><head>...// 将数据格式化成json字符串,放到script标签中<script>window.__INITIAL_DATA__ = ${JSON.stringify(initData)}</script></head>...</html>
`;

组件中获取数据

function createApp() {return createSSRApp({data: () => ({ count: 1 }),template: `<button @click="count++">{{ count }}</button>`,// 自定义一个名为 asyncData 的函数asyncData: async () => { // 在处理远程数据并 return 出去const data = await getSomeData()return data; },async mounted() {// 如果已经有数据了,直接从 window 中获取if (window.__INITIAL_DATA__) {// 有服务端数据时,使用服务端渲染时的数据this.count = window.__INITIAL_DATA__;window.__INITIAL_DATA__ = undefined;return;} else {// 如果没有数据,就请求数据this.count = await getSomeData();}}});
}

预加载资源

  • 在打包过程中生成 manifest
    • 作用是将打包后的模块 ID 与它们关联的 Chunk 和资源文件进行映射
  • 依靠这个 manifest 获取资源的路径,然后创建 Link 标签拼接到 HTML 模板中即可

避免应用单例

  • 服务器端返回给客户端的每个请求都应该是全新的、独立的应用程序实例,避免直接将对象或变量创建在全局作用域,否则它将在所有请求之间共享,在不同请求之间造成状态污染

避免全局副作用代码

  • 比如 vue 服务器端渲染只会执行 beforeCreate 和 created 生命周期,应该避免在这两个生命周期里产生全局副作用的代码
  • 例如使用 setInterval 设置定时器。在纯客户端的代码中,我们可以设置一个定时器,然后在 beforeDestroy 或 destroyed 生命周期中将其销毁。但是在 SSR 期间并不会调用销毁钩子函数,所以定时器将永远保留下来,最终造成服务器内存溢出

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

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

相关文章

技术流 | ClickHouse工具ckman v3.1.3 sinker v3.1.8 版本发布

【本文作者&#xff1a;擎创科技 ClickHouse专家&#xff0c;ckman作者禹鼎侯】 在这个端午小长假里&#xff0c;ckman和clickhouse_sinker分别带来了全新的版本。让我们一起来看看&#xff0c;新版本都有哪些新特性吧&#xff01; ckman v3.1.3新版本特性 ckman v3.1.3作为…

3D场景的交互设计有什么软件吗?

需求&#xff1a;类似于游戏那样在3D房间内&#xff0c;能通过鼠标或键盘操作在房间里自由行走。 对于3D场景的交互设计&#xff0c;尤其是像设计一间房间并允许用户在其中自由行走这样的需求&#xff0c;以下几款软件应该会适合&#xff1a; 1、博维数孪&#xff1a;专业从事…

另辟蹊径的终端防病毒

在数字时代的浪潮中&#xff0c;网络安全问题愈发凸显&#xff0c;防病毒成为了保护信息安全的重要一环。而白名单作为一种有效的安全策略&#xff0c;在防病毒方面发挥着不可或缺的作用。 首先&#xff0c;我们需要明确白名单的概念。白名单是一种管理和安全实践&#xff0c;用…

ROS——自定义话题消息和使用方法

定义Person话题 定义Person发布者 /*** 该例程将发布/person_info话题&#xff0c;自定义消息类型&#xff1a; test_topic::Person*/#include <ros/ros.h> #include <test_topic/Person.h> //包含的头文件&#xff0c;ros相关的头文件&#xff0c;及自定义头文件…

Vue25-内置指令02:v-text指令

一、v-html对比v-text v-html支持结构的解析&#xff0c;v-text不支持结构的解析。 二、v-html的安全性问题 2-1、cookie的原理&#xff08;node.js&#xff09; 7天免登录&#xff0c;cookie实现。 cookie的本质就是类似于json的字符串&#xff0c;格式是&#xff1a;key-va…

Java学习之-SpringAI

文章目录 一、SpringAI是什么二、准备工作1.GPT-API-free2.AiCore3.eylink 三、对话案例实现1.创建项目2.实现简单的对话 四、聊天客户端ChatClient1.角色预设2.流式响应 五、聊天模型六、图像模型(文生图)七、语音模型1.文字转语音(文生语音)2.语音转文字 八、多模态九、函数调…

【云计算】Docker部署Nextcloud网盘并实现随地公网远程访问

配置文件 切换root权限&#xff0c;新建一个nextcloud的文件夹&#xff0c;进入该目录&#xff0c;创建docker-compose.yml [cpslocalhost ~]$ su root Password: 666666 [rootlocalhost cps]# ls Desktop Documents Downloads Music Pictures Public Templates Vide…

CPN tools学习——可执行的 PN

目录 1添加令牌 2.转换防护Guard 1添加令牌 左侧新建颜色集和变量的声明定义&#xff1a; 为库所分配颜色集&#xff1a;左键tab键 P1处&#xff1a;添加多重集合&#xff0c;表示添加了两个令牌&#xff0c;第一个令牌值为A&#xff0c;第二个为B。 P2处&#xff1a;表示…

在AI云原生时代应该如何应对复杂的算力环境

引言 随着在2019年ChatGPT4的爆火,AI这个之前常常被人觉得非常高深的技术渐渐的被越来越多的人们所了解,越来越多的公司、组织和开发者开始投入AI的使用和开发中来.随着AI和LLM的火热,算力资源也变的越来越紧缺,所以如何高效的管理和使用算力资源也变成了必须要面对的问题。 …

vue2动态路由实现

实现一个简单的动态路由&#xff1a; 1、先定义菜单页面组件的结构&#xff0c;使用的是elementUI的NavMenu 导航菜单 <template><div><el-menu default-active"1" router><el-submenu :index"item.path" v-for"item in menu_…

借助大语言模型快速学习金仓数据库 KES

基础概念 KES 人大金仓数据库管理系统 KingbaseES&#xff08;KES&#xff09; 是由 北京人大金仓信息技术股份有限公司 (以下简称“人大金仓”)自主研发的面向全行业、全客户关键应用的企业级大型通用数据库管理系统。产品融合了人大金仓在数据库领域几十年的产品研发和企业级…

TiKV 源码分析之 PointGet

作者&#xff1a;来自 vivo 互联网存储研发团队-Guo Xiang 本文介绍了TiDB中最基本的PointGet算子在存储层TiKV中的执行流程。 一、背景介绍 TiDB是一款具有HTAP能力(同时支持在线事务处理与在线分析处理 )的融合型分布式数据库产品&#xff0c;具备水平扩容或者缩容等重要特…

Python写UI自动化--playwright(安装)

Playwright是微软推出的开源自动化测试工具&#xff0c;专为跨浏览器端到端测试设计。Playwright可以在多个浏览器引擎上运行测试&#xff0c;包括基于Chromium的浏览器&#xff08;如Chrome、Edge&#xff09;、Firefox和WebKit&#xff08;Safari的技术基础&#xff09;。支持…

标星好多好多k,这2个开源项目绝了!

在这个信息爆炸的世代&#xff0c;不妨让我给大家精选并介绍一些优质的开源项目&#xff0c;让大家感受到开源世界的美好。 我的数据我做主 每个人的微信聊天记录里都藏着无数珍贵的回忆和秘密。如果有一个宝盒&#xff0c;能够帮你把这些记忆永久保存&#xff0c;甚至让它们活…

新加坡裸机云多IP服务器为何适合跨境外贸业务

新加坡裸机云多IP服务器在跨境外贸业务中展现出了卓越的适配性&#xff0c;其独特优势为外贸企业提供了强大的支持。以下将详细阐述为何新加坡裸机云多IP服务器是跨境外贸业务的理想选择。 首先&#xff0c;新加坡裸机云多IP服务器在性能上表现出色。由于去除了虚拟化层的开销&…

大数据在商业中的应用——Kompas.ai如何助力企业决策

引言 在现代商业中&#xff0c;大数据逐渐成为企业决策的重要工具。通过对海量数据的分析和处理&#xff0c;企业可以获得重要的市场信息和决策支持。本文将探讨大数据在商业中的应用&#xff0c;并介绍Kompas.ai如何通过AI技术助力企业决策。 大数据的发展及其重要性 大数据…

为什么要学习Flink系统管理及优化课程?

Flink系统是一种流式处理框架&#xff0c;能够高效地处理大规模数据流。然而&#xff0c;要确保Flink系统的正常运行&#xff0c;就需要进行系统管理和优化。系统管理是指对Flink集群的监控、调度和维护&#xff0c;而系统优化则是指通过调整参数和优化算法&#xff0c;提高Fli…

Anime Girls Pack

动漫女孩包 35个动画&#xff08;就地&#xff09;支持人形。 8情绪。 角色列表&#xff1a;原艾艾琪惠美子惠理文子星薰和子佳子奈子理子凛老师小樱老师津雨僵尸女孩01 下载&#xff1a;​​Unity资源商店链接资源下载链接 效果图&#xff1a;

[vue2]深入理解路由

本节目标 单页应用程序路由概念VueRouter基本使用组件分类存放路由模块封装声明式导航其他路由配置路由模式编程式导航案例-面经基础版 单页应用程序 单页应用程序(SPA): 所有的功能都在一个HTML页面上实现 网易云音乐: 网易云音乐 多页应用程序(MPA): 不同功能通过切换不同…

Kotlin 协程真的轻量吗?

前言 在官方文档的介绍中,提到了: 协程是轻量的 并给出了一个例子: fun main() = runBlocking {repeat(50_000) {// 启动大量的协程launch {delay