Pages

Thursday, 20 October 2016

静态网站生成器将是下一个大事件

英文出处:smashingmagazine

在 StaticGen,我们有一个关于静态站点生成器的开源目录,在这一年多我们追踪了超过一百个生成器。在那段时间里,我们见证着这些项目的数量和流行度在 Github 上高涨得不可思议——从只有 50 个到超过 100 个,直到有关静态站点的库获得了超过 10 万的 Stars。
像 Nest 和 MailChimp 这样专注于设计的知名公司,已经将静态站点生成器用于其主网站的开发。 Vox Media 围绕 Middleman 建立了一整套系统。 Carrot,一个大型的纽约中介、 Vice 帝国的一部分,用它自己的开源生成器 Roots 给世界的一些大品牌建站。一些 Google 的产品,像“A Year In Search ”和 “Web Fundamentals”也是静态的。
StaticGen’s Graph of growth over the last year.(看大图)
静态站点不是新事物,可以追溯到 Web 伊始之时。为什么会有爆发性的关注度?发生了什么?为什么是现在?

静态是什么时候产生的

第一个网站—— Tim Berners-Lee 的万维网处女页——就是静态的。那时的站点仅仅由一个文件夹下的一组 HTML 文档组成,而且HTML文件只包含18种标签。浏览器只是简单的文本导航器,它从服务器端抓 HTML,终端用户可以由超链接导航。Web基本上是静态的。
随着浏览器和 HTML 的演进,我们逐渐看到了纯静态站点的限制。
起初,网站只是无样式纯文档,但很快便被精心设计,带有图形头和复杂导航。从那时开始,管理自己网页的每个文档失去意义,模版语言进入大众视野。
显然,使用 HTML 作结构、CSS 作设计,无法抽象内容(像故事板、产品、零挂件等等)与设计分离的理念。
几乎同一时间,基于 SQL 的关系型数据库开始成为主流。对于许多在线公司而言,数据库成为了他们存储内容的圣地,由警惕的长胡子数据库管理员看守着。
像 Dreamweaver 和 FrontPage 一类的桌面应用也有建立内容驱动型网站的解决方案——使用所见即所得的编辑器——页面可以被分离成可重用组件,例如导航、头部、尾部。这些内容很大程度上也能被存到数据库中。虽然它们有很大的缺陷,从某种程度上讲,这就是最原始的静态站点生成器:从模版、部件、媒体库甚至是 SQL 数据库获得资源创建站点,通过 FTP 发布静态文件。直到 2004 年,我才得以在大型内容网站工作一段时间,成千上万的页面在不同的编辑组传播,全都通过 Dreamweaver 管理。
即使 Dreamweaver 在某种程度上能够与数据库整合,它却不具备内容模型,没有内容与形式分离的概念,无法将内容与形式用合适的工具独立编辑。
最主流的解决方案是 LAMP 栈和像 WordPress 、 Drupal 和 joomla 这样的 CMS ,这些在推动 Web 2.0 演进有着不可或缺的作用。 2.0 时代许多网站的关键功能是用户生成内容。用户从点击超链接变成了订购商品、参与社区,以及创建内容。

动态问题

我 15 年前第一次建立动态站点时,我遵循着 MySQL 文档的 LAMP 栈手册。这样建立的站点,每次有访客时都要执行一次这种流程,意识到这些时我简直疯了!
Web 服务器尽快把我的代码加载到 PHP 解释器里,然后打开数据库连接池,来回发送查询语句,使用模版中的数据并将文本字符串拼接到 HTML 文档中,之后呈现给访客。太神奇了!
不得不承认,几年之后当我再访问这个网站时就没那么有趣了。整个网页都被黑客的消息替换了,指出了配置中的安全漏洞。他很宽宏大量,只是在网站上涂涂画画,而不是把它当作传播恶意软件的媒介。
动态网站的结构推动 Web 前行,但也打开了蠕虫的蜜罐。保守估计,当下超过 70% 的 WordPress 源很容易受到已知的漏洞利用(同时 WordPress 驱动着超过 23% 的 Web 站点)仅仅几个月前,一千两百万的 Drupal 站点需要紧急补丁,任何在漏洞通知7小时内没打补丁的站点都该考虑是不是被注入了恶意软件…不到一周,我从社交媒体到站点的超链接就成了“数据库连接错误”。规模化动态网站的成本很高,想要保持站点的活力,动态站点所在的代理不得不千般戒备网络攻击。否则的话就得殊死挣扎让网站重新上线(往往发生在非工作时间)。
我们为跑在服务器上每个请求的复杂代码付了高额费用——要是不必这么复杂,就不用再花一分钱了。

动态网站和缓存

有时,我们尝试用缓存解决问题。没有 WP Super Cache 这类插件的话,那些知名的 WordPress 站点不可能跑起来。大型站点无疑要依赖其上层的代理缓存,比如 Varnish 、 Nginx 和 Apache Traffic Server 。
然而缓存的错误是臭名昭著的,并且即使是相当优化的动态站点通常也会比静态的解决方案慢几倍。
Smashing Magazine 显然是由最关注性能的团队做的,大体上是深层性能优化过的。所以,为这篇文章我做了一个实验。我用 HTTrack 抓了这个网站的一级拷贝,然后把静态版本部署到了 Netlify 上,后者是一个基于内容分发网络(CDN)的静态主机平台。我除了用深度 CDN 整合把静态版本部署到主机上之外,没做任何优化。
Smashing Magazine 比大部分网站都快,但所有请求是一个数据中心承载的。(查看大图)
接着我又跑了几个测试看看第一比特传输时间和主页 index.html 下载完成所用时间。这是 Sucuri’s super-useful performance tool 的结果。
哪怕和高度优化的动态网站相比,静态版本平均要快六倍以上。诚然,不是每个静态主机都有这种差异。但不经过手动配置,这种基于 CDN 缓存的动态网站是做不出来的,至少没有相当变态的缓存神器是不行的。
同样的 HTML,运行在高性能静态主机上(查看大图)
缓存,更确切来说是缓存失效,在动态网站上很难做好,尤其是需要充分利用 CDN 的分发缓存机制。对于一个 WordPress 站点,无法保证同样的 URL 会返回一致的 HTML,这取决于用户登录状态、查询参数、多次 A/B 测试等等。跟踪缓存失效的准确时间是个困难的任务:任何评论、全局站点设置、标签、种类或数据库里其他内容的变动都可能影响到列表里相关文章、索引页、归档、评论计数器等等。
从这个角度来看,静态网站有天壤之别。他们遵循一个十分简单的缓存规则:对于任何访客的 URL 都返回相同的 HTML,直到对应的 URL 有了明确的更新。
在开发时遵循这些规则会有些束手束脚,但如果网站按照这些规则创建,那么在性能、运行时和花销上将产生巨大变化。

现代静态网站生成器

近年来,传统动态架构的替代品逐渐出现。静态站点生成器不是什么新玩意。甚至那时 WordPress 最大的竞争对手 Movable Type,如今都有切换静态网站生成器的选项。
Google Trends 有关”静态站点生成器”(查看大图
那时开始,静态站点不再因那些限制黯然失色。如今的生成器是饱受前端开发者喜爱的、更现代、更具生命力的发布引擎。
每周都有更多的静态站点生成器发布,跟上发展很难。但总的来说,最流行的静态站点都有如下特点:

模版

静态站点生成器的基本思路之一是把网站划分成布局和组件以避免重复。有许多的模版引擎可供选择,它们各有利弊——有些是较无逻辑的、有些将模版和代码混用,但都能让你摆脱重复的头部、尾部和导航。

MarkDown 支持

MarkDown 的兴起很可能是静态站点生成器变得如此流行的主要原因之一。几乎没有人愿意所有内容都用 BBCode 或纯文本来写,然而 MarkDown 很容易上手,用 MarkDown 编辑器来写作、记笔记、发博客貌似快速流行起来。
所有的主流静态生成器都支持 Markdown。有的声称支持 reStructuredText,或一种可替代的标记格式。大体上讲,都允许内容开发者在结构化格式中使用纯文本文档。
这种方法将内容与设计分离,并保持文件的纯文本性。作为开发者,我们开始掌握神奇的工具套件来应付纯文本。相比于把所有内容作为二进制 blob 堆砌在数据库中,这是很大的进步。

元数据

内容往往不会孤立存在。读者总想找到博文的作者、发文日期、文章种类等等。
Jekyll 推动了静态网站生成器的演进:现在可以由 MarkDown 模版驱动
当 Github 拥有者 Tom Preston Werner 编写 Jekyll 作为博客引擎时,他想到了一个代表元数据(主要用于 MarkDown 文档和模版)切实有趣的解决方案——开头描述。
开头描述是少量元数据,主要以 yaml 格式位于文档最前面:
这种标记使包含元数据的单文件文档注解一目了然,也让那些通常在数据库里存储的不透明格式成为了简易可读的文本。

资源管道

如今前端开发几乎总要涉及一些开发工具和编译器。我们想要资源最小化打包,CSS 预处理器从小众走向主流,CoffeeScript 和 ES6 转译使编译器整合进浏览器。
大部分现代静态站点生成器包括一个资源进程,处理资源编译、转换、最小化和打包事宜。有一些基于构建工具,例如 Grunt 、 Gulp 和 Broccoli,你可以紧紧围绕整个生态系统的任务和构建阶段。剩下的更专注于精简其中某个过程,或让某些工具在不经过复杂配置的条件下运作良好。写入文件实时刷新浏览器也成为了许多生成器的标准。

汇总

通常静态站点生成器建站时都有命令行 UI,或者把网站挂在一个本地服务器上用于开发。
拿Jekyll来说,你用 jekyll build 命令时本地文件夹会生成一个 Jekyll 项目源文件,在 _site 子文件夹输出一个静态网站。
下面是源文件夹的样子:
这个文件夹是完备的静态网站,可以传到任何静态主机、跑在任何普通的 Web 服务器上。

为什么现在

如果所有东西听上去很酷,那样它的确很酷。但为什么静态网站技术现在兴起,而早期的生成器未能给 WordPress 的统治带来冲击?有什么变化?我们可以用多久?
如今的生成器和前辈们所处的生态系统完全不同,以前由于许多约束不得不选择动态网站。如今那个基本的在线手册已经过时了,尽管有些还能用。

浏览器成熟了

当 Tim Berners-Lee 发布第一个 www 站点时,浏览器只是简单的文档查看工具,可以显示超链接、超文本。
如今,我们在努力埋葬扯 Web 后腿的最后一个浏览器( IE8 安息)。现代浏览器本身就是一个操作系统,不只是展示从 Web 下载的文档,也可以跑成熟的 Web 应用,对任何的 CORS 兼容的 API 发起外部调用,本地化数据存储,向流媒体服务器打开 WebSockets ,甚至通过 WebRTC 处理其他浏览器的点对点连接。
随着浏览器的成熟,许多之前需要服务器动态代码环境支持的特性可以完全移到客户端。想要站点评论吗?添加 Disquz , Isso 或 Facebook 评论。整合社交功能?把 Twitter 或 Facebook 的 JS 插件加进来。想要你网站有实时数据更新?用 Firebase 。想要搜索?加上 Swiftype。想要支持在线聊天? Olark 就可以。哎呀,你都可以用 Snipcart 给站点加电商。
功能列表越来越多,基于纯浏览器插件的整个生态系统就形成了。除此之外,用 Ember.js 、 Angular.js 或 React 的现代浏览器 app 通常完全作为静态网站部署,由一个纯 API 后端的 CDN 伺服浏览器 UI 和移动端。

CDN 成为主流

当 Akamai 在 1999 年启动第一个内容分发网络时,只有世界上最大的 Web 公司负担得起由 CDN 边缘节点分发web资产的服务。不久前 CDN 也只是 CNN 和 Facebook 规模的公司在用,而不是普通大众。
Akamai 仍然保持企业级报价,而如今任何人都能注册 Amazon AWS,把 CloudFront 放在自己站点前面。并且,小型企业负担得起像 Fastly、 MaxCDN 和 CloudFlare 的 CDN 服务报价。
你可以在动态网站使用 CDN,但缓存失效一直是计算机领域的一个棘手问题。至少,有关边缘节点的缓存和专门用来做请求计算的后端动态系统之间的平衡,是很棘手的。
另一方面,静态站点可以直接部署到 CDN 上,从本地缓存伺服附近终端用户。折腾配置花时间,缓存失效很棘手,但也可以用 Netlify 实现自动化。

性能很重要

移动设备的蓬勃在很多方面改变了 Web 的面貌。越来越多的访客从移动设备进入 Web ,有时是 3G 连接。性能从未像现在这样如此重要。
我们都知道: 57% 的互联网用户放弃加载超过三秒的页面。人们过去愿意等到 10 秒,但如今期待更高。在移动端,不能处理多任务也做不了什么,等网站加载实在是太烦了。超过 4% 的人表示,当用着一个慢悠悠的移动网站时,他们简直要摔手机了。
无论你怎样优化动态网站的性能,或者在这上面投入财力,它都不如精心开发一个静态站点那样保证性能,后者挂在一个月几块钱的 CDN 主机上。随着性能愈发重要,难怪开发者寻找预生成 HTML 的方式,而不是让服务器把生成页面的时间和资源花在每个 HTTP 请求上。
静态网站生成器在开发过程中也消除了很多性能问题。
如果你在建一个数据驱动型动态网站,因为要支撑每一个 HTTP 请求,数据库查询的效率极其重要。即使在你的网站前方有个坚实的缓存层,总要遇到这样的风险,有的请求会成为缓存克星,触发最坏的后端请求,引起整个系统的延时停顿。
而使用静态生成的网站,把内容放到模版上多几秒少几秒无所谓:只有在你发布时才会出现,从不会给终端用户带来性能问题。

构建工具到处都是

编译器和构建工具过去是 C 和 Java 程序员担心的事,不是你建站时用的。现在也不知是好是坏,情况完全变了。
如今,前端开发者采用了构建工具、包管理器和多种编译器混搭。Grunt 是第一个成为趋势的前端构建工具,如今大部分新项目都有构建阶段。
随着构建工具的普及,静态站点生成器融入了前端工具包,而传统动态站点的 php 衍生工具在现代的前端工具流眼中开始不入流。

遗失了什么?

所有这些因素结合到一起,创造出了静态站点生成器的潮流。难怪越来越多的站点开始静态搭建。
但并不都是好事。在静态站点生成器完全成为主流之前,有些东西需要进步。
初次上手静态站点生成器的项目仍然很繁琐,可用工具、文档、资源上有许多的细节和提升空间。
随着静态站点生成器生态系统的发展,离成熟的主题市场相距甚远,对传统动态平台的支持也不够。
然而,最大的困扰在内容编辑方面。在一个文本编辑器里直接用 Markdown 然后发到 Github 上更像是前端开发者的理想工作流,并不是你会拉一个普通、不懂技术的终端用户参与进来的事儿。
因此,许多用静态站点生成器搭起来的的网站整合了动态 CMS。我们急切需要在在内容编辑器和静态网站生成之间搭个桥。在那之前,生成静态站点用于网站还只能是小众。
有一些有趣的”no-CMS “解决方案。 Verge 为 Middleman 用 googlesheets 作为内容层StaticGen 用 Gist 和 Github API 作数据库;Carrot 用 Contentful 作静态 CMS 供非技术人员为它们的静态站点生产内容。
其他人在致力于融合静态站点生成和内容编辑的最佳解决方案,接下来几年在内容和发布方面无疑会有新的工作方式。
像 Contentful、 prismic.io 和 GatherContent 一样的系统将 CMS 层从实际的建站工具解耦,很受多频道内容管理者欢迎。在那里你不是给一个特定的网站写东西,也适用于移动 app、Facebook 页面或白纸。发布新内容触发构建系统一个 Web 钩子;然后静态站点生成器从内容 API 取数据建站,成品直接发到 CDN。
编辑内容另一种方式是利用下面的库:
在静态生成器 Prose.io 上的 MarkDown 编辑器,无缝整合 Github API
prose.io 已经有一阵子了,整合 Github API ,给内容编辑者提供更友好的 UI 在 Github 里编辑 MarkDown 文件。
在 Netlify,我们在做一个开源 CMS ,不限定专门的静态站点生成器、Git 主机或伺服平台。目标是适用于目前所有的静态站点生成器,我们认为这会是对现代静态站点技术的一个突破。
很明显,总会有网站不太适合静态生成——尤其是那些核心内容持续更新的,或者那些一直在推送消息、高度依赖搜索和过滤的。
那也就是说,静态站点生成器会在能力和流行度上继续演进,基础架构和生态系统愈发成熟。随着工具的进步,我们会看到开发者在静态站点技术上的突破。
在 Netlify,我们已经开始看到大型内容驱动站点。它们带有实时搜索、多语言支持和私有板块,由静态站点生成器和内容 API 搭建。静态站点对性能和安全重要性的意识也越来越强,未来充满期待。
from http://blog.jobbole.com/103451/