在之前的 一篇文章里,初步介绍了 Jamstack 这套建站技术栈的背景以及各方面优劣势。
所以这次这篇文章会更加深入,聊聊这套技术栈的演进以及业界的一些最佳实践。
在开始阅读之前,先解释一下文章里用到的英文缩写:
SSR 这套技术栈相信很多人应该都非常熟悉了(如果你不熟悉的话可以先阅读相关文章),React/Vue/Angular 等等都从框架层面直接提供了支持,例如在 React 中你可以这样使用:
import React from 'react'import ReactDOMServer from 'react-dom/server'
const html = ReactDOMServer.render(<h1>Hello, world!</h1>)
SSR 最早是为了解决单页应用(SPA)产生的 SEO、首屏渲染时间等问题而诞生的,在服务端直接实时同构渲染用户看到的页面,能最大程度上提高用户的体验,流程类似下面:
但 SSR 引入了另一个问题,既然要做服务端渲染,就必然需要一个实时在线的后台服务(通常是基于 Node.js 的服务)用来承载页面请求,那么:
有没有办法解决这些问题呢?
我们重新对 SSR 进行审视,服务端渲染出的页面,逻辑上讲可以分成下面两大块:
例如,在一篇文章的页面中,文章的主题内容是偏向于静态的,很少有改动,那么每次用户的页面请求,都通过服务端来渲染就变得非常不值得,因为每次服务端渲染出来大部分内容都是一样的!
我们完全可以将文章的页面渲染为静态页面,至于页面内那些动态的内容(用户头像、评论框等),就通过 HTTP API 的形式进行浏览器端渲染(CSR):
这样做有很多好处:
这便是 Gatsby.js、Next.js 这样的网站生成器解决的问题,他们属于 React/Vue 更上一层的框架(Meta Framework),通过 SSR 把动态化的 Web 应用渲染为多个静态页面,并且对高度动态的内容也保留了 CSR 的能力。
细心的同学一定发现了 SSG 这样的模式,看似美好,但存在一个瑕疵:
对于只有几十个页面的个人博客、小型文档站而言,数据有变化时,跑一次全页面渲染的消耗是可以接受的。
但对于百万级、千万级、亿级页面的大型网站而言,一旦有数据改动,要进行一次全部页面的渲染,需要的时间可能是按小时甚至按天计的,这是不可接受的。
为了解决这个问题,各种框架和静态网站托管平台都提供了不同的方案,这里我们介绍 ISR 和 DPR 两种。
既然全量预渲染整个网站是不现实的,那么我们可以做一个切分:
页面的更新遵循 stale-while-revalidate 的逻辑,即始终返回 CDN 的缓存数据(无论是否过期);如果数据已经过期,那么触发异步的预渲染,异步更新 CDN 的缓存。
这就是增量式更新(ISR)的概念,这个概念最早由 Next.js 在 9.5 版本中提出,下面是一个小 Demo:
Static Reactions Demo: https://reactions-demo.vercel.app/
在 Next.js 中,你可以使用 getStaticPaths() 来定义哪些路径需要预渲染,通过 getStaticProps() 来获取预渲染需要的数据:
//定义哪些页面需要预渲染
export async function getStaticPaths() {
return {
// 只有 /posts/1 和 /posts/2 会被预渲染
paths: [{ params: { id: '1' } }, { params: { id: '2' } }],
// 其它页面,如 /posts/3,都会返回 fallback 页面,然后 CSR
fallback: true,
}
}
// 定义预渲染需要的数据
export async function getStaticProps({ params }) {
// 拉取对应的文章内容
const res = await fetch(`https://.../posts/${params.id}`)
const post = await res.json()
return {
props: { post },
revalidate: 60 // 数据有效期为 60 秒
}
}
但 ISR 存在部分缺陷:
Incremental Static Regeneration: Its Benefits and Its Flaws: https://www.netlify.com/blog/2021/03/08/incremental-static-regeneration-its-benefits-and-its-flaws/
为了解决 ISR 的一系列问题,Netlify 在前段时间发起了一个新的提案:
Distributed Persistent Rendering (DPR): https://github.com/jamstack/jamstack.org/discussions/549
DPR 本质上讲,是对 ISR 的模型做了几处改动,并且搭配上 CDN 的能力:
在 Netlify 平台上,你可以像这样定义一个 Builder,用于预渲染或者实时渲染。这个 Builder 将会以 Serverless 云函数的方式在平台上运行:
const { builder } = require("@netlify/functions")
async function handler(event, context) {
return {
statusCode: 200,
headers: {
"Content-Type": "text/html",
},
body: `<!DOCTYPE html> <html> <body> Hello World </body> </html>`,
};
}
exports.handler = builder(handler);
更多详细信息可以参考文档: https://docs.netlify.com/configure-builds/on-demand-builders/
当然 DPR 还在很初期的阶段,就目前的讨论来看,依然有一些问题:
Jamstack 这套技术栈在国外的流行,很大程度上得益于近年来相关云服务和云平台的成熟:
Jamstack 非常适合以呈现内容为主的网站,如文档、博客、电商网站、论坛、官网等等,所以更多地应该将它视为“建站技术”,是目前诸多建站技术栈(LAMP、MEAN 等等)的一个新生替代品。极低的运维成本、Serverless、快速、安全、且不损失网站的动态性,是它的核心优势。
当然它本身并不是完美的,SSG、ISR、DPR 这些解决方案,都或多或少有一些瑕疵和问题,它们本质上就是在平衡动态性、渲染性能、缓存性能这三个矛盾点,依然需要继续探索和演进下去。
另外,除了上文提到的 Netlify 和 Vercel 这两家小而美的平台以外,国外的几家大型云厂商(GCP、AWS、Azure)也提供了类似的产品,向 Web 前端开发者提供对 Jamsatck 等新生代技术栈的支持:
国内市场上,这块产品目前还处于缺位的状态,虽然底层的 IaaS 能力(对象存储、CDN、Serverless、网关等等)都趋近于完善,但还缺少能够把这些能力组合封装起来的一层,前段时间我也表达过类似的想法:
“经常看到有人讨论为啥国内没有 netlify、vercel 这样的 web 托管产品,其实在国内要做个类似的东西还真没那么容易,起码要打通 CDN、对象存储、Serverless、API 网关,正式产品化的话还要考虑计费、安全、用户隔离等等,能完整提供这套基建的国内厂商就 AT 两家,并且边边角角上还缺了挺多能力的。”
当然除了技术层面的原因外,国内外的市场、网络环境、技术生态都是完全不同的,仅仅是 “Copy to China” 的方式很可能会导致产品水土不服,不过这就超出本文的范畴了,可以后续安排一篇文章详细聊聊。
云开发(Tencent CloudBase,TCB)是腾讯云提供的云原生一体化开发环境和工具平台,为开发者提供高可用、自动弹性扩缩的后端云服务,包含计算、存储、托管等 serverless 化能力,可用于云端一体化开发多种端应用(小程序,公众号,Web 应用,Flutter 客户端等),帮助开发者统一构建和管理后端服务和云资源,避免了应用开发过程中繁琐的服务器搭建及运维,开发者可以专注于业务逻辑的实现,开发门槛更低,效率更高。
开通云开发: https://console.cloud.tencent.com/tcb?tdl_anchor=techsite
产品文档: https://cloud.tencent.com/product/tcb?from=12763
技术文档: https://cloudbase.net?from=10004
技术交流群、最新资讯关注微信公众号【腾讯云云开发】
代做工资流水公司许昌代做工资银行流水孝感入职银行流水镇江银行流水修改多少钱台州对公银行流水查询泰州打印对公账户流水台州查询工资流水盐城查询工资流水app截图揭阳企业对公流水办理长春银行流水PS办理南昌公司流水代开珠海制作流水单阜阳打对公流水长春企业对公流水打印绵阳办理银行流水PS兰州背调工资流水公司兰州企业对公流水查询上海打印对公账户流水宜昌公司银行流水模板重庆代办背调工资流水芜湖对公账户流水报价石家庄查询转账流水济南银行流水修改代做西宁房贷工资流水 打印鞍山打流水单开封银行流水电子版查询包头代办流水单柳州房贷工资流水 制作汕头对公账户流水图片惠州贷款工资流水 开具扬州代做个人流水香港通过《维护国家安全条例》两大学生合买彩票中奖一人不认账让美丽中国“从细节出发”19岁小伙救下5人后溺亡 多方发声卫健委通报少年有偿捐血浆16次猝死汪小菲曝离婚始末何赛飞追着代拍打雅江山火三名扑火人员牺牲系谣言男子被猫抓伤后确诊“猫抓病”周杰伦一审败诉网易中国拥有亿元资产的家庭达13.3万户315晚会后胖东来又人满为患了高校汽车撞人致3死16伤 司机系学生张家界的山上“长”满了韩国人?张立群任西安交通大学校长手机成瘾是影响睡眠质量重要因素网友洛杉矶偶遇贾玲“重生之我在北大当嫡校长”单亲妈妈陷入热恋 14岁儿子报警倪萍分享减重40斤方法杨倩无缘巴黎奥运考生莫言也上北大硕士复试名单了许家印被限制高消费奥巴马现身唐宁街 黑色着装引猜测专访95后高颜值猪保姆男孩8年未见母亲被告知被遗忘七年后宇文玥被薅头发捞上岸郑州一火锅店爆改成麻辣烫店西双版纳热带植物园回应蜉蝣大爆发沉迷短剧的人就像掉进了杀猪盘当地回应沈阳致3死车祸车主疑毒驾开除党籍5年后 原水城县长再被查凯特王妃现身!外出购物视频曝光初中生遭15人围殴自卫刺伤3人判无罪事业单位女子向同事水杯投不明物质男子被流浪猫绊倒 投喂者赔24万外国人感慨凌晨的中国很安全路边卖淀粉肠阿姨主动出示声明书胖东来员工每周单休无小长假王树国卸任西安交大校长 师生送别小米汽车超级工厂正式揭幕黑马情侣提车了妈妈回应孩子在校撞护栏坠楼校方回应护栏损坏小学生课间坠楼房客欠租失踪 房东直发愁专家建议不必谈骨泥色变老人退休金被冒领16年 金额超20万西藏招商引资投资者子女可当地高考特朗普无法缴纳4.54亿美元罚金浙江一高校内汽车冲撞行人 多人受伤