Vue服务端渲染——同构渲染

Vue.js 可以用于构建客户端应用程序,组件的代码在浏览器中运行,并输出 DOM 元素。同时,Vue.js 还可以在 Node.js 环境中运行,它可以将同样的组件渲染为字符串并发送给浏览器。这实际上描述了 Vue.js 的两种渲染方式,即客户端渲染(client-side rendering,CSR),以及服务端渲染(server-side rendering,SSR)。另外,Vue.js 作为现代前端框架,不仅能够独立地进行 CSR 或 SSR,还能够将两者结合,形成所谓的同构渲染(isomorphic rendering)。我们将讨论CSR、SSR 以及同构渲染之间的异同,以及 Vue.js 同构渲染的实现机制。

1、CSR、SSR 以及同构渲染

在设计软件时,我们经常会遇到这样的问题:“是否应该使用服务端渲染?”这个问题没有确切的答案,具体还要看软件的需求以及场景。想要为软件选择合适的架构策略,就需要我们对不同的渲染策略做到了然于胸,知道它们各自的优缺点。服务端渲染并不是一项新技术,也不是一个新概念。在 Web 2.0之前,网站主要负责提供各种各样的内容,通常是一些新闻站点、个人博客、小说站点等。这些站点主要强调内容本身,而不强调与用户之间具有高强度的交互。当时的站点基本采用传统的服务端渲染技术来实现。例如,比较流行的 PHP/JSP 等技术。下图给出了服务端渲染的工作流程图:
在这里插入图片描述

(1) 用户通过浏览器请求站点。
(2) 服务器请求 API 获取数据。
(3) 接口返回数据给服务器。
(4) 服务器根据模板和获取的数据拼接出最终的 HTML 字符串。
(5) 服务器将 HTML 字符串发送给浏览器,浏览器解析 HTML 内容并渲染。

当用户再次通过超链接进行页面跳转,会重复上述 5 个步骤。可以看到,传统的服务端渲染的用户体验非常差,任何一个微小的操作都可能导致页面刷新。

后来以 AJAX 为代表,催生了 Web 2.0。在这个阶段,大量的SPA(single-page application)诞生,也就是接下来我们要介绍的 CSR 技术。与 SSR 在服务端完成模板和数据的融合不同,CSR 是在浏览器中完成模板与数据的融合,并渲染出最终的 HTML 页面。下图给出了 CSR 的详细工作流程:
在这里插入图片描述
客户端向服务器或 CDN 发送请求,获取静态的 HTML 页面。注意,此时获取的 HTML 页面通常是空页面。在 HTML 页面中,会包含 <style>、<link><script> 等标签。例如:

01 <!DOCTYPE html>
02 <html lang="zh">
03 <head>
04   <meta charset="UTF-8">
05   <meta name="viewport" content="width=device-width, initial-scale=1.0">
06   <title>My App</title>
07   <link rel="stylesheet" href="/dist/app.css">
08 </head>
09 <body>
10   <div id="app"></div>
11
12   <script src="/dist/app.js"></script>
13 </body>
14 </html>

这是一个包含 <link rel="stylesheet"><script> 标签的空HTML 页面。浏览器在得到该页面后,不会渲染出任何内容,所以从用户的视角看,此时页面处于“白屏”阶段。

虽然 HTML 页面是空的,但浏览器仍然会解析 HTML 内容。由于 HTML 页面中存在 <link rel="stylesheet"><script> 等标签,所以浏览器会加载 HTML 中引用的资源,例如 app.css 和 app.js。接着,服务器或 CDN 会将相应的资源返回给浏览器,浏览器对 CSS 和 JavaScript 代码进行解释和执行。因为页面的渲染任务是由 JavaScript 来完成的,所以当 JavaScript 被解释和执行后,才会渲染出页面内容,即“白屏”结束。但初始渲染出来的内容通常是一个“骨架”,因为还没有请求 API 获取数据。

客户端再通过 AJAX 技术请求 API 获取数据,一旦接口返回数据,客户端就会完成动态内容的渲染,并呈现完整的页面。

当用户再次通过点击“跳转”到其他页面时,浏览器并不会真正的进行跳转动作,即不会进行刷新,而是通过前端路由的方式动态地渲染页面,这对用户的交互体验会非常友好。但很明显的是,与 SSR 相比,CSR 会产生所谓的“白屏”问题。实际上,CSR 不仅仅会产生白屏问题,它对 SEO(搜索引擎优化)也不友好。下表从多个方面比较了 SSR 与 CSR:
在这里插入图片描述
SSR 和 CSR 各有优缺点。SSR 对 SEO 更加友好,而 CSR 对SEO 不太友好。由于 SSR 的内容到达时间更快,因此它不会产生白屏问题。相对地,CSR 会有白屏问题。另外,由于 SSR 是在服务端完成页面渲染的,所以它需要消耗更多服务端资源。CSR 则能够减少对服务端资源的消耗。对于用户体验,由于CSR 不需要进行真正的“跳转”,用户会感觉更加“流畅”,所以 CSR 相比 SSR 具有更好的用户体验。从这些角度来看,无论是 SSR 还是 CSR,都不可以作为“银弹”,我们需要从项目的实际需求出发,决定到底采用哪一个。例如你的项目非常需要 SEO,那么就应该采用 SSR。

那么,我们能否融合 SSR 与 CSR 两者的优点于一身呢?答案是“可以的”,这就是接下来我们要讨论的同构渲染。同构渲染分为首次渲染(即首次访问或刷新页面)以及非首次渲染。下图给出了同构渲染首次渲染的工作流程。
在这里插入图片描述
实际上,同构渲染中的首次渲染与 SSR 的工作流程是一致的。也就是说,当首次访问或者刷新页面时,整个页面的内容是在服务端完成渲染的,浏览器最终得到的是渲染好的 HTML 页面。但是该页面是纯静态的,这意味着用户还不能与页面进行任何交互,因为整个应用程序的脚本还没有加载和执行。另外,该静态的 HTML 页面中也会包含 、

假设浏览器已经接收到初次渲染的静态 HTML 页面,接下来浏览器会解析并渲染该页面。在解析过程中,浏览器会发现HTML 代码中存在 <link><script> 标签,于是会从 CDN 或服务器获取相应的资源,这一步与 CSR 一致。当 JavaScript 资源加载完毕后,会进行激活操作,这里的激活就是我们在Vue.js 中常说的 “hydration”。激活包含两部分工作内容:

  • Vue.js 在当前页面已经渲染的 DOM 元素以及 Vue.js 组件所渲染的虚拟 DOM 之间建立联系。
  • Vue.js 从 HTML 页面中提取由服务端序列化后发送过来的数据,用以初始化整个 Vue.js 应用程序。

激活完成后,整个应用程序已经完全被 Vue.js 接管为 CSR 应用程序了。后续操作都会按照 CSR 应用程序的流程来执行。当然,如果刷新页面,仍然会进行服务端渲染,然后再进行激活,如此往复。

下表对比了 SSR、CSR 和同构渲染的优劣:
在这里插入图片描述
可以看到,同构渲染除了也需要部分服务端资源外,其他方面的表现都非常棒。由于同构渲染方案在首次渲染时和浏览器刷新时仍然需要服务端完成渲染工作,所以也需要部分服务端资源,但相比所有页面跳转都需要服务端完成渲染来说,同构渲染所占用的服务端资源相对少一些。

另外,对同构渲染最多的误解是,它能够提升可交互时间(TTI)。事实是同构渲染仍然需要像 CSR 那样等待JavaScript 资源加载完成,并且客户端激活完成后,才能响应用户操作。因此,理论上同构渲染无法提升可交互时间。

同构渲染的“同构”一词的含义是,同样一套代码既可以在服务端运行,也可以在客户端运行。例如,我们用 Vue.js 编写一个组件,该组件既可以在服务端运行,被渲染为 HTML 字符串;也可以在客户端运行,就像普通的 CSR 应用程序一样。

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

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

相关文章

爬虫项目实战:利用基于selenium框架的爬虫模板爬取豆瓣电影Top250

&#x1f44b; Hi, I’m 货又星&#x1f440; I’m interested in …&#x1f331; I’m currently learning …&#x1f49e; I’m looking to collaborate on …&#x1f4eb; How to reach me … README 目录&#xff08;持续更新中&#xff09; 各种错误处理、爬虫实战及模…

Lua实现面向对象三大特性

面向对象是基于table实现的 封装 :(冒号) 自动将调用该函数的对象作为第一个参数传入 --Object就是第一参数 function Object:new() self&#xff1a;代表默认传入的第一个参数 _index&#xff1a;当自己的变量中找不到时&#xff0c;会默认找原表中_index指向的内容 Obj…

AD9361快速开发指南

AD9361是ADI&#xff08;Analog Devices&#xff09;公司推出的一款全集成的RF收发器芯片&#xff0c;广泛应用于无线通信系统&#xff0c;包括基于FPGA和ARM处理器的数码电视&#xff0c;卫星通信&#xff0c;雷达通信&#xff0c;军事通信和工业控制等领域。AD9361提供了广泛…

Qt问题 QString 和 void* 相互转化

QString转为void*格式 //将路径QString转为void*格式QByteArray byteArray qstrFilePath.toUtf8();char* charArray byteArray.data();void* voidPath static_cast<void*>(charArray);void*转为QString格式 char* charPath static_cast<char*>(voidPath); QS…

从 RBAC 到 NGAC ,企业如何实现自动化权限管理?

随着各领域加快向数字化、移动化、互联网化的发展&#xff0c;企业信息环境变得庞大复杂&#xff0c;身份和权限管理面临巨大的挑战。为了满足身份管理法规要求并管理风险&#xff0c;企业必须清点、分析和管理用户的访问权限。如今&#xff0c;越来越多的员工采用移动设备进行…

杰发科技AC7801——Flash模拟EEP内存分布情况

简介 本文记录了在使用AutoChips芯片Flash模拟EEP过程中的一些理解 核心代码如下 #include <stdlib.h> #include "ac780x_sweeprom.h" #include "ac780x_debugout.h"#define SWEEPROM_SIZE (2048UL) /* Ssoftware eeprom size(Byte) */ #define TE…

音视频5、libavformat-2

4、封装 Muxers (封装器)以 AVPacket 的形式获取编码数据并将其写入到指定容器格式的文件或输出字节流中。 muxing过程中最重要的API函数有: avformat_write_header() 用于写入文件header; av_write_frame() / av_interleaved_write_frame() 用于写…

后端跟前端讨论:如何对比分析AB方案?

目录 一、结论 二、场景再现 1、方案说明 2、不同思维的碰撞&#xff08;重点&#xff09; &#xff08;1&#xff09;场景描述 &#xff08;2&#xff09;后端思维 &#xff08;3&#xff09;前端思维 3、我作为后端说一句 一、结论 不是在设置相同条件下进行对比。 …

Excel动态选择某一行/列的最后一个数据

选择列的最后一个数据&#xff1a; 以A列为例&#xff0c;使用&#xff1a; LOOKUP(1,0/(A:A<>""),A:A)选择行的最后一个数据&#xff1a; 以第3行为例&#xff0c;使用&#xff1a; LOOKUP(1,0/(3:3<>""),3:3)示例程序 列最后一个数据&a…

C++右值引用

文章目录 1.左值概念和右值概念1.1.赋值目的1.2.左值右值1.2.1.左值1.2.2.右值 2.左值引用和右值引用2.1.左值引用2.2.右值引用2.2.1.细化参数2.2.2.资源转移2.2.2.1.返回转移2.2.2.2.参数转移 3.万能引用和完美转发3.1.万能引用3.2.完美转发 4.关于const的补充5.类的新成员5.1…

【精选】框架初探篇之——MyBatis的CRUD及配置文件

MyBatis增删改查 MyBatis新增 新增用户 持久层接口添加方法 void add(User user);映射文件添加标签 <insert id"add" parameterType"com.mybatis.pojo.User">insert into user(username,sex,address) values(# {username},# {sex},# {address}) <…

华硕灵耀XPro(UX7602ZM)原装Win11系统恢复安装教程方法

华硕灵耀XPro(UX7602ZM)原装Win11系统恢复安装教程方法&#xff1a; 第一步&#xff1a;需要自备华硕6个底包工厂安装包&#xff08;EDN.KIT.OFS.SWP.HDI.TLK&#xff09;或者自己备份的iso/esd/wim等镜像恢复 支持系列&#xff1a; 灵耀系列原装系统 无畏系列原装系统 枪…

golang学习笔记——并发计算斐波纳契数

文章目录 按顺序计算斐波纳契数并发计算斐波纳契数使用两个无缓冲 channel 的程序的第二个版本 按顺序计算斐波纳契数 golang学习笔记——将 channel 用作通信机制 golang学习笔记——并发计算斐波纳契数 package mainimport ("fmt""math/rand""tim…

不单一的错误!如何修复Windows 10上“未安装音频输出设备”的错误

许多Windows 10用户,尤其是那些使用HP或Dell笔记本电脑和PC的用户,都会遇到一个错误,上面写着“未安装音频输出设备”。这意味着你无法收听计算机上的任何声音,这让你很难放松,也很难完成工作。 错误通常会在系统托盘中的音频控制旁边显示一个红十字符号。 在这篇文章中…

postgresql经常出现连接一会后服务器拒绝连接

本地连接远程Linux上PG数据库经常自动断开连接 原因&#xff1a;Linux设置的tcp的keepalive超时时间太长&#xff0c;如果网络状况不佳&#xff0c;可能会导致连接断掉。 [rootlocalhost ~]# sysctl -a | grep net.ipv4.tcp_keepalive sysctl: reading key "net.ipv6.con…

小程序中的大道理之三--对称性和耦合问题

再继续扒 继续 前一篇 的话题, 在那里, 提到了抽象, 耦合及 MVC, 现在继续探讨这些, 不过在此之前先说下第一篇里提到的对称性. 注: 以下讨论建立在前面的基础之上, 为控制篇幅起见, 这里将不再重复前面说到的部分, 如果您还没看过前两篇章, 阅读起来可能会有些困难. 这是第一…

壳牌——利用人工智能应对新能源转型

荷兰皇家壳牌(Shell)最初是一家卖贝壳的商店&#xff0c;截至 2018 年&#xff0c;它是全球收入排名第五的公司。它的业务范围涵盖从勘探和钻探到提炼和零售的整个燃料供应链。壳牌在石油、天然气、生物燃料、风能和太阳能等端到端燃料生产领域处于世界领先地位。 当前&#x…

【21年扬大真题】编写程序,去除掉字符串中所有的星号。

【21年扬大真题】 编写程序&#xff0c;去除掉字符串中所有的星号。 int main() {int i 0;int j 0;char arr[30] {0};char brr[30] {0};printf("请输入一个字符串:");gets(arr);for (i 0;i < 30;i){if (arr[i] ! *) {brr[j] arr[i];j;}}int tmp j;for (i …

【Amazon】安装卸载AWS CLI操作流程(Windows 、Linux系统)

AWS 命令行界面&#xff08;AWS CLI&#xff09;是用于管理 AWS 产品的统一工具。只需要下载和配置一个工具&#xff0c;您就可以使用命令行控制多个 AWS 产品并利用脚本来自动执行这些服务。 AWS CLI v2 提供了多项新功能&#xff0c;包括改进的安装程序、新的配置选项&#…

Vue中mvvm的作用

目录 模型表示应用程序的数据。在Vue.js中&#xff0c;它们是JavaScript对象。视图是用户界面。在Vue.js中&#xff0c;使用模板语法编写HTML的表示层。ViewModel是视图的抽象表示&#xff0c;负责处理用户输入的数据&#xff0c;并处理视图的数据绑定。ViewModel使用模型中的…