简介:我相信小型网站在美学上很引人注目,但对于帮助我们抵制向大型科技公司的灵魂出售也很重要。在本文中,我提出了对“小型网络”以及为其提供动力的小型软件和体系结构的愿景。此外,还有关于微服务的大声疾呼。
大约15年前,我读了舒马赫(E. F. Schumacher)的《小就是美丽》,尽管对经济学不感兴趣,但我对它的信息感到震惊。也许甚至更多,我喜欢这本书标题的简洁诗意-它与我的节俭养育和我自己的审美观共鸣。
我认为该是该书的第一版了,该书的内容是有关Web开发的一章:“小型Web十分美丽:对Web开发的研究就像人们在乎的事情一样”。除非有人写,否则这篇文章将是必须要做的。
这有两个方面:第一,小型团队和公司。在这里,我不会谈论太多,但是Basecamp和其他许多人都有。在本文中,我将重点介绍小型网站和架构。
我不是第一个谈论“小型网络”的人,但是有点令人惊讶的是,只有少数人使用该术语进行了讨论。这是我可以找到的主要网页:
通过Parimal Satyal重新发现小型网络:一篇神话般的文章,与“商业网络”相比,有关小型,独立(有时是复古)网站的乐趣。
小型网络是什么?小型技术基金会的阿拉尔·巴尔卡(Aral Balka)撰写的文章:更多的是反对大技术监视的宣言,而不是具体的东西,但仍然很有趣。
在这个拥有大量RAM的快速计算机时代,为什么要瞄准小目标? 有多种原因,但对我而言最重要的原因是: 活动部件更少。 创建更强大的系统并在出现问题时修复问题变得更加容易。 小型软件速度更快。 下载和阻塞计算机内存的位数更少。 降低功耗。 这对于“拯救地球”规模非常重要,但对于增加手机和笔记本电脑的电池寿命的局域规模而言,这一点也很重要。 轻巧,节俭的美学。 我知道这是个人的,但正如您所看到的,我并不孤单。 因此,让我们开始吧。我想涵盖一堆不同的角度,每个角度都有自己的副标题。 如果我们要谈论小型网络,则需要从小型软件开始。
十几岁的时候,我学会了使用x86汇编语言和Forth编程–也许是奇怪的选择,但是我父亲非常喜欢Forth,并且我喜欢这种语言是如此简单,以至于我可以编写自己的自举式编译器。
在职业方面,我是从嵌入式程序员开始的-并不是在“嵌入式Linux”中,而是在16KB RAM足够大的微控制器中。我目前的笔记本电脑有16GB的RAM,按照今天的标准,这还不算什么。我们正在构建RAM数量达到百万分之一的IP网络产品。这些微控制器的价格与芯片(芯片)一样便宜,并且仍广泛用于小型电子设备,传感器,物联网产品等。
您必须考虑每个字节,在启用大小优化的情况下进行编译,并重新使用缓冲区。这与现代Web开发完全不同,在现代Web开发中,JavaScript应用程序将其“向下”编译为1MB捆绑软件,或者单个Python对象标头为16字节,甚至还没有任何数据,或者Go hello-world二进制文件为2MB。甚至在您添加任何真实代码之前。
您如何创建小程序?我认为最主要的是您必须关心大小,而我们大多数人都认为我们没有时间这样做。除了嵌入式开发之外,还有一个完整的编程亚文化叫做demoscene,它对此很在意。他们为最小的4KB演示竞争,他们可以将最多的图形文件打包到4096字节的可执行文件中。它比许多网站图标还小! (Elevated和cdak是收视率最高的4K演示中的两个。)许多演示者后来都成为游戏开发人员。
这不仅与可执行文件的大小有关……在开发下一个命令行工具时,如果您使用Go或Rust甚至C语言,与Python或Java等效语言相比,您的程序将更快,更小并且使用更少的内存。而且更容易安装。如果您不明白为什么,请务必学习。 (本文不讨论此内容,但总结一下:Go,Rust和C可以编译为可以立即执行的机器代码,不带虚拟机,也没有整数等对象的内存开销。 )
但是,为什么不将某些相同的原理应用于Web开发呢?在网络世界中,我认为主要技巧是要小心包含的依赖项以及它们引入的依赖项。总之,请知道node_modules –甚至更好的是,不要使用node_modules。有关此的更多信息,请参见下文。
帕斯卡(Pascal)名望的尼克劳斯·沃斯(Niklaus Wirth)在1995年撰写了一篇著名的论文,名为《精益软件的辩护》 [PDF]。他的观点是:“造成复杂性的主要原因是软件供应商不加批判地采用了用户想要的几乎任何功能”,并且“当通过功能的数量来衡量系统的功能时,数量比质量变得更为重要”。他继续描述Oberon,这是一种计算机语言(从多种方面使我联想到Go)和一种他认为有助于解决复杂性问题的操作系统。绝对值得一读!
我已经思考了很多年了-早在2008年,我就对Adobe Reader的肿程度发了讽刺的讽刺:谢谢Adobe Reader 9!即使在2008年,它的下载量为33MB,需要220MB硬盘空间(现在为150MB下载,我不知道它需要多少硬盘空间,因为这些天我没有安装它)。
但是,我们不仅要抱怨,还应如何实际解决这个问题?具体而言,我认为我们需要开始以下工作:
关心大小:这听起来很明显,但是只有当人们认为重要时,事情才会改变。
衡量:可执行文件的大小和程序的内存使用情况。您可能希望随着时间的推移进行度量,如果度量在发行版中增长超过x%,则可能会成为阻塞问题。或者,您可以每隔一段时间举行一次减少内存的冲刺。
语言:选择可能的后端语言,例如Rust,C或C ++,或者对于服务器,选择Go。这些语言并非适用于所有内容(例如数据转换脚本),但它们可生成小的可执行文件,并且对CLI和桌面应用程序非常有用。
删除:减少功能集。旨在获得少量高质量的功能。我的汽车不能飞翔或漂浮,没关系–它开得很好。
对新功能说不:除非它们真的符合您的理念,否则在您的项目生命周期中增加的费用不菲。
依赖关系:了解引入的每个依赖关系的大小和复杂性。如果可以,请仅使用内置库。
我很高兴有越来越多的人对小型网站感兴趣。
几个月前,《黑客新闻》上发布了一系列有关各种“俱乐部”的文章,您可以在以下网站上发布您的小型网站:1MB俱乐部(评论),512KB俱乐部(评论),250KB俱乐部(评论),甚至10KB俱乐部( 评论)。我认为这些是重新显示出对极简主义兴趣的有趣指示,但我会说原始大小还不够-没有真实内容的2KB网站不够好,而包含512KB非常慢的JavaScript的页面比一个快照站点,其中包含4MB精心挑选的图像。
黑客新闻:我个人喜欢极简主义,近乎野蛮主义的设计,但我更喜欢它的轻巧性。我刚刚下载了主页,并且加载的所有资源仅传输21KB(未压缩的61KB)。即使具有巨大注释线程的页面也只能传输约100KB的压缩数据,并且加载速度很快。相比之下,Reddit变得如此肿。黑客新闻,永不改变!
Lobste.rs:一个类似的新闻投票网站,其样式略为“现代”。它使用了一些JavaScript和个人资料图标,但仍然干净快捷,首页的总传输大小仅为102KB。您只是不需要兆字节就可以创建一个不错的网站。
Sourcehut:我喜欢Drew DeVault的业务背后的概念,但是我喜欢这个网站的规模和反绒毛程度。他建立了一个名为Software Forge Performance Index的微型站点,该站点跟踪著名源代码网站的大小和浏览器性能-Sourcehut无疑是最轻便,最快的。甚至他的主页也只有81KB,包括几个屏幕截图缩略图。
SQLite:SQLite不仅是一个小型的,功能强大的SQL数据库引擎,而且网站小巧且内容丰富。甚至他们有关测试的7000字页面也只有70KB。他们怎么做到的?这不是魔术:专注于高质量的文本内容,最少的CSS,没有JavaScript和很少的图像(一个小的徽标和一些SVG)。
LWN:我有点偏见,因为我为他们写过文章,但是它们是Linux和编程新闻的绝佳网站。高质量的技术内容(对作者来说是很高的标准)。它们绝对是利基市场,拥有“我们专注于高质量的内容,而不是每年更新CSS”的外观–他们已经发布了23年的丰富内容!他们的主页仅下载44KB(未压缩的90KB)。
丹·卢(Dan Luu)的博客:这是更为严格的例子之一。他的内联CSS仅约200字节(页面基本上没有样式),并且他的HTML源代码不使用任何换行符。有点有趣,尽管后来他继续加载20KB的Google Analytics(分析)JavaScript…
正如一位朋友指出的那样,这些网站具有“反美学的美感”。我承认一点也不介意,但另一方面,小不一定意味着丑陋。越来越多的个人博客和网站采用了小型网络方法,但在印刷上更具吸引力:
还有很多很多。程序员Sijmen Mulder创建了一个不错的纯文本网站列表-虽然与小型网站不尽相同,但肯定是重叠的!
但是,这不仅涉及原始大小,还涉及“小的精神”。它关心您网站的用户:您的页面下载速度快,易于阅读,具有有趣的内容,并且不会为Google或Facebook的跟踪器加载JavaScript的内容。从头开始构建网站并不是每个人的功劳,但对于我们当中做的那些人来说,也许我们可以推广模板和工具,使它们产生小的站点来鼓励质量而不是数量。
对于这个网站,我喜欢手工制作HTML和CSS的每个字节,就像赶时髦的人制作精酿啤酒一样。不过,认真地说,如果您关注的重点是好的内容,那么仅用几行HTML和CSS即可从头开始创建一个简单的模板并不难。它既小又快,它将成为您的。
加载本文将传输大约23KB(未压缩的56KB),包括收藏夹图标和分析脚本。它体积小,速度快,并且在台式机或移动设备上可读。我认为外观并不算太糟糕,但我的主要目标是针对内容进行简约设计。
除了确保HTML和CSS较小以外,请确保正确压缩图像。这里有两个基本要点:不要直接从相机上传超高分辨率图像,而是对照片使用合理的JPEG压缩量(对屏幕截图或矢量图片使用PNG)。即使对于大图像,通常也可以使用75%或80%的压缩率,而图像仍然没有JPEG噪点。例如,我的副业首页顶部的1920x775大图片只有300KB。
说到英雄图片,您不需要在博客文章顶部添加无关紧要的大图片。它们只会使您的页面重量增加数百KB(甚至兆字节),而无法提供价值。而且,请不要用动画GIF来散布您的文章:如果屏幕上有动画,那么我几乎无法集中精力阅读文字-而且我不是唯一的一位。包括相关的非库存图像,这些图像提供的值等于其权重(以字节为单位)。裸露的文字也可以,就像杂志上的文章一样。
尽管IndieWeb.org使用的是“独立”而不是“小”一词,但IndieWeb.org在这里是一个很好的资源。这个运动看起来比小型技术基金会(甚至被批评为“数字绿色清洗”)更有机,而且他们的Wiki具有更多的真实内容。 IndieWeb还推广本地的Homebrew网站俱乐部和IndieWebCamp聚会。
JavaScript是Web的好运,而对于小型网站却常常是祸根:它增加了下载大小和时间,可能成为性能杀手,对可访问性不利,并且如果您使用不正确的话,对搜索引擎不利。另外,如果您的网站内容繁重,则可能不会增加太多。
不要误会我的意思:JavaScript有时是不可避免的,并且在很棒的地方也很棒。如果您要开发基于浏览器的应用程序(例如Gmail或Google Maps),则几乎可以肯定使用JavaScript。但是对于您的下一个博客,手册网站或项目文档网站,请考虑使用纯HTML和CSS。
如果您的网站(如许多网站)介于两者之间并且包含少量交互,请考虑仅将JavaScript用于需要它的页面部分。无需使用React和Redux来对整个网站进行大修,只需添加表单即可。让服务器生成HTML仍然是创建快速网站的有效方法。
堆栈溢出就是一个很好的例子。从第一天开始,他们就通过在服务器上呈现其页面以及测量和减少呈现时间来使性能成为一项功能。我敢肯定,自从Jeff Atwood时代以来,Stack Overflow代码已经发生了很大的变化-现在,它为广告目的提出了很多额外的请求-但内容仍然可以快速加载。
黑客新闻(又是该网站)是服务器端的经典之作。仅使用一个很小的JavaScript文件进行投票,其余的就由服务器上生成的HTML来完成。而且显然它仍然可以在一台机器上运行。
大约十五年前,有一个伟大的想法叫做渐进增强。这个想法是向所有人提供可用的HTML内容,但是启用JavaScript或快速互联网连接的用户将获得具有更简化的用户界面的增强版本。实际上,Hacker News本身使用了渐进增强功能:即使在2021年,您仍然可以关闭JavaScript并使用投票按钮。这有点笨拙,因为现在需要重新加载页面才能进行投票,但是效果很好。
在2021年,渐进式增强仍然有意义吗?可以说不是,尽管一些顽固分子仍然关闭了JavaScript,或者至少仅对他们信任的网站启用了JavaScript。但是,我认为最重要的是心态:它表明开发人员在乎性能,规模和替代用户。如果没有JavaScript,Hacker News投票就无法奏效,我认为这不会是一个大问题-但是,这表明它确实起到了某种书呆子的作用。另外,他们拥有的JavaScript只有2KB(未压缩的5KB)。
将其与Reddit主页加载的8MB(未压缩的14MB)进行比较。在201个请求中,这不是我在骗你! –其中大多数是JavaScript,可为所有广告和跟踪提供支持。迷人的…
当然,您不需要“框架”来开发这种方式,但是有些工具可以使这种服务器端开发风格更加容易。来自Basecamp的人们的Turbolinks还是一个早期的技术,现在已被Turbo取代,Turbo显然已用于为其电子邮件服务提供支持。我还没有亲自使用这些工具,但是它们的想法很聪明(而且令人惊讶地是老套):使用标准链接和表单提交,提供纯HTML格式,但可以使用WebSockets和JavaScript加快速度。实际上,直到今天,有人在Hacker News上发表了一篇新文章,声称“网络软件的未来是HTML-over-WebSockets”。如果“嘿”有什么要走的,那么此技术非常快捷!
另一方面,有时候,如果您仍然需要整个页面,可以通过使用JavaScript来降低整体复杂性。例如,我的婚礼注册表网站上的注册表页面是在客户端上呈现的(它们实际上使用Elm,可编译为JavaScript)。我确实需要JavaScript的交互性(它不仅仅是内容,而且是“单页应用程序”),但是我不需要这些页面的服务器端呈现或良好的SEO。主页是服务器渲染的简单模板,但是注册表页面是完全由客户端渲染的。
最近,另一种新的兴趣是静态网站(以前称为“网站”)。您将一些静态HTML(以及CSS和JavaScript)上传到静态文件服务器,仅此而已。
对此进行改进的是,有许多可用的“静态站点生成器”。这些工具可通过简单的模板生成静态网站,因此您无需手动将网站的页眉和页脚复制到每个HTML文件中。添加文章或进行更改时,请运行脚本以重新生成。如果您托管的是简单网站,博客甚至新闻网站,那么这是一个不错的选择。毕竟,它的内容不是交互式应用程序。
我之所以在此站点上使用GitHub Pages,是因为它是支持SSL的免费主机,并且每当您进行更改时便使用Jekyll静态站点生成器自动构建您的站点。我有一个标准的标头,可以轻松地在所有页面上包含相同的CSS,尽管您可以根据需要具有多个模板或“布局”。因为大多数人只在我的网站上查看一两篇文章,所以我将CSS内联。使用HTTP / 2并没有太大的区别,但是Lighthouse用内嵌CSS显示约200毫秒,使用外部CSS显示约300毫秒。
这是一个简单的Jekyll页面外观的示例(实际上是本文的开头):
---布局:默认标题:"小网页很漂亮"永久链接:/ writings / the-small-web-is-beautiful /描述:“小型网络”,小型软件以及... --- Markdown文本的构想。
我还使用了雨果(Hugo),这是一种用Go语言编写的非常快速的静态网站生成器-它可以在几秒钟内甚至生成具有数千个页面的大型网站。并且还有许多其他选项可用。
没有任何事情像第三方依赖项那样会炸毁您的软件(或JavaScript捆绑包)。我总是很难找到一个Web项目的node_modules目录-只是其中的大量内容让我感到难过。
不同的语言似乎具有不同的“依赖文化”。当然,JavaScript以“如果可以成为一个库,应该成为一个库”的姿态而臭名昭著,这导致左撇子灾难以及诸如3行isarray之类的其他小型库。还有像Moment.js这样的大文件包,即使压缩后也要占用160KB的空间。如果您不需要所有语言环境,可以通过多种方法将其缩小,但这不是默认设置,因此大多数人都不需要(您最好选择更具模块化的方法,例如date-fns)。
现在,Go借助最近的模块工具具有良好的依赖关系管理,但是它还具有“尽可能使用标准库”的文化。拉斯·考克斯(Russ Cox)撰写了一篇出色的文章,论述了不谨慎处理依赖项的缺点:我们的软件依赖关系问题。 Go的共同创造者Rob Pike甚至把这句话作为Go的谚语之一:“复制多于依赖。”您现在可能已经猜到了,但是我喜欢这种极简主义的方法:除了减少故障点的数量之外,它还使程序更小。
Python,Ruby,Java和C#似乎介于两者之间:人们使用了大量的依赖项,但据我所知,需要更多的注意,并且它不会像node_modules那样失控。诚然,这有点不公平,因为Python(和其他语言)具有比JavaScript多的标准库。
YouMightNotNeedjQuery.com网站显示了您认为可能需要使用库的许多任务,实际上,使用纯JavaScript可以很简单地完成这些任务。例如,在我的一个项目中,我使用类似以下的函数来使用简单的旧XMLHttpRequest发出API请求:
函数postJson(url,data,callback){var xhr = new XMLHttpRequest
......