【ArchSummit架构师峰会】探讨数据与人工智能相互驱动的关系>>> 了解详情
写点什么

Stimulus 1.0: 一个针对你已有的 HTML 的 JavaScript 框架

  • 2018-02-27
  • 本文字数:3480 字

    阅读完需:约 11 分钟

现代JavaScript 并不一定意味着客户端MVC 单页Apps。

Basecamp ,我们写了许多 JavaScript,但是我们并没有用它来创造当代意义上的“JavaScript 应用”。我们的所有应用在核心部分都有服务端渲染的 HTML,然后添加少量 JavaScript 来让页面变得炫酷。

这是一种构建庞大的一体化应用的方式。Basecamp 运行在多个平台上,包括原生移动Apps,只有单独一套使用Ruby on Rails 创建的controllers、views 和models。拥有一套唯一的共享的可以在一个地方更新的接口,是一个小型团队能够支撑多个平台的关键。

这使得我们能够像过去一样凝聚生产力。这可以让我们回到过去那种高生产力的时期,那时一个程序员无需陷入层层间接的或分布式的系统,就可以完成大量任务进度。那时候,还不是每个人都认为,服务端就是给客户端JS 喂JSON 的。

这并不是说,大型JS 应用没有价值。这只是在说,作为一种对很多应用程序都通用的方案,特别是那些像Basecamp 的应用,这是一种简单性和生产力的整体倒退。

而且这也不是说,JavaScript 单页应用的发展没有带来切实的好处。其中最主要的好处是界面从全页刷新中解放出来,变得更快、更流畅。

我们过去也想让Basecamp 变得那样。因此,我们曾跟随大众,用客户端渲染重写了所有东西,或者在移动端采用纯原生的实现。

我们因为这种需求而创建了一种双重方案: Turbolinks Stimulus

Turbolinks 高屋建瓴,Stimulus 贴近细节

在我介绍新的 JavaScript 框架——Stimulus 之前,让我先大致介绍一下 Turbolinks 的细节

Turbolinks 是从一种叫做 pjax 的方案简化而来,托管在 GitHub 上。基本的概念保持相同。全页刷新通常感觉起来慢的主要原因并不是因为浏览器需要处理服务器发送的一堆 HTML。浏览器都非常棒,处理这种事情都非常快。在大多数情况下,HTML 负载比 JSON 负载大,对于页面响应速度也并没有太大的影响(特别是启用 gzip 压缩的情况下)。全页刷新感觉慢的主要原因是 CSS 和 JavaScript 必须重新初始化并重新应用到页面。无论这些文件本身是否被缓存。如果你有相当多数量的 CSS 和 JavaScript,全页刷新就会非常慢。

为了绕过这种重新初始化,Turbolinks 维护了一种持久化过程,就像单页应用做的那样。但很大程度上看不出来。它拦截了链接,然后通过 Ajax 加载新页面。服务器仍然返回完整格式的 HTML 文档。

这种策略可以让大多数应用中的大部分动作感觉起来非常快(如果服务器能在 100-200ms 时间内返回响应,而这可能非常需要使用缓存)。对于 Basecamp,这样使得页面到页面的转换速度加快了 3 倍左右。这使得应用程序感觉起来响应灵敏而流畅,而这也是单页应用最吸引人的部分。

但是 Turbolinks 只是故事的一半。粗粒度的那一半。在全页改变的级别之下,存在一个单页的所有细粒度的行为。包括显示和隐藏元素、将内容复制到粘贴板、在列表中增加一个新的 todo 以及所有其它我们与一个现代 Web 应用发生的交互行为。

在 Stimulus 之前,Basecamp 使用了几种不同风格和模式来实现这些零碎的功能。一些代码只是一撮 jQuery,一些代码也是差不多大小的普通 JavaScript,而一些代码又是比较大型的面向对象的子系统。它们通常使用 data-behavior 属性来避免显式事件处理。

尽管像这样通过新增代码来解决问题非常容易,但这不是一个全面的解决方案,而且我们混杂了太多内部风格和模式。这使得复用代码非常困难,并且这使得新开发者很难学习一种一致的方案。

Stimulus 的三个核心概念

Stimulus 将那些模式中最好的部分糅合到一个适度的小型框架中,只围绕三个主要概念:Controllers、actions 和 targets。

当你查看它所展示的 HTML 时,它看起来是一种渐进的增强。因此,你可以查看一个 template,然后就知道哪些行为发生在它上面。这里是一个例子:

复制代码
<div data-controller="clipboard">
PIN: <input data-target="clipboard.source" type="text" value="1234" readonly>
<button data-action="clipboard#copy">Copy to Clipboard</button>
</div>

你可以看到这些内容,然后对会发生什么事情有一个比较好的概念。即使完全不知道任何关于 Stimulus 的东西或者查看 controller 本身的代码。这很像伪代码。这和阅读一份 HTML 片段,然后这段 HTML 中有一个外链的 JavaScript 文件将事件处理器应用到其中元素的情况有很大不同。这还维护了关注分离,而这点在许多现代 JavaScript 框架中已经遗失了。

正如你所看到的,Stimulus 并不纠结于创建 HTML。相反,它将自身绑定到一个已存在的 HTML 文档上。在大多数情况下,HTML 是在服务器端渲染的,无论是在页面加载的时候(首次点击或者通过 Turbolinks)或者是通过一个 Ajax 请求改变 DOM 的时候。

Stimulus 关注的是对这种已有的 HTML 进行操作。有时这意味着增加一个 CSS class 来隐藏一个元素,或者使它有动画效果,或者让它高亮显示。有时这意味着在组里对元素重新布置。有时这意味着操作一个元素的内容,例如我们将 UTC 时间转变成可以显示的当地时间。

有一些场景下,你会想要 Stimulus 创建新的 DOM 元素,那么你完全可以随意那么做。将来,我们甚至会增加一些语法糖来让创建 DOM 元素这件事更简单。但是,这只是比较罕见的应用场景。重点是操纵元素,而不是创建元素。

Stimulus 和主流 JavaScript 框架相比有哪些不同

重点是操纵元素,而不是创建元素。这一点让 Stimulus 和大部分现代 JavaScript 框架有很大不同。几乎所有的现代 JavaScript 框架都聚焦于通过某种形式的模板语言将 JSON 转变成 DOM 元素。许多人使用这些框架来创建一个空的页面,然后毫无例外地使用那些通过 JSON- 到 - 模板的渲染方式产生的元素来填充这个空页面。

Stimulus 在状态管理问题上也有很大不同。大部分框架有通过 JavaScript 对象保持状态的方法,然后基于保持的状态渲染 HTML。Stimulus 正好相反。状态保存在 HTML 中,因此 controllers 可以在页面改变时丢弃,但是当缓存的 HTML 再出现的时候又可以重新初始化为原来的样子。

这是一种非常不同的模式。一种我确定许多已经习惯了用现代框架工作的经验丰富的 JavaScript 开发者会嘲笑的模式。随便吧,嘲笑就嘲笑吧。如果你享受复杂框架,例如 React + Redux 的复杂性和维护它们所需要投入的努力,那么你可能不会对 Turbolinks+Stimulus 感兴趣。

相反,如果你对正在使用的这些现代技术所带来的强烈复杂性和应用程序分离性感到非常不满,那么你应该会在我们的方案中找到解决之道。

Stimulus 及相关的想法提炼于他山之石

在 Basecamp,我们已经在多个不同版本的 Basecamp 和其它应用程序中使用这种架构很多年了。GitHub 使用了一种类似的方案,起到了非常好的效果。关于“现代”Web 应用程序看起来应该是什么样子,这不仅是相对于主流理解的另一种合理可选方案,还是一种非常有吸引力的方案。

事实上,这感觉和我们在 Basecamp 开发 Ruby on Rails 时非常相似。同一种秘方,同一种味道。感觉现代主流方案有一些不必要的复杂性,而我们可以用更少的投入更快地完成更多的事情。

另外,你甚至不一定非要进行选择。Stimulus 和 Turbolinks 和其它比较重的方案可以很好的结合。如果你的应用 80% 都不需要那么复杂的架构,可以考虑使用我们的方案。然后在剩余的部分使用那些复杂的框架,从而可以真正地从中受益。

在 Basecamp,我们一直都在场景需要的时候使用一些比较重的方案。我们的日历采用客户端渲染。我们的编辑器采用 Trix,一款完全生成的文本处理器,完全不用作为一组 Stimulus controllers。

这组框架旨在尽可能避免过于复杂的处理。使大部分处理保持请求 - 响应模式,大部分交互使用简单的模型就可以生效。然后在特别复杂的场景下使用那些代价昂贵的工具。

总之,如果你的团队规模较小,但又想要和那些使用比较费力的主流方案的较大团队竞争,那么这是一个比较适合的工具箱。

试试吧

Stimulus 是我在为期两周的深入研究过去一年中我采用的 JavaScript 的当前状态后想到的。我深挖了我们的 Basecamp 3 代码库中的模式,提取出一个原型,然后使用最新的最伟大的 JavaScript 技术来实现它。这个深入研究最初产生了针对 Rails 的 Webpacker ,而如果没有 Sam Stephenson Javan Makhmali 的杰出工作,就不会有这个框架。他们根据我粗糙的 Stimulus 原型,用 TypeScript 进行了重写。正如他们重写 Turbolinks 5 时一样。这是一段美丽的代码

关于作者

DHH是 Ruby on Rails 的创作者、Basecamp(原名 37signals)的创始人兼 CTO、纽约时报畅销书《REWORK and REMOTE》的作者以及勒芒级别获奖赛车手。

查看英文原文: Stimulus 1.0: A modest JavaScript framework for the HTML you already have

感谢徐川对本文的审校。

2018-02-27 17:162215

评论

发布
暂无评论
发现更多内容

数字藏品系统开发,NFT数字藏品开发说明

开源直播系统源码

软件开发 NFT 数字藏品 数字藏品软件开发 数字藏品系统

主流定时任务解决方案全横评

阿里巴巴中间件

阿里云 云原生 定时任务

Java编程之语法结构

魏铁锤

数据赋能智慧重庆,巴适得很!

浪潮云

云计算

视频会议,WebRTC及RingCentral解决之道

RingCentral铃盛

WebRTC 视频会议 企业号九月金秋榜

【计算讲谈社】第十一讲|商用车智能驾驶商业化实践:“科技+保险”模式探索

大咖说

智能驾驶 商用车

百余位顶级投资人齐聚无锡,DEMO CHINA创新中国峰会即将揭幕

创业邦

重拾面向对象软件设计

阿里巴巴中间件

阿里云 技术 中间件 技术代码

基于预训练模型的金融事件分析及应用

澜舟孟子开源社区

人工智能 自然语言处理 金融科技 大规模预训练模型

【8.26-9.2】写作社区精彩技术博文回顾

InfoQ写作社区官方

优质创作周报

Nacos 企业版如何提升读写性能和可观测性

阿里巴巴中间件

阿里云 微服务 云原生 中间件 可观测

盘点:专业OKR管理工具有哪些?

PingCode

06_Linux基础-NGINX和浏览器、网页的关系-云服务器ssh登陆-安装NGINX-上传网页-压缩命令-xz-gzip-bzip2-zip-tar-配置NGINX服务器支持下载功能-备份脚本

mycpen

Linux

设计模式的艺术 第二十一章备忘录设计模式练习(设计一款RPG网游,为了给玩家提供更多方便,在游戏过程中可以设置一个恢复点,用于保存当前的游戏场景。如果在后续游戏过程中玩家角色“不幸牺牲”,可以返回到先前保存的场景,从所设恢复点开始重新游戏)

代廉洁

设计模式的艺术

极狐GitLab Helm Chart 已上线,玩转云原生极狐GitLab!

极狐GitLab

DevOps gitlab 云原生 Helm Kubernetes, 云原生, eBPF

预训练模型在金融 NLP场景下的应用

澜舟孟子开源社区

人工智能 自然语言处理 大规模预训练模型

​孟子轻量化技术迈上新台阶:登顶 ZeroCLUE 和 FewCLUE 榜单,已开源并提供 SDK

澜舟孟子开源社区

人工智能 自然语言处理 后端 大规模预训练模型

超越所有人的成就,牛顿的光芒也无法掩盖的天才数学巨人

图灵教育

数学 微积分 数学家

当你的老板站在你背后,看你处理故障......

嘉为蓝鲸

运维 IT 故障 上班

三面阿里,offer到手定级P7,过程很艰辛结果很满意

程序知音

程序员 阿里 java面试 后端技术 Java八股文

图文实录|多模态自然语言处理最新进展

澜舟孟子开源社区

人工智能 自然语言处理 算法 后端

阿里云对边缘计算的探索和实践

阿里云视频云

边缘计算

超越所有人的成就,牛顿的光芒也无法掩盖的天才数学巨人

图灵社区

数学 微积分 数学家

了解数字机器人最新发展动向,不要错过华为数字机器人秋季发布会​

王吉伟频道

RPA 机器人流程自动化 智慧政务 机器人开发 华为数字机器人

到底什么样的数字化才是企业需要的?用2个数字化案例告诉你

优秀

数字化转型

MobPush 安卓推送消息数据解析推荐实现

MobTech袤博科技

android 移动推送

05_Linux基础-NGINX编译安装^判断是否启动^修改端口^启动停止重启^相关路径^中文乱码-Windows、Linux文件传输

mycpen

Linux

测评:腾讯Coding平台好不好用?

PingCode

看了深入Java虚拟机:JVMG1GC的算法与实现文档,我悟了

程序知音

Java JVM 垃圾回收 java架构 后端技术

落地好OKR的8大关键步骤及常用辅助工具

PingCode

OKR

卡塔尔世界杯足球赛dapp系统智能合约开发

开发微hkkf5566

Stimulus 1.0:一个针对你已有的HTML的JavaScript框架_JavaScript_DHH_InfoQ精选文章