个人使用 Gatsby 已经有一段时间了。去年年底接触到 Gatsby ,开始摸索这个新玩具。用 Gatsby 造了博客轮子后,对 Gatsby 及其周边生态有了一个大概的了解。这篇文章是个人使用 Gatsby 的一些总结。
什么是 Gatsby
Gatsby is a free and open source framework based on React that helps developers build blazing fast websites and apps
Gatsby 将各种数据源汇总,转化成通用 GraphQL 数据,然后 SSR 渲染成静态页面。
Gatsby 适合做什么
https://www.gatsbyjs.com/showcase/
拿 Gatsby 可以写一个静态博客,但不仅仅是写静态博客。Gatsby 是一个比较通用的建站工具。只不过在静态内容的处理上更有优势,你也可以加入动态内容,也就是普通的 React 开发模式,请求 API 拿数据,然后再渲染页面。动态和静态,二者并不冲突。
官方的 showcase 里面给了很多例子,涵盖了大部分的站点类型,个人博客、公司主页、商品展示、API 文档(React 的官方文档就是使用 Gatsby 构建的)。
是否选择用 Gatsby 构建站点,有2点需要考虑。
这里的构建是指走 Gatsby 的 build 流程:拉取数据 > Graphql >SSR。
- SEO
- 静态站点的先天优势。
- 数据量
- UGC 站点不适合,因为 Gatsby build 耗时取决于数据量。比如微博这样的站点,只能动态渲染,不可能做到一次性 build 出所有页面。当然这并不冲突,任何站点都包含静态内容,不管是服务端渲染返回的,还是纯静态的 html。对于这些静态部分的内容,使用 Gatsby 构建是适合的。
综上2点。如果某个化妆品公司需要搭建一个官方站点,在站点中介绍公司及其产品。那么这时候使用 Gatsby 构建是非常合适的。首先,静态内容可以保证 SEO ,能够有效地获取到流量,宣传公司及其产品。然后,化妆品公司的产品种类是有限的,数据量级是很小的,更新频率很低(不会频繁的 build 站点)。
总体说来,在任何存在静态内容的地方,你都可以使用 Gatsby 构建,Gatsby 提供了开箱即用的脚手架,可以快速的生成项目文件。秉承着约定大于配置的原则,按照 Gatsby 的约定格式(pages 目录下新建页面),则无需处理路由这些问题。
对于无法控制数据量级的动态内容,大可采用静态+动态结合的模式,在静态部分使用 Gatsby 构建,动态内容渲染则使用普通的 Ajax 模式。
Gatsby 为什么这么快
这里的快是指成品站点的使用体验,涉及到一些前端优化的知识。大致是可以分为2点。
- 缓存
$$ t = s/v $$
很简单的道理,从本地获取数据。s 无限趋近于 0, t 无限趋近于 0。静态文件很方便缓存。需要在服务端开启。
- 预取
主动的缓存,在用户还未访问某个页面时,获取页面内容。但是这样会造成一定的资源浪费。
这就好比你去食堂吃饭,饭都是一碗一碗的事先盛好,放在那里。而不是等你来了才给你打饭。先盛好的饭可能会冷。
Gatsby 会对页面内链接的其它页面进行预取。如下图所示,Gatsby构建的站点,html 头部会包含大量的预取内容。
Gatsby 构建站点时,会渲染出每一个页面的 html,即静态的网页文件。当用户首次访问 /posts/第一篇文章
这样的链接时,这时候返回的是静态 Html 网页文件,第一篇文章.html
。如果这个页面内包含第二篇文章的链接,浏览器会预取 第二篇文章.json
和 文章模板.js
。当用户通过链接访问 /posts/第二篇文章
时,并不会返回 第二篇文章.html
这个文件,而是会动态渲染,通过模板和数据渲染出第二篇文章的页面。
即用户的着陆页是静态 HTML ,在此之后路由是被 React 接管的,通过页面内链接访问站内内容都是动态渲染。
基于这样的实现,Gatsby 既满足了 SEO 的需要,又真他妈的快。
怎么让 Gatsby 站点更快
老实说来,Gatsby 在静态内容的处理上已经做了很多工作,可优化的地方比较少。但是优化是没有止境的,下面2篇记录了部分优化的过程。
https://gine.me/posts/64b7a2b265f94447902af60cf3dbd236
https://gine.me/posts/25553b3aa5d0421c908fea9008d9e032
主要还是围绕缓存做文章。PWA 可以改善弱网环境下的访问体验,将客户端缓存做到了极致。网络方面上 CDN 即可,没啥好说的。对于静态站点来说上了 CDN,TTFB 自然就降下来了。
Gatsby 的生态与发展
Gatsby 是基于React 的,可以享受到 React 生态中的一切资源。
插件生态
Gatsby 提供了很多官方的插件,这些插件可以满足不同用户群体的需求。通过插件,你可以把 Gatsby 站点打造的很强大。
在 Gatsby 中插件主要分为下面几种类型。
- source
处理数据源,将各种数据源转化成 gatsby 中可用的 graphql 数据。
- transformer
数据处理,将不同格式的数据转化成 JS 对象。
- theme
主题
https://www.gatsbyjs.com/plugins
博客生态
很多人会拿 Gatsby 和 Hexo 这类静态博客生成器做对比。 相比于专注静态博客的前辈们,Gatsby 的这类通用型的建站工具在博客方面不怎么流行。接触过 Gatsby 的同学,大都会赞叹于它的理念,但是下定决心把博客从 Hexo 迁移到 Gatsby 的却不是很多。
开始接触 Gatsby 时,我使用 Gatsby 写自己的博客轮子。一段时间后发现了一些同好,大家都有这样的感叹,Gatsby 的博客生态不怎么繁荣。究其原因,存在以下几点问题。
- Gatsby 缺少博客主题
- Gatsby 是泛用型的生成器,可以从不同的数据源获取数据,对于文章格式缺乏统一的规范。没有 Hexo 那样的 Front-matter。由此造成,基于 Gatsby 写的博客没有通用性,博客之间无法平滑地迁移主题。
博客的核心是主题,好看是第一生产力。
终于Gatsby 社区搞清楚了这个问题,Gatsby 今年 7月正式推出了 theme。主题是一个 npm 包,这样他人可以通过安装包来使用主题,并且可以按规则重载主题,这样可玩性和通用性又提高了不少。这解决了上面的第一个问题——缺少博客主题。
https://www.gatsbyjs.com/blog/2019-07-03-announcing-stable-release-gatsby-themes/
针对第二个问题,Gatsby 社区好像也没啥动静,作为一个泛用型生成器,很难做得面面俱到。毕竟 theme 的推出已经前进了一大步,有了很多的可能性。
发现与探索——预取的学问
在 Gatsby 为什么这么快
中,提到了 Gatsby 的预取方案。Gatsby 是很快,但是这个快是有代价的。只要是使用了 Link 组件(Gatsby 提供的链接组件)的链接,Gatsby 都会预取其内容,不管用户是否会访问到这些链接的页面,这样会额外消耗用户的流量。
Google 受到 Gatsby 的启发,搞了个新项目 —— quicklink
https://github.com/GoogleChromeLabs/quicklink
quiclink 是一套通用的方案,并且做出了一些改进(不再无脑预取所有链接内容),可以用在任何网页中。当然这样还是会损耗用户的流量,于是 Google 又搞了一套数据驱动的方案 —— Guess.js
相比于前两者,Guess.js 更加智能,它会预取访问频率较高的链接。缺点是需要和 ga 搭配使用(毕竟要先有数据)。Guess.js 也有 Gatsby 插件。
https://www.gatsbyjs.com/docs/how-to/performance/improving-site-performance/
速度快是要付出代价的。但是对于用户而言,流量这个东西是很难感知到的。现在流量这么便宜,用户体验可能更重要一些。
Netlify —— 静态站点的好伙伴
Netlify 对静态站点提供了一站式的解决方案。从 git 仓库拉取代码,提供 build 环境,部署 CDN 什么的一条龙服务,可以说是十分贴心了。
你可以对不同的分支进行部署和预览,你可以添加 hook 一键部署,你还可以定制哪些文件缓存多长时间。其功能和优点这里就不再赘述了,总之很棒。
但是对于国内用户来说,GitHub pages 和 Netlify 的 CDN 速度都差不多,所以很难感受出什么区别。因此你可能需要套一层 Cloudflare ,相对而言会快一点。
Netlify 的老板提出了一种新的理念 —— JAMStack 。我比较喜欢这个模式,因为它真的很爽。
后面可能会写一篇关于这个主题的文章。