- 笔记/
服务端渲染gatsby简介
Table of Contents
目前react在市面上的渲染方案 #
React 在市场上的渲染方案可以分为:客户端渲染(Client-side Rendering,CSR)和服务端渲染(Server-side Rendering,SSR),静态网站生成器(Static Site Generator,SSG)
-
客户端渲染(CSR)客户端渲染是指在浏览器中使用 JavaScript 处理页面的渲染和数据交互。在这种模式下,React 的工作方式是将应用程序的代码打包成一组 JavaScript 文件,浏览器会下载这些文件并在页面上动态渲染。常见的客户端渲染方案有使用 React 自带的 create-react-app 脚手架。
-
服务端渲染(SSR)服务端渲染是指在服务器端使用 React 处理页面的渲染和数据交互,服务器将整个渲染好的页面发送给浏览器。这种模式下,React 的工作方式是在服务器上预渲染应用程序并将其传输给浏览器,然后进行客户端渲染。常见的服务端渲染方案有使用 Next.js、Remix等框架。
-
静态网站生成器(Static Site Generator,SSG)简单来说,SSG 是一种将动态内容转换为静态站点的技术,可以将动态内容渲染为 HTML、CSS 和 JavaScript 文件,并将其发布到 HTTP 服务器上,从而使之可以像普通静态文件一样访问。与传统的 CMS 不同,SSG 将内容存储在文件而不是数据库中,可以将该文件作为静态资源部署到 Web 服务器或者 CDN 中。使用 SSG 可以实现非常快速的页面加载速度,因为页面需要的数据和 HTML 已经预先生成,而不用等待服务器渲染动态内容。而且,SSG 还可以提升 SEO,因为生成的静态页面对搜索引擎爬虫更加友好。SSG 可以轻松应用于各种 Web 项目中,例如博客、商业网站和电子商务网站等等。常见的静态站点生成器包括 Gatsby、Hugo等。需要注意的是,虽然 SSG 能快速提高 Web 应用的性能和 SEO,但是对于包含动态内容的应用程序,SSG 可能无法满足需求。因此,在选择使用 SSG 技术时,需要考虑项目的实际需求以及业务规模。
需要注意的是,使用不同的渲染方案可能会对页面性能、SEO、开发效率等方面产生不同的影响,具体选择渲染方案时需要根据项目需求进行权衡和选择。
区分一下使用场景 #
对于不同使用场景需要采用不同的渲染方式
-
面向C端的动态网站
-
需要考虑seo的如:网站官网、博客。这时候需要使用Next.js,SSR
-
不需要seo的如:云服务器控制台,用cra或umi即可,CSR
-
-
需要面向C端的静态网站(天然有SEO)
-
官网,一般不包含太多的动态信息,SSG
-
文档类型的网站,SSG
-
-
面向企业的网站
- 管理后台(完全不需要SEO): CSR
方案对比 #
需要 SSR - Next.js #
-
第一步,打开浏览器,访问这个 blog 网站的文章列表页面 (
/
或者/articles
)。 -
第二步,请求到达服务器的 nginx,nginx 设置的规则是,如果请求匹配
/api/v1/\*
,则转给 API 服务处理,否则如果匹配/\*
,则转给 next.js 服务处理,所以/articles
请求发送给了 next.js 服务。 -
第三步到第六步,next.js 收到
/articles
请求后,会选择渲染文章列表界面,假如这个 page 叫 ArticleListPage,在这个 component 中,next.js 的 getInitialProps() 方法会去访问 API 服务的/api/v1/articles
API,获得所有的 articles 数据 (不考虑分页),然后渲染出 html,html head 中 link 了 bundle 的所有 js 代码,html 返给浏览器。 -
第七步,浏览器得到了 html 后,进行首屏渲染,用户马上就看到了内容。浏览器解析完 html 后,会继续下载 html 中 link 的 js 代码并执行,然后该网站就变成了一个 SPA,js 接管剩余的所有路由,并且 js 会把此页面用 js 再重新渲染一遍 (用户没有感知)。
-
第八步到第九步,用户点击某篇文章查看详情,比如
/articles/1
,由于 js 在客户端已经接管了路由,所以这个请求并不会发送到服务端的 nginx,js 代码根据路由,切换到详情页面 (比如 ArticlePage) 组件,在这个组件在 getInitialProps() 方法中,它会发送/api/v1/articles/1
的 ajax 请求去访问 API 获取文章的详情数据。 -
第十步到第十一步,
/api/v1/articles/1
的请求到达服务端的 nginx 后,转发给 API 服务处理,API 从数据库查询得到结果返回给浏览器,浏览器渲染之。整个流程结束。
CSR - CRA/Umijs #
不需要太多解释,典型的 SPA,大家对这个再熟悉不过了。
CRA build 后,得到空白 body 的 index.html 和 bundle.js (不考虑 split) 静态文件,浏览器首次访问任何页面,得到同一个 index.html,然后下载 index.html 中 link 的 bundle.js 并执行,js 在客户端这边接管剩余路由,用 js 渲染相应的页面,在不同的页面通过 ajax 请求访问不同的 API。
静态网站 - Gatsby #
工作流程:
-
gatsby 从各处数据源获取数据,build 后一次性生成所有静态页面,包括 html / json / bundle.js,一个页面就有一个 html 和 json,比如 articles.html / articles-$hash.json, hello.html / hello-$hash.json,然后把这些静态文件扔到 CDN 上即可 (比如 netlify)
-
浏览器首次访问某个页面,比如
/articles
,则得到的是/articles.html
,如果是/hello
,则得到的是/hello.html
,假定这里我访问的是/articles
。 -
每个 html 的 head 都 link 了 bundle.js (实际做了 split,拆成了很多个 js,这里做简化处理),浏览器解析并渲染 html 后,下载并执行 bundle.js,接管所有剩余路由。
-
接下来就是 gatsby 相比 jekyll/hugo 这些静态建站工具的特别之处了,如果此时我点击某篇文章的详情,假如是
/hello
,jekyll/hugo 会去 CDN 访问相应的 html 文件,但 gatsby 不会,前面说到,它会在客户端这边接管所有剩余的路由,因此 gatsby 会根据/hello
路由在客户端这边用 js 渲染相应的页面,那数据来自何处,前面说到每一个 html 都有一个相应的 json 文件,json 文件存储的就是各页面对应的数据,因此 gatsby 在客户端渲染不同的页面时,会通过 ajax 请求去取相应的 json 文件,取回来后解析成 object 作为各个 component 的 props。详细的分析看这篇文章 - gatsby 是如何做到无刷新的页面跳转以及瞬间加载
基于以上三种渲染方式的分析,我们可以看出,SSR的速度取决于服务器渲染出页面的速度,而CSR则是在客户端获取JS以后再进行渲染的,而SSG则是生成好的html后续通过json获取数据。
由于CSR首屏渲染白屏的问题,因此可以不考虑CSR来作为官网开发。SSR是服务端渲染因此速度上会逊色于静态网站,可以看出三个对比下来使用Gatsbyjs来开发官网是个很不错的选择。使用nginx来做静态文件服务器,可以轻松实现高并发、良好的SEO。
使用Gatsby #
快速开始 #
-
创建一个新的 Gatsby 项目
npm init gatsby
这个命令会要求您填写站点标题和项目目录的名称。继续按照提示选择您喜欢的语言(JavaScript 或 TypeScript)、CMS、样式工具和其他功能。
- 下载完成后,您将看到一条消息,其中包含导航到您的站点并在本地运行它的说明。
命令行界面(CLI)创建了一个新文件夹,该文件夹的名称与您在第 1 步中选择的名称相同。
请先进入该文件夹目录:
cd my-gatsby-site
-
启动开发服务器
npm run develop
Gatsby 将启动一个热加载的开发环境,默认情况下可以访问 http://localhost:8000
创建页面 #
-
在
src/pages
目录下创建一个新的页面,比如about.js
import React from “react”
const AboutPage = () => { return
About Us
}export default AboutPage
2. 访问 http://localhost:8000/about
页面,你应该可以看到 About Us
字样
查询数据 #
-
Gatsby 通过 GraphQL 来管理数据
-
在页面组件中添加一个 GraphQL 查询:
import React from “react” import { graphql } from “gatsby”
const BlogPost = ({ data }) => { const post = data.markdownRemark
return (
{post.frontmatter.title}
<div dangerouslySetInnerHTML={{ __html: post.html }} />export const query = graphql
query ($slug: String!) { markdownRemark(fields: { slug: { eq: $slug } }) { frontmatter { title } html } }
部署 #
-
在
package.json
文件中添加一个脚本{ “scripts”: { “build”: “gatsby build” } }
-
执行以下命令生成静态文件
npm run build
-
将
public
目录下的文件上传到服务器
结合Wordpress CMS #
由于目前的需求是一个官网程序,并且需要文章或者公告之类的功能,因此需要引入成熟的CMS。 要在 Gatsby 中集成 WordPress CMS,可以使用 gatsby-source-wordpress
插件。该插件提供了将 WordPress 数据源转换为 Gatsby 数据层查询类型的方法,从而可在 Gatsby 网站中使用 WordPress 数据。
以下是一个简单的集成 WordPress CMS 的步骤:
-
安装
gatsby-source-wordpress
插件:可以通过 npm 安装该插件:npm install –save gatsby-source-wordpress -
配置插件:在
gatsby-config.js
文件中添加以下配置信息:module.exports = { plugins: [ { resolve: “gatsby-source-wordpress”, options: { url: “https://your-wordpress-site.com/graphql”, nodeUpdateInterval:60000 // 本地运行时刷新的时间 }, }, ], };
可以根据需要自定义配置,包括 WordPress 网站的 URL、GraphQL 的 schema 和 type 等。
3. 在 GraphQL 查询中使用 WordPress 数据:创建并在src/templates/blog-post.js
使用graphql查询信息,
import React from "react"
import { Link, graphql } from "gatsby"
import { GatsbyImage } from "gatsby-plugin-image"
import parse from "html-react-parser"
// We're using Gutenberg so we need the block styles
// these are copied into this project due to a conflict in the postCSS
// version used by the Gatsby and @wordpress packages that causes build
// failures.
// @todo update this once @wordpress upgrades their postcss version
import "../css/@wordpress/block-library/build-style/style.css"
import "../css/@wordpress/block-library/build-style/theme.css"
import Bio from "../components/bio"
import Layout from "../components/layout"
import Seo from "../components/seo"
const BlogPostTemplate = ({ data: { previous, next, post } }) => {
const featuredImage = {
data: post.featuredImage?.node?.localFile?.childImageSharp?.gatsbyImageData,
alt: post.featuredImage?.node?.alt || ``,
}
return (
<Layout>
<Seo title={post.title} description={post.excerpt} />
<article
className="blog-post"
itemScope
itemType="http://schema.org/Article"
>
<header>
<h1 itemProp="headline">{parse(post.title)}</h1>
<p>{post.date}</p>
{/* if we have a featured image for this post let's display it */}
{featuredImage?.data && (
<GatsbyImage
image={featuredImage.data}
alt={featuredImage.alt}
style={{ marginBottom: 50 }}
/>
)}
</header>
{!!post.content && (
<section itemProp="articleBody">{parse(post.content)}</section>
)}
<hr />
<footer>
<Bio />
</footer>
</article>
<nav className="blog-post-nav">
<ul
style={{
display: `flex`,
flexWrap: `wrap`,
justifyContent: `space-between`,
listStyle: `none`,
padding: 0,
}}
>
<li>
{previous && (
<Link to={previous.uri} rel="prev">
← {parse(previous.title)}
</Link>
)}
</li>
<li>
{next && (
<Link to={next.uri} rel="next">
{parse(next.title)} →
</Link>
)}
</li>
</ul>
</nav>
</Layout>
)
}
export default BlogPostTemplate
export const pageQuery = graphql`
query BlogPostById(
$id: String!
$previousPostId: String
$nextPostId: String
) {
post: wpPost(id: { eq: $id }) {
id
excerpt
content
title
date(formatString: "MMMM DD, YYYY")
featuredImage {
node {
altText
localFile {
childImageSharp {
gatsbyImageData(
quality: 100
placeholder: TRACED_SVG
layout: FULL_WIDTH
)
}
}
}
}
}
previous: wpPost(id: { eq: $previousPostId }) {
uri
title
}
next: wpPost(id: { eq: $nextPostId }) {
uri
title
}
}
`
以上是一些基本的 wp 集成设计,如果你想获取更多的数据信息,请参考 gatsby-source-wordpress
的官方文档。
以上是一个 Gatsby 的基本使用流程,如果你想深入了解 Gatsby,可以参考官方文档:https://www.gatsbyjs.com/docs/
问题 #
使用这种前后端分离的CMS时候,gatsby并不支持动态生成,这里指的是如果文章更新了,生产上不会实时更新,需要重新走一遍CI/CD的过程。跟预期的新增文章,相应的网站内容也需要更新是不符合的。这时候可以选择使用next.js或者使用wordpress本身的webhook触发CI/CD。
总结 #
Gatsby 是一个基于 React 的静态网站生成器,它可以帮助开发人员快速构建高性能、可扩展的静态网站,不需要手动处理复杂的构建过程。
以下是 Gatsby 框架的特点和优势:
1. 基于 React #
Gatsby 是一个基于 React 的静态网站生成器,它使用 React 组件来构建页面布局并处理数据。由于 React 具有出色的性能和可重用性,因此 Gatsby 的代码结构非常简洁、模块化和易于维护。
2. 静态网站生成器 #
Gatsby 是一个静态网站生成器,它可以将您的 React 组件和数据转换为静态 HTML、CSS 和 JavaScript 文件。与传统的动态网站相比,静态网站的优点在于速度快、安全性高、可缓存性强。
3. 内置优化 #
Gatsby 内置了多项性能优化功能,如懒加载、图片压缩、响应式图片、代码分割、缓存等。这些功能可以大大提高网站的加载速度、交互体验和搜索引擎优化。
4. 插件生态 #
Gatsby 拥有庞大的插件生态,开发者可以通过插件轻松地实现各种功能,如数据源集成、样式处理、SEO、社交分享等。这些插件极大地提高了开发效率和代码质量。
5. 部署易用性 #
Gatsby 的静态文件可以轻松地部署到各种托管服务上,如 Github Pages、Netlify、AWS S3 等。无需繁琐的服务器配置和部署流程,大大降低了网站的部署难度和成本。
综上所述,Gatsby 框架是一个灵活、高效、易用的静态网站生成器,适合各种类型的静态网站和 Web 应用的开发。