快速在你的vue/react应用中实现ssr(服务端渲染)-程序员宅基地

前言

我们都知道, VueReact是构建客户端应用程序的框架。默认情况下,可以在浏览器中输出自定义组件,进行生成 DOM 和操作 DOM, 也就是我们常说的客户端渲染, 并且我们大部分主流的场景都是SPA(单页面)应用, 而随着 SPA尤其是 ReactVueAngular 为代表的前端框架的流行,越来越多的 Web App 使用的是客户端渲染。

使用客户端渲染的优势在于节省后端资源局部刷新前后端分离等,但随着应用的日益复杂, 首屏渲染时间不断变长, 并且存在严重的SEO问题。

所以为了解决SPA应用遇到的这些问题, 我们必须考虑SSR:

服务端渲染(ssr),是指由服务器端完成页面的HTML 结构拼接,并且直接将拼接好的HTML发送到浏览器,然后为其绑定状态与事件,成为完全可交互页面的处理技术。

对于服务端渲染的页面,服务端可以直接将带数据的内容通过 HTML 文本的形式返回,搜索引擎爬虫可以轻易的获取页面内容,而对于客户端渲染的应用,客户端必须执行服务器返回的 Javascript 才能得到正确的网页内容。目前,除 GoogleBing 支持 Javascript 外(也会有一些限制),其他的大部分搜索引擎都不支持 Javascript,也就无法获取正确的网页内容。而本文要讲的技术方案,正是为了解决SPA下的SSR技术困境.接下来我们看看常用的ssr技术实现方案.

摘要

ssr(服务端渲染)技术实现方案

接下来笔者将列举几个常用的基于vue/react的服务端渲染方案,如下:

  • 使用next.js/nuxt.js的服务端渲染方案

  • 使用node+vue-server-renderer实现vue项目的服务端渲染

  • 使用node+React renderToStaticMarkup实现react项目的服务端渲染

  • 传统网站通过模板引擎来实现ssr(比如ejs, jade, pug等)

  • 使用rendertron实现SPA项目的服务端渲染

以上是笔者之前实践过的方案, 最后一种方案笔者将在下面一节详细介绍, 因为next/nuxt是已有的服务端渲染解决方案,文档写的比较详细,这里笔者就不再做过多介绍了,这里我们简单介绍一下第二种和第三种方案.

1.使用node+vue-server-renderer实现vue项目的服务端渲染

首先vue-server-renderer依赖node的api,所以只能运行在node环境, 我们需要先安装它:

npm install vue vue-server-renderer --save

在node中使用,代码如下:


const Vue = require('vue')const server = require('express')()const renderer = require('vue-server-renderer').createRenderer()
server.get('*', (req, res) => {  const app = new Vue({    data: {      url: req.url    },    template: `<div>趣谈前端:{
    { url }}</div>`  })
  renderer.renderToString(app, (err, html) => {    if (err) {      res.status(500).end('Internal Server Error')      return    }    res.end(`      <!DOCTYPE html>      <html lang="en">        <head><title>Hello</title></head>        <body>${html}</body>      </html>    `)  })})
server.listen(8080)

当然实际情况比上面的案例要复杂很多, 我们可以专门写一个template.html,然后通过模板差值的方式导入后端数据,进而实现服务端渲染. 在使用这种方式的时候我们仍然要维护两套代码.

2.使用node+React renderToStaticMarkup实现react项目的服务端渲染

使用这种方案和vue的方案类似, 只不过这里我们用了react自带的api来实现ssr,简单的实现代码如下:


var express = require('express');var app = express(); var React = require('react'),    ReactDOMServer = require('react-dom/server'); var App = React.createFactory(require('./App')); app.get('/', function(req, res) {    var html = ReactDOMServer.renderToStaticMarkup(        React.DOM.body(            null,            React.DOM.div({id: 'root',                dangerouslySetInnerHTML: {                    __html: ReactDOMServer.renderToStaticMarkup(App())                }            })        )    );     res.end(html);}); app.listen(80, function() {    console.log('running on port ' + 80);});

以上使用了renderToStaticMarkup, 我们都知道react-dom提供了两种服务端渲染函数,如下:

  1. renderToString:将 React Component 转化为 HTML 字符串,生成的 HTML 的 DOM 会带有额外属性:各个 DOM 会有data-react-id属性,第一个 DOM 会有data-checksum属性。

  2. renderToStaticMarkup:将 React Component 转化为 HTML 字符串,但是生成 HTML 的 DOM 不会有额外属性,从而节省 HTML 字符串的大小。

所以这里我们一般使用renderToStaticMarkup函数. 同理在实际业务场景中我们也会写2套代码来实现ssr.

使用谷歌rendertron实现服务端渲染

Google 推出的 Rendertron 使得 SPA 也能够被不支持执行 Javascript 的搜索引擎爬取渲染后的内容。其原理主要是通过使用 Headless Chrome 在内存中执行 Javascript,并在得到完整内容后,将内容返回给客户端。

我们通常会将 Rendertron 部署为一个独立的 HTTP 服务,然后为 Web 应用框架配置 Google 官方提供的中间件或者在反向代理上添加相应路由规则,使得能够在检测到搜索引擎爬虫的 UA 时,可以将请求代理给 Rendertron 服务。笔者总结了一下其基本实现原理图,方便大家理解:

Rendertron 提供了两个主要 API:

  • Render 用于渲染网站内容

  • Screenshot 用于将网站内容截图

在 SEO 场景下我们使用的是 Render 接口。

比如当客户端请求我们的网站时,我们服务端可以根据请求头 User Agent 发现是否包含了 Baiduspider/2.0 关键字,如果是, 那么可以认定为当前的客户端是一个百度爬虫此时可以将这个请求代理 Rendertron 服务的 /render/客户端请求地址 路由,让 Rendertron 帮助执行网页内的 Javascript,并将最终内容返回给搜索引擎爬虫。

使用Rendertron的好处在于我们可以不用考虑服务端渲染的部分,完全按照SPA的模式开发项目,也不用为了兼容服务端渲染而写多余的兼容代码.

具体实现

首先我们需要安装Rendertron, 可以在github中找到其安装和使用方法,在安装前最好先安装docker, 目前docker的最新版本以支持傻瓜式安装,所以安装启动都非常方便.

1.本地运行

在安装好docker之后, 我们先全局安装rendertron:

npm install -g rendertron

然后我们需要安装谷歌浏览器(作为合格的开发都应该有谷歌浏览器~),然后就可以用它的cli来启动服务了,我们只需要在命令行执行如下命令:

rendertron

之后控制台会打印本地服务启动的地址,比如localhost:3000 这个时候我们只需要在地址后面输入我们想渲染的网站即可:localhost:3000:render/你的网站地址, 如下图所示:

此时我们的rendertron服务已经搭建完成, 接下来我们可以在服务端来实现ssr了,代码如下:


const koa = require('koa');const app = new koa();app.use(async (ctx, next) => {    ctx.type = "html";    if(/Baiduspider\/2\.0/g.ctx.header['user-agent']) {      // 是百度爬虫,则转发到rendertron服务中      ctx.redirect(`http://localhost:3000/render/${ctx.url}`)    }else {        // 渲染正常的路由页面    }
    await next();    })
app.listen('80');

当然如果我们后端技术栈采用的是express, rendertron有专门的中间件可以使用, 不仅仅可以拦截百度的爬虫,具体用法如下:


const express = require('express');const rendertron = require('rendertron-middleware');
const app = express();
app.use(rendertron.makeMiddleware({  proxyUrl: 'http://your-rendertron-instance/render',}));
// 正常的路由和页面渲染逻辑app.use(...);app.listen(81);

所以为了降低开发成本笔者建议可以采用rendertron的方案, 单独部署一套服务器用来实现ssr. 但是我们需要考虑当网站流量增加时的扩容问题,以及配置搭建反向代理或负载均衡等配套服务。

后期展望

后期笔者将会继续带大家探索大前端相关内容, 基本框架如下:

往期精彩

当后端一次性丢给你10万条数据, 作为前端工程师的你,要怎么处理?

基于react/vue搭建一个通用的表单管理配置平台

javascript进阶必备的二叉树知识

原生javascript组件开发之Web Component实战

如何使用css3实现一个类在线直播的队列动画

最后

如果想学习更多H5游戏, webpacknodegulpcss3javascriptnodeJScanvas数据可视化等前端知识和实战,欢迎在公号《趣谈前端》加入我们的技术群一起学习讨论,共同探索前端的边界。

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/KlausLily/article/details/107075298

智能推荐

Android studio 下drawable与mipmap文件夹详解_androidstudio drawable 文件夹类型-程序员宅基地

文章浏览阅读8.7k次,点赞10次,收藏21次。大家在App打包的时候会不会很疑惑为什么生成的apk文件这么大 这个时候我们不妨浏览下项目的目录,可以看到一个叫res的目录长这个样子: Android的APK文件大都是大在那几个名字里带drawable的目录上适配所有机器和屏幕的图片素材和其他资源都在一个安装包里,肯定大啊如果界面做得超简单,纯色啊均匀渐变完全不使用图片资..._androidstudio drawable 文件夹类型

Qt实现的自定义登录框连接MySQL(完整的实现过程)_qt实现登录功能连接数据库-程序员宅基地

文章浏览阅读554次,点赞3次,收藏5次。Qt实现的自定义登录注册窗口,连接MySQL_qt实现登录功能连接数据库

基于Java SSM框架实现在线学习系统项目【项目源码+论文说明】计算机毕业设计-程序员宅基地

文章浏览阅读907次,点赞24次,收藏19次。该在线学习系统的开发和设计根据学生的实际情况出发,对系统的需求进行了详细的分析,然后进行系统的整体设计,最后通过测试使得系统设计的更加完整,可以实现系统中所有的功能,在开始编写论文之前亲自到图书馆借阅SSM 框架书籍,MYSQL数据库书籍等编程书籍,然后针对开发的在线学习系统 ,去网上查找了很多别人做好的系统,参照他们的设计结果,来对自己的系统进行更加详细的系统的设计,将系统中所有的功能结果一一列举出来,然后进行需求分析,最后对所有的功能模块进行编码,最后完成系统的整体测试,实现系统的正常运行[6]。

2023年 MOOC《计算机网络》—— 第四章CSMA/CD作业答案解析(手写版)_考虑建立一个csma/cd网络,其最小顿长为2500字节,以1 gbps的速度运3行,没有中继器,-程序员宅基地

文章浏览阅读1.1k次。所有节点都共享网络传输信道,节点在发送数据之前,首先检测信道是否空闲,如果信道空闲则发送,否则就等待;在发送出信息后,再对冲突进行检测,当发现冲突时,则取消发送。 最大长度变成1/10_考虑建立一个csma/cd网络,其最小顿长为2500字节,以1 gbps的速度运3行,没有中继器,

【华为云云耀云服务器L实例评测|云原生】自定制轻量化表单Docker快速部署云耀云服务器_智能 表单 docker-程序员宅基地

文章浏览阅读1.3k次,点赞12次,收藏10次。华为云的云耀云服务器L实例备受推崇,以其高效、可靠和安全的基础设施服务而闻名。本文将为展示在该服务器上部署轻量化定制表单服务为例带你一文走进该服务器的方方面面。_智能 表单 docker

Cygwin64 报错:Please ensure that you have authorized the remote application by visiting the link below_unable to retrieve data please ensure that you hav-程序员宅基地

文章浏览阅读1.4k次。Cygwin64 报错:Please ensure that you have authorized the remote application by visiting the link below**报错说明:**在用cygwin下载MODIS数据时,运行 【./download.sh】 时报如题所述错误(忘记截图了。。)**报错原因:**没有权限**解决方法:**右键点击图标,选择【以管理员身份运行】,然后再运行【 ./download.sh】就可以下载数据了。..._unable to retrieve data please ensure that you have authorized the remote ap

随便推点

机器学习通俗易懂系列之Word2vec_word2vec 查看token-程序员宅基地

文章浏览阅读960次。本来工作后比较懒,很久不写博客了,因为实习小同学时不时问到一些问题,网上的资料比较分散、不够通俗透彻,决定重新开启这个系列,这一篇是word2vec_word2vec 查看token

【愚公系列】2023年06月 网络安全(交通银行杯)-AES加密_银行aes加密-程序员宅基地

文章浏览阅读4.1k次。AES即高级加密标准(Advanced Encryption Standard),是一种对称密钥加密算法。它采用128、192和256位密钥,并且对明文进行分块加密。AES算法使用替换、置换、XOR和线性运算等基本加密算法,在加密和解密时都使用相同的密钥。AES算法主要分为四个步骤:密钥扩展、初始轮、重复轮和最终轮。密钥扩展将一次性密钥扩展成多个轮密钥,重复轮将轮密钥用于执行加密或解密操作,最终轮是一个特殊的加密轮,用于处理最后一个分组的加密或解密操作。AES算法应用广泛,特别是在安全领域。_银行aes加密

LTE资源调度(4)-上行资源申请方式和BSR缓存状态报告_上行资源分配协议-程序员宅基地

文章浏览阅读2.6w次,点赞28次,收藏171次。1.UE申请上行资源的途径当UE需要向网侧发送数据的时候,必须要有上行RB资源,如果没有RB资源则需要先向网侧申请RB资源。UE有三种方式向网侧申请RB资源:(1)向网侧发送BSR。BSR的全称是Buffer Status Report,即缓存状态报告。UE可以在MAC层的PDU(即分组数据单元)中插入一个BSR控制单元来告诉网侧:我的某个逻辑信道组或某几个逻辑信道组有多少多少的数据需要发送,希望_上行资源分配协议

Word实现论文编辑中大批量公式居中,编号右对齐格式,同时消除编号上下不居中问题,完全版!!!_word多行公式编号居中-程序员宅基地

文章浏览阅读6k次,点赞14次,收藏31次。在写论文的过程中,往往要求公式要居中,同时编号要右对齐。如何实现,请看下文:最方便的方法——制表位法:(原理:通过设置两个标识位来分别对公式和编号对齐)1.打开制表位,方法:右键单击公式所在行---->段落---->左下角“制表位”2.设置制表位,方法:“全部清除”---->设置居中制表位---->设置右对齐制表位在设置之前,先看纸张大小和..._word多行公式编号居中

基于Python爬虫广西招聘信息数据可视化和岗位查询系统(Django框架) 研究背景和意义、国内外现状_3000字的《招聘网站数据可视化平台》的开题报告,要求国内外研究现状及发展趋势不-程序员宅基地

文章浏览阅读2.2k次,点赞25次,收藏31次。基于Python爬虫广西招聘信息数据可视化和岗位查询系统(Django框架) 研究背景和意义、国内外现状。例如,在国内,拉勾网、BOSS直聘等招聘网站提供了丰富的招聘信息,并且提供了基于地域、薪资、行业等条件的岗位查询功能。这个系统的开发将减少求职者在查询和筛选招聘信息上的时间和精力成本,提高求职者的效率。总之,基于Python爬虫的广西招聘信息数据可视化和岗位查询系统有着重要的现实意义,可以提高求职者的效率,为企业和政府部门提供数据支持,同时也填补了国内广西地区招聘信息展示和岗位查询系统的空白。_3000字的《招聘网站数据可视化平台》的开题报告,要求国内外研究现状及发展趋势不

【基于HTML5的网页设计及应用】——事件代理.-程序员宅基地

文章浏览阅读814次,点赞16次,收藏15次。【基于HTML5的网页设计及应用】——事件代理.

推荐文章

热门文章

相关标签