Sapper:迈向理想的 Web 应用框架

扎稳阵脚,再进一步。
注意:原文发表于2017-12-31,随着框架不断演进,部分内容可能已不适用。
给迫不及待的小伙伴们的快速入门:Sapper 文档 和快速模板 starter template。
如果要列出完美的 Node.js Web 应用框架的特征,你可能会想到这些:
- 它应该支持服务端渲染(SSR),能够快速初始化并加载内容,且对 SEO 友好;
- 应用支持同构为更通用的服务端和客户端的代码,这是当下合情合理的趋势预期;
- 客户端应用支持与服务端渲染的 HTML 混写,绑定事件侦听到现有的元素上,而非重新渲染它们;
- 导航到其他页面快如闪电;
- 离线及其他渐进式 Web 应用特性,务必支持开箱即用;
- 首个展示的页面应该按需仅加载必要的 JavaScript 和 CSS,这意味着框架支持路由级别的自动代码分割,及动态
import(...)以实现更细粒度的手动控制; - 性能毫不妥协;
- 绝佳的开发体验,使用热模块重载及其他辅佐搭配工具;
- 生成的代码应该易于理解和维护;
- 框架应该是浅显易懂的,并且各个方面均可自定义,没有被 webpack 的配置锁死在某个框架中,以及少之又少会“暗藏玄机”;
- 一个小时内就可以将整个框架悉数习得,不论是久经沙场的老手,还是初入门径的新人。
Next.js 就十分接近这个理想值。
如果你与 Next 还素未谋面,我强烈推荐你去看 learnnextjs.com 上面的教程学学。
Next 提出了一个绝妙的想法:你应用中所有的页面都是 your-project/pages 目录下的文件,每个文件都是一个 React 组件。
这是 Next 所有突破性设计的根基。
找到某个页面的代码轻而易举,只需要在文件系统中查看即可,而不用去猜测组件的名称是做什么的。
同时,对于用什么样的项目文件结构这类鸡毛蒜皮争论不休的事情便一去不再了。
而 SSR(服务器端渲染)及代码分割的结合更是从容不迫(不过 React 团队放弃了 Router,对那些尝试 SSR 和代码分割的人说,“祝你好运!”)。
然而但是 —— 虽然 Next 这么美好,恕我出言不逊,Next 仍然美中不足:
- Next 使用“rout masking”的技术来创建更为美观的 URL(譬如
/blog/hello-world替换掉/post?slug=hello-world)。
这破坏了应用程序结构与目录结构一一对应的保证,并迫使你维护这两种形式之间转换的配置。 - 你所有的路由都假定是“页面”。
但通常你需要一些服务端路由,比如 301 重定向,或者专门为页面提供数据的 API endpoint,而 Next 没有兼顾到这一点(注:Next 新版本已经具备 API 路由能力)。
你可以将处理这类情况的逻辑写到server.js中,不过这样会让人感觉与页面声明的方式不太一致。 - 要使用客户端路由,链接不能是标准的
<a>标签。 相反你必须使用框架指定的<Link>组件,譬如在这篇用 markdown 写的博客文章中的使用<Link>是不可能的了。
然而,真正的问题是,所有这些好处都是要付出代价的。
最简单的 Next 应用(仅展示一个“hello world”静态文本的页面),其 JavaScript 使用 gzip 压缩后是 66kb,解压后,它占用 204kb,对于移动端来说这是一个非常庞大的代码量了,但这已是“最低消费”。此时,性能是决定你的用户是否会留下来的关键因素。
这事我们可以做得更好!
编译器即框架的逆袭
Svelte 提出了一个激进的想法:如果你的UI框架压根就不是框架,而是一个编译器呢?如果它把你的组件编译成独立的 JavaScript 模块会怎么样呢?
我们生成高度优化的普通的 JavaScript,而不是使用 React 或者 Vue 这些类库,其实它们对你的应用一无所知,因为框架必须提供一个通用的解决方案。
如果只生成应用所需的代码,便可以完全避免了基于虚拟 DOM 方案的内存和性能开销。
JavaScript 领域正在朝着这种趋势发展。
Stencil 是一个来自 Ionic 团队的深受 Svelte 启发的轻量级框架,它支持编译为 Web Components。
Glimmer 虽说并没有编译为独立的 JavaScript(不深入地讲了,要详尽叙述其优缺点的内容都可以独立成篇),但是团队正在围绕将模板编译为字节码做了一些有趣的研究。
(React 现在也开始加入了这个阵营,尽管他们目前研究的重点是优化 JSX 的代码,这与近年来 Angular、Reactive 和 Vue 所做的预优化其实是异曲同工。)
试想一下,如果我们破旧立新,尝试使用这种新的方式作为新的起点,其结果又将如何?
Sapper 简介
Sapper 或许可以回答这个问题(这个名字源于“工兵”,它也是“Svelte 应用程序制作器”的代名词)。
Sapper 是一个类似 Next.js 的框架,旨在满足前文提及的 11 个理想标准,同时极大减少发送到浏览器的代码量。
它可以与 Express 的中间件兼容,这意味着它很容易理解和定制。
同样的 “hello world” 使用 React 和 Next 需要 204kb,而使用 Sapper,仅有 7kb。
随着我们不断探索其空间优化的可能性,这个数字未来会进一步下降,比如,除了处理客户端路由的微型 Sapper 运行时以外,其余情况压根不会为没有交互的页面发送任何 JavaScript。
有没有一个更真实的示例看看呢?
其实 RealWorld 就提供了这么一个开发中型项目的示例。
展示这个 RealWorld 示例的交互式首页,Sapper 的实现 仅需39.6kb(压缩后 11.8kb)。
整个应用的尺寸是132.7kb(压缩后为 39.9kb),远远小于用来参照的 React/Redux 327kb(85.7kb)的实现,即便 132.7kb 仍然是挺大的,不过关键是,得益于代码分割,它会使人感观上觉得跑起来非常快速。
代码分割当下早已蔚然成风了,不过如果你的应用使用了 React 或者 Vue 等传统的框架,代码分割就有一个“最低消费” —— 框架本身,它可能占据整个应用程序总尺寸的很大一部分。
代码分割也不是免费的 —— 譬如 React 等框架使用了代码分割,它体积会更大。
不过如果使用的是 Svelte,情况就大相径庭。
当然,尺寸大小问题也不过是开发的关注点之一罢了。
Svelte 写的应用同时具有极高的性能和内存利用率,并且它包含了强大的功能,而如果你选择其他某个框架,搭配“小型”或者“简易”的 UI 库的话,那么可能会牺牲掉这些东西。
权衡
对于许多开发者来说,Sapper 最大缺点是什么呢?
“我还是喜欢 React,而且用惯用熟了。” —— 其实会这么觉得,也是无可厚非。
如果你属于上面这个阵营的话,那我建议你至少尝试一下其他框架,很可能你会喜出望外!
Sapper 的 RealWorld 实现,总共才 1,201 行代码,而其他框架需要 2,377 行,因为你可以使用非常简洁、易于表达的模板语法(只需要5分钟就可以上手)。
你还能享受到范围受限的局部CSS,内置了对未使用的样式自动删除和最小化能力,你也可以使用 Less 这样的预处理器。
这样你就不用再依赖 Babel 了。
而 SSR 也是非常地快速,因为它只是字符串拼接而已。
我们最近还加入了 svelte/store,这是一个小型的全局状态管理库,它可以零引入就能在组件层次结构之间同步状态。
就算是最糟糕的情况下,你也会觉得自己的选择是英明的!
尽管如此,我们还是有值得权衡取舍之处。
你比方说,某些人对“模板语言”深恶痛绝,难道你就是其中之一?
JSX 的支持者会说 “它其实就是 JavaScript” 这样的话来刺激刺激你,React 最大的优点就是它这种写法有无限的灵活性。
对于这种灵活性,React 有其自己的一套权衡逻辑,总之一言难尽,我们不在此展开过多讨论。
接着聊聊生态。
特别是 React 周边生态 —— 开发工具、编辑器集成、辅助类库、教程指南、StackOverflow问答数量、框架自身的天坑以及工作机会等等……这些 React 简直天下无敌。
诚然,如果你将“生态系统”视为选型的重要依据的话,说明你已局限在个人技术的天花板了,势必成为你技能上升的桎梏。
但它仍旧是当下普惠开发者最重要的举措。
路线图
我们还不会发布 v1.0.0 版本,因为还有很多变数在里面。不过相信指日可待了,想必届时会有许多令人兴奋的可能性。(注:事实上 v1.0 可能永远都不会发布,作者对技术有了一番新的思考)
我认为Web性能的下一个风口将会是 “全应用程序优化”。
目前 Svelte 的编译器是作用在组件级别,编译器通过理解组件之间的边界,能够生成更有效的代码。
React 团队的 Prepack 研究 也基于类似的想法,Glimmer 团队也在这一块做一些有趣的研究。
Svelte 和 Sapper 可以很好地利用这些想法。
说起 Glimmer,我们可能会在 2018 尝试借鉴他们“将组件编译为字节码”的想法。
试想一下,像 Sapper 这样的框架,可以根据应用的特性来决定使用哪种编译模式,它甚至可以为 JavaScript 的初始路由提供最快的启动时间,然后为后续路由提供延迟的字节码解释器,从而实现启动大小和应用程序总大小的最佳组合。
不过大多数情况下,我们希望 Sapper 的发展方向由用户决定。
如果你乐于助我们一臂之力,并希望协助我们打造 Web 应用的未来,欢迎加入 Github 和 Discord。
< The End >
Sapper:迈向理想的 Web 应用框架的更多相关文章
- 学习ASP.NET Web API框架揭秘之“HTTP方法重写”
最近在看老A的<ASP.NET Web API 框架揭秘>,这本书对于本人现阶段来说还是比较合适的(对于调用已经较为熟悉,用其开发过项目,但未深入理解过很多内容为何可以这样“调用”).看到 ...
- tornado 学习笔记2 Python web主流框架
2.1 Django 官方网址:https://www.djangoproject.com/ 简介:Django is a high-level Python Web framework that e ...
- Spring 4 官方文档学习(十一)Web MVC 框架之配置Spring MVC
内容列表: 启用MVC Java config 或 MVC XML namespace 修改已提供的配置 类型转换和格式化 校验 拦截器 内容协商 View Controllers View Reso ...
- Spring 4 官方文档学习 Web MVC 框架
1.介绍Spring Web MVC 框架 Spring Web MVC 框架是围绕DispatcherServlet设计的,所谓DispatcherServlet就是将请求分发到handler,需要 ...
- Spring 4 官方文档学习(十一)Web MVC 框架
介绍Spring Web MVC 框架 Spring Web MVC的特性 其他MVC实现的可插拔性 DispatcherServlet 在WebApplicationContext中的特殊的bean ...
- 开发大型项目必备 98%公司都在用的十佳 Java Web 应用框架
众所周知,工欲善其事,必先利其器.选择一个好的 Web 应用框架就像一把称手的兵器,可以助大家披荆斩棘. 今天就为大家整理了十佳 Java Web 应用框架,并简单讨论一下它们的优缺点. 第一,大名鼎 ...
- React 还是 Vue: 你应该选择哪一个Web前端框架?
学还是要学的,用的多了,也就有更多的认识了,开发中遇到选择的时候也就简单起来了. 本文作者也做了总结: 如果你喜欢用(或希望能够用)模板搭建应用,请使用Vue 如果你喜欢简单和“能用就行”的东西 ...
- L20n – Mozilla 推出的 Web 本地化框架
L20n是 Mozilla 开发的用于 Web 开发的本地化框架.它允许本地化开发者把逻辑细分为本地化的资源. L20n 的框架不再需要开发人员深入理解自然语言的具体细节,并提供了机会为本地化创造更好 ...
- 【转】谈谈Google Polymer以及Web UI框架的未来
原文转自:http://www.csdn.net/article/2013-05-27/2815450-google-polymer 摘要:开发者Axel Rauschmayer在自己的博客上详解了G ...
随机推荐
- HttpServletResponse的学习
关于Response对象的一些方法和属性可以查看官方文档:https://javaee.github.io/javaee-spec/javadocs/ 比如里面定义了许多常量: 这些都是服务器向浏览器 ...
- hdu 1517 Multiplication Game
题意: 用整数p乘以2到9中的一个数字.斯坦总是从p = 1开始,做乘法,然后奥利乘以这个数,然后斯坦,以此类推.游戏开始前,他们画一个整数1 < n < 4294967295,谁先到达p ...
- Detect the Virus ZOJ - 3430 AC自动机
One day, Nobita found that his computer is extremely slow. After several hours' work, he finally fou ...
- 病毒侵袭持续中 HDU - 3065 AC自动机
小t非常感谢大家帮忙解决了他的上一个问题.然而病毒侵袭持续中.在小t的不懈努力下,他发现了网路中的"万恶之源".这是一个庞大的病毒网站,他有着好多好多的病毒,但是这个网站包含的病毒 ...
- jmespath(2)投影Projections
投影 投影是JMESPath的关键特性之一.它允许您将表达式应用于元素集合.有五种投影: 列表投影 切片投影 对象投影 展平投影 过滤投影 处理投影需要注意的点 投影评估分为两个步骤.左侧(LHS)创 ...
- Shell 函数 & 数组
Shell 函数 函数介绍 # 什么是函数? 具备某一功能的工具 => 函数 事先准备工具的过程 => 函数的定义 遇到应用场景拿来就用 => 函数的调用 # 为何要用函数? 没有引 ...
- Chapter Zero 0.2.3 显示适配器
显示适配器(Video Graphics Array,VGA) 不看后悔!!深入了解显卡!!!走你! 我们常常会调试显示器的分辨率,一般对于图像的显示重点在于分辨率与颜色深度, 每个图像显示的颜色会占 ...
- Http和Https之为什么Https更安全
[除夕了,加油干.希望自己新的一年万事顺意,祝大家身体健康,心想事成!] 我们都知道 HTTPS 安全,可是为什么安全呢? 看小电影还是浏览正常网站,一定要检查是不是 HTTPS 的,因为Https相 ...
- C语言经典面试题
[题目]零值比较--BOOL,int,float,指针变量与零值比较的if语句. (首先给个提示:题目中要求的是零值比较,而非与0进行比较,在C++里"零值"的范围可就大了,可以是 ...
- redis字符串-sds
redis自己实现了一种名为简单动态字符串的抽象类型(simple dynamic string)作为字符串的表示.下面将简单介绍sds的实现原理. 一.sds的结构