CSRSSRPrerender原理全解密在了解这些概念之前,我们要先了解一个熟知的概念,那就是SPA(Singl

为什么会产生这种技术,要解决的问题是什么呢?

每种技术背后的原理又是什么呢?

在了解这些概念之前,我们要先了解一个熟知的概念,那就是SPA(SinglePageApplication),没错,就是大家熟知的单页应用,其实CSR、SSR、Prerender都是基于SPA,关于SPA的概念我就不多阐述了。

即,渲染过程全部交给浏览器进行处理,服务器不参与任何渲染。

打包下来页面是这个样子:

我们来使用create-react-app来建立一个web工程,并在Chrome里使用slow3G网络下做个实验:

即,打包的时候就预先渲染页面,所以在请求到index.html就已经是渲染过的内容

流程:浏览器-->服务器-->index.html(预渲染的内容)-->Render-->bundle.js+images-->Render

我们将刚刚的工程加入prerender-spa-plugin这个插件,再次运行看看结果

这次打包下来的主页html是这个样子的:

流程:浏览器-->服务器-->服务器执行渲染-->index.html(实时渲染的内容))-->Render-->bundle.js+images-->Render

可见SSR在服务端多做了一些实时渲染的操作,那么我们这次运行下来回事什么结果呢?

P.S其实另一方面的原因是,CSR对SEO太不友好了,搜索引擎抓取不到关键信息,只能抓取一个毫无元素的白屏页面,会导致搜索引擎搜索不到你的页面信息进行推荐,SSR和Prerender都能很好的解决这个问题。(吐槽一下:Google已经实现了抓取基于SPA的CSR)

在做出选择之前,我们必须要充分的了解两者的差异。

说了那么多利弊,那么,预渲染是怎么做到生成页面的呢?

做过爬虫的同学肯定知道headless的概念

HeadlessChrome在Chrome59中发布,用于在headless环境中运行Chrome浏览器,也就是在非Chrome环境中运行Chrome。它将Chromium和Blink渲染引擎提供的所有现代Web平台功能引入命令行。它有什么用处呢?headless浏览器是自动测试和服务器环境的绝佳工具,您不需要可见的UIshell。例如,针对真实的网页进行测试,创建网页的PDF,或者只是检查浏览器如何呈现URL。

Prerender就是利用Chrome官方出品的Puppeteer工具,对页面进行爬取。它提供了一系列的API,可以在无UI的情况下调用Chrome的功能,适用于爬虫、自动化处理等各种场景。它很强大,所以很简单就能将运行时的HTML打包到文件中。

原理是在Webpack构建阶段的最后,在本地启动一个Puppeteer的服务,访问配置了预渲染的路由,然后将Puppeteer中渲染的页面输出到HTML文件中,并建立路由对应的目录。

下面是流程图

目前来说,主流的框架React、Vue都已经支持SSR,只是配置会繁琐点,有人就会疑惑,框架还要支持SSR?

可事实是,正是因为现代SPA的VirtualDOM的存在,才能使SSR变成现实,但是,SSR这种理念的实现,并非易事。

我们先来看看详细的SSR流程图:

可以看出,SSR和Prerender的最大区别就在于,Prerender是静态的,SSR是动态的,SSR会在服务端实时构建出对应的DOM。

这也是SSR的难点所在:同构(即服务器和浏览器共同构建)。

同构这个概念存在于Vue,React这些新型的前端框架中,同构实际上是客户端渲染和服务器端渲染的一个整合。我们把页面的展示内容和交互写在一起,让代码执行两次。在服务器端执行一次,用于实现服务器端渲染,在客户端再执行一次,用于接管页面交互。

上面我们说过,SSR的工程中,React代码会在客户端和服务器端各执行一次。你可能会想,这没什么问题,都是JavaScript代码,既可以在浏览器上运行,又可以在Node环境下运行。但事实并非如此,如果你的React代码里,存在直接操作DOM的代码,那么就无法实现SSR这种技术了,因为在Node环境下,是没有DOM这个概念存在的,所以这些代码在Node环境下是会报错的。

但是就是由于VirtualDOM技术的存在,让这一切变成了可能,这里不过多介绍VirtualDOM,简单来说,它就是一个普通的JS对象,只不过映射了HTMLDOM的结构,React在做页面操作时,实际上不是直接操作DOM,而是操作VirtualDOM,也就是操作普通的JavaScript对象,这就使得SSR成为了可能。

我们可以直接在代码里判断当前的运行环境,如果是浏览器,就可以直接操作DOM,如果是服务器,就需要使用VirtualDOM生成HTML字符串。

所以React分别为浏览器端和服务器端分别提供了BrowserRouter和StaticRouter两种路由,通过BrowserRouter我们能够匹配到浏览器即将显示的路由组件,对浏览器来说,我们需要把组件转化成DOM,所以需要我们使用ReactDom.render方法来进行DOM的挂载。而StaticRouter能够在服务器端匹配到将要显示的组件,对服务器端来说,我们要把组件转化成字符串,这时我们只需要调用ReactDom提供的renderToString方法,就可以得到App组件对应的HTML字符串。

还没有!

对于一个React应用来说,路由一般是整个程序的执行入口。在SSR中,服务器端的路由和客户端的路由不一样,也就意味着服务器端的入口代码和客户端的入口代码是不同的。而入口则是Webpack进行打包完成的。

针对代码运行环境的不同,要进行有区别的Webpack打包,我们需要在Webpack的配置中加入target:'node',表明是服务器环境进行打包,除此之外,还有各种各样的配置需要解决。

如果要用到redux进行全局状态管理,一定要记得写成这种形式:

constgetStore=req=>{returncreateStore(reducer,defaultState);};exportdefaultgetStore;因为服务器端的Store是所有用户都要用的,但是不能让所有用户共享Store,所以在服务器端渲染中,Store的创建应该像下面这样,返回一个函数,每个用户访问的时候,这个函数重新执行,为每个用户提供一个独立的Store。

由于服务器不存在挂载元素这一生命周期,所以例如React的componentDidMount或者VUE的mounted生命周期都不会执行了,所以在服务端利用接口获取数据的时候,不能写入上述的生命周期中。

当然在真正实现SSR架构的过程中,难点有时不是实现的思路,而是细节的处理。比如说如何针对不同页面设置不同的title和description来提升SEO效果,这时候,我们其实可以用react-helmet这样的工具帮我们达成目标,这个工具对客户端和服务器端渲染的效果都很棒,值得推荐。还有一些诸如工程目录的设计,404,301重定向情况的处理等等,不过这些问题,我们只需要在实践中遇到的时候逐个攻破就可以了。

THE END
1.轻松理解客户端和服务器端的区别服务器端和客户端的区别因特网发展以后,较常用的用户端包括了如万维网使用的网页浏览器,收寄电子邮件时的电子邮件客户端,以及即时通讯的客户端软件等。对于这一类应用程序,需要网络中有相应的服务器和服务程序来提供相应的服务,如数据库服务,电子邮件服务等等,这样在客户机和服务器端,需要建立特定的通信连接,来保证应用程序的正常运行。https://blog.csdn.net/hhhh222222/article/details/77369200
2.服务器和客户端的区别详解服务器与客户端的核心差异-客户端:虽然也需要一定的安全措施(如防病毒软件、数据加密),但其安全重点更多在于保护用户隐私和防止恶意软件入侵 三、协同工作:客户端-服务器模型 客户端与服务器之间的协作基于一种称为“客户端-服务器模型”(Client-Server Model)的架构 这一模型的核心思想是分工合作,让服务器专注于数据处理和资源管理,而客户http://www.09wl.com/2024/11/26056b.html
3.简述什么是服务器和客户端?Worktile社区服务器和客户端是网络通信中常用的术语,用于描述计算机网络中不同角色的设备。 一、服务器: 服务器是指在计算机网络中提供服务并响应客户请求的计算机或软件。它通常具有强大的处理能力、大容量的存储空间以及良好的稳定性和安全性,用于存储和处理大量的数据和请求。 https://worktile.com/kb/ask/1868729.html
4.详解客户端/服务器区别联系及其应用客户端/服务器是一种常见的计算机架构,它将应用程序分为客户端和服务器端两个部分。客户端是指用户使用的应用程序,而服务器端则是指提供服务的应用程序。今天小编要来跟大家详细介绍客户端/服务器架构的定义、区别、联系及其应用。 一、什么是客户端 客户端/服务器是一种分布式计算架构,它将应用程序分为两个部分https://www.kkidc.com/about/detail/hcid/196/id/1913/
5.10分钟学会在Ubuntu18.04LTS上安装NFS服务器和客户端NFS在客户端 -服务器环境中运行,其中服务器负责管理客户端的身份验证,授权和管理,以及特定文件系统内共享的所有数据。授权后,任意数量的客户端都可以访问共享数据,就好像它们存在于其内部存储中一样。在Ubuntu系统上设置NFS服务器非常简单。您需要做的就是在服务器和客户端计算机上进行一些必要的安装和配置,这样你就可https://cloud.tencent.com/developer/article/2055428
6.第5章目录服务器安全性(SunJavaSystemDirectoryServer安全套接字层 (Secure Sockets Layer, SSL) 在目录服务器和客户端之间提供加密通信和可选验证。可以通过 LDAP 使用 SSL,也可以将 SSL 与 DSML-over-HTTP 结合使用。默认情况下通过 LDAP 启用 SSL,但如果使用 DSML-over-HTTP,则可以轻松地启用 SSL。此外,还可以将复制配置为使用 SSL 在服务器之间进行安全通信https://docs.oracle.com/cd/E19957-01/820-0293/6nc1tbp02/index.html
7.python设置网卡为混杂模式kekenai的技术博客服务器端进程需要申请套接字,然后绑定套接字进行监听。当有客户端发送请求,则接收数据并进行处理,处理完后对客户端进行响应。 创建套接字 import socket # socket模块的socket()函数能创建socket对象 socket.socket([family[,type[,proto]]]) ''' family:设置套接字种族,包括AF_UNIX和AF_INET,常用AF_INET选项https://blog.51cto.com/u_13259/12773024
8.ssl源代码: Lib/ssl.py 该模块提供了对传输层安全(通常称为 "安全套接字层")加密和网络套接字的对等认证设施的访问,包括客户端和服务器端。 该模块使用 OpenSSL 库。它可以在所有现代 Unix 系统、 Windows 、 macOS 和可能的其他平台上使用,只要 OpenSSL 安装在该平台上。 http://docs.python.org/zh-cn/3.11/library/ssl.html
9.将客户端连接到游戏服务器游戏服务器是使用服务到服务呼叫通过 PlayFab Server API 分配的。 客户端连接所需的连接信息通过这些服务和客户端传递,而它们通常使用 TCP 或 UDP 套接字驱动到游戏服务器的直接连接。 通常情况下,游戏服务器将侦听已知的 UDP 和游戏开发者选择的 TCP 端口。 https://docs.microsoft.com/zh-cn/gaming/playfab/features/multiplayer/servers/connecting-clients-to-game-servers
10.思科网络技术学院教程(第6版):网络简介图1-2 客户端/服务器示例 3.对等 客户端和服务器软件通常运行在单独的计算机上,但一台计算机也可以同时兼任两个角色。在小企业和家庭中,许多计算机在网络中既是服务器又是客户端。这种网络称为对等网络,如图1-3所示。 图1-3 对等示例 对等网络的优点: https://www.epubit.com/bookDetails?id=N15003
11.教师邮箱客户端设置说明如客户端收发仍有问题,请确认以下两点: 1、请确认已设置:发件时也需要进行身份验证。 例如,Foxmail软件在发信服务器设置里需要勾选: 又如,苹果电脑自带邮件客户端软件,取消默认的“自动管理连接设置”,为发信认证选择“密码”方式。 2、请确认这里已开启: https://itsc.nju.edu.cn/1a/8e/c21586a334478/pagem.htm
12.GitHubfanqiangvpn/fanqiang这里还有个ExpressVPN使用小提示,万一在敏感时期VPN服务器暂时被墙之后,改变客户端默认的连接协议(一般是Automatic),改为L2TP-IPSec协议然后尝试连接,你会发现其实还有些节点可以正常连接使用。 所以说选择大型正规的VPN服务,灵活的使用基本上能确保全年的正常使用,当然在国内的敏感时期有些节点的速度还是比平时慢一些,https://github.com/fanqiang-vpn/fanqiang-vpn.github.io
13.iFileSpace而iFileSpace 的优点还在于它提供了主流平台的客户端和服务器端,包括 Android、iOS、Win、Mac 和 Linux,相比其他仅有网页端的更方便一点。不过稍显遗憾的是 iFileSpace 目前并没开源,但如果你需要一款简单、免费且跨平台支持较好的自建网盘程序,那么可以一试。 相关文件下载地址 官方网站:访问 软件性质:免费 相关链https://www.iplaysoft.com/ifilespace.html
14.TCP/UDP区别&&心跳包机制3客户端收到服务器发送的包,并向服务器发送确认标识,随后连接成功 注意:是在连接成功后进行数据传输 什么是四次挥手? 心跳机制 心跳机制是定时发送一个自定义的结构体(心跳包),让对方知道自己还活着,以确保连接的有效性的机制。(看下图) 网络中的接收和发送数据都是使用操作系统中的SOCKET进行实现。但是如果此套https://www.jianshu.com/p/6d93a3c21c34
15.CP2431作为客户端与S7客户端与服务器定义请参看:服务器Server和客户端Client有什么区别? S7-200 PLC本体没有以太网口,需要通过以太网模块CP243-1来扩展以太网通信,且一个S7-200PLC只能扩展一个CP243-1。 CP243-1最多8个以太网S7控制器通信,每个连接既可以是服务器连接也可以是客户机连接。 https://www.ad.siemens.com.cn/productportal/prods/published/Comm/Comm_5.1/Comm_5.1.html
16.ntp客户端配置多个时间源/etc/ntp.conf文件被用来在记录每次校验发生时候客户端和服务器时钟之间的差(或者叫漂移)。 一旦xntpd守护进程预计到这个时间差,它会开始使用这个“可预期”的漂移,来调节本机的时钟,这样就避免每次都去查询网络中的ntp服务器,从而可以减轻网络负载。 xntpd守护进程会慢慢的转成使用这个drift文件,而查询NTP服务器的次https://blog.itpub.net/7191998/viewspace-748401/
17.使用JWT实现前后端权限验证技术交流用户可以把该token保存到客户端,服务器不保存任何用户信息。之后,当用户与服务器通信时,通常将token通过HTTP的Authorization header发送给服务端,服务端使用自己保存的密钥验证token的正确性,只要正确即通过验证。服务器仅依赖于这个token来标识用户。 1、jwt的组成(了解)https://www.itsource.cn/web/news/1740.html
18.科学网—[转载]联邦学习算法综述上述过程是一个典型的基于客户端服务器架构的联邦学习过程。但并不是每个联邦学习任务都一定要严格按照这样的流程进行操作,有时可能会针对不同场景对流程做出改动,例如,适当地减少通信频率来保证学习效率,或者在聚合后增加一个逻辑判断,判断接收到的本地计算结果的质量,以提升联邦学习系统的鲁棒性。 https://blog.sciencenet.cn/blog-3472670-1280769.html
19.超文本传输协议(HTTP)介绍超文本传输协议(HyperText Transfer Protocol,HTTP)是从服务器传输数据到客户端的传输协议。 HTTP 的主要特点 支持客户/服务器模式。 简单快速:客https://www.imooc.com/article/4803
20.RADIUS认证授权和计费RADIUS是一种分布式的、客户端/服务器结构的信息交互协议,能保护网络不受未授权访问的干扰,常应用在既要求较高安全性、又允许远程用户访问的各种网络环境中。该协议定义了基于UDP(User Datagram Protocol)的RADIUS报文格式及其传输机制,并规定目的UDP端口号1812、1813分别作为默认的认证、计费端口号。 https://support.huawei.com/enterprise/zh/doc/EDOC1100112417/35071f9a
21.RHEL挂载挂起:nfs:server[]notresponding,stilltrying对于非红帽 NFS 客户端或服务器,请联系非红帽系统的供应商。调查连接性问题,如网络连接停止、网络数据包丢失、系统挂起、NFS 客户端/服务器挂起或缓慢、存储挂起或缓慢。 负责NFS 客户端和 NFS 服务器之间网络的团队应参与调查连接性和容量问题。 Root Cause https://access.redhat.com/zh_CN/solutions/1386653
22.OPC服务器的研究及其在CAN总线系统中的实现AETOPC 服务器对象是客户端与服务器交互的首要对象。客户端通过访问服务器对象的接口函数与之进行交互。一个服务器对象里可以设置一个以上的组对象。OPC 服务器对象的主要功能是:①创建和管理OPC 组对象;②管理服务器内部的状态信息;③将服务器的错误代码翻译成描述性语句;④浏览服务器内部的数据组织结构。 http://www.chinaaet.com/article/119319