探索

无需安装的应用时代

作者: makemind · 2026年1月8日
本文有实证版。 同一主题已用能跑的代码和真实渲染的画面重做 — 只有画面这一层会化 — 无需安装的应用,以及编译冻住的东西。这篇保持写成时的原样。

改一个按钮颜色需要什么

假设你修好了一个功能。改了按钮颜色,捉了个错字,修正了一行错误的计算逻辑。代码改动量不过五行左右。工作本身十分钟就能完成。

可是想一想,这十分钟的修改,在抵达用户屏幕之前会发生什么。

先构建。把整个应用重新编译。然后打包、签名。上传到商店。等待审核——运气好一天,通常两三天。被驳回就读理由,改好再提交。审核通过,开始分发。而到这里还没完。相当一部分用户会在一段时间里继续用旧版本。 关掉了自动更新的人,等着连Wi-Fi的人,把更新提示随手关掉的人。你修好的那个错字,快则几天慢则几周,缓缓地抵达用户。

改一个按钮颜色,就需要这整套流程。而几十年来我们一直把它当作理所当然的成本接受下来。无论是移动应用还是桌面程序,在「我修好了」和「用户看到修好了」之间,总隔着这条长长的锁链。

掌中的屏幕——我们每天握着、用着的应用,其背后总隔着一条长长的锁链
掌中的屏幕——我们每天握着、用着的应用,其背后总隔着一条长长的锁链

这篇文章谈的是:这条锁链为何存在,我们是怎么被困在其中的,以及它从来都不是必然的。 这会是一篇长文。作为创刊Vol的第一篇,我们想把这本杂志所立足之处讲清楚。

我们是怎么被困进这条锁链的

这条锁链并非一开始就有。让我们简短地追溯一下谱系。若知道今天的憋闷是在何处凝固的,也就清楚了该解开什么。

第一代——打包软件。 把程序装进CD或软盘出售的年代。画面也好逻辑也好,全都安装在用户的电脑里。要改怎么办?压制新版本重新分发,用户得重新安装。更新是一季度一次,运气差则以年计。锁链的原型在这里诞生了——程序的本体在用户的设备里。

第二代——网页。 浏览器改变了一切。画面由服务器送下来,浏览器只负责把它画出来。改了之后呢?下一个访客立刻看到新画面。没有安装,没有更新。这是锁链第一次被斩断的瞬间。我们自由了——只要我们处理的是文档。

第三代——应用商店。 智能手机一登场,潮流又倒了回去。摄像头、GPS、推送通知、加速度传感器、离线运行、流畅的六十帧动画——为了网页给不了的原生能力,我们又回到了安装到设备上的应用。 而这一次又多叠了一层:商店这道关卡,以及审核。锁链比第一代更长了,就这样再次凝固。

这里要看清核心。我们回到应用商店模式,是因为原生的能力,而不是因为想要安装、审核、更新这条锁链。锁链是为了获得能力而不得不附带的成本。然而不知不觉间,我们竟把这成本和能力当成了一捆。「想要原生能力,就得连锁链一并承受。」

这篇文章所追问的,正是这一捆。

能力与锁链,真的不能分开吗?

我们已经尝试过的那些绕行

业界并非只是干等着忍受这条锁链。绕开锁链的尝试不断出现,而看看这些尝试的成功与局限,真正解法的轮廓便浮现出来。

混合应用(WebView)。 在应用的壳子里塞进一个浏览器,画面用网页来画。因为画面能在服务器端改,锁链被斩断了一部分。但代价不小——WebView不如原生流畅,难以触及设备的深层功能,还给人一种「像网页的应用」的不上不下之感。等于是放弃了一部分能力,买来了即时性。

代码推送(热更新)。 不经审核就把JavaScript包推进设备,更新应用逻辑的方式。对紧急修复有用,但本质仍然是往设备里植入代码。得和商店政策拉锯,大的改动最终还得回到正式审核。它没有斩断锁链,只是把它放松了而已。

服务器驱动UI(SDUI)。 大型服务悄悄沿用的方式。画面的构成(放哪些卡片、按什么顺序、用什么数据来显示)由服务器送下来,应用接到这份规格,用原生控件把它画出来。在信息流、主页这类频繁变动的区域大显身手。这是最接近本质的尝试——用原生来画,但画什么由服务器来定。

可是SDUI也有局限。它大多是各家公司只为自家服务打造的封闭系统。只在那家公司那个应用里才能工作的规格,只和那家公司服务器对话的结构。它不是通用标准。所以「我们的信息流画面由服务器定义」做到了,但「向任意服务器、任意设备定义并发送画面与工具」却做不到。

业界走到这里为止。即时性由网页,能力由原生,画面的动态定义由SDUI,各自展示了出来。只是这三者从未融合进同一个开放标准罢了。

应用为何非得「安装」不可——审视结构

现在回到根本的问题。一个因太理所当然而无人追问的问题。应用为何非得安装到用户的设备上不可?

答案,看看应用由什么构成便能得出。应用是两样东西。一样是显示什么(画面、布局、按钮的位置与颜色),另一样是做什么(按下按钮会发生的事,处理数据的规则)。传统的应用把这两样都写成代码植入设备。 画面是代码,动作也是代码。把那团代码编译出来的成品,正是「被安装的应用」。

所以一旦有什么改变——无论画面还是动作——就得把植入设备里的那团代码整团换掉。 没有什么好办法只改一部分。这就是构建—审核—安装—更新这条锁链的根。锁链的存在不是因为懒惰或陈旧的习惯,而是从「应用的本体在设备里」这一结构中必然流出的。

这结构之下铺着一个深层的假设:设备必须聪明。 画面怎么画、按下按钮做什么、接下来显示什么——所有这些判断都得由设备里的代码来下。所以才把那些判断代码全都预先放进设备里。

可是——如果把这个假设翻过来呢?

翻转前提:如果画面由服务器定义

这样设想一下。画面和动作不由设备而由服务器来定义。设备不再自己知道「显示什么」。它转而问服务器——「这个画面现在该画什么?」服务器答道「一个标题,下面一个按钮,按下按钮执行这个动作」,设备便只按那指示去画。

这小小的翻转,就把整条锁链推倒了。

设备里不再有「只属于这个应用的代码」。设备里有的,只是一个无论来什么都能画出来的通用绘制引擎。 画面要变?改服务器的定义。要加新功能?往服务器里添动作。设备没什么可碰的。没有要构建的,没有要送审的,没有要安装或更新的——因为设备里本就没有可改的「应用」。

这和上一节看到的绕行有什么不同?混合应用放弃了原生能力,但这里负责画的一方是真正的原生运行时,所以不放弃能力。代码推送仍然往设备里植代码,但这里设备里根本没有按应用而分的代码。 SDUI是一家公司的封闭系统,而这里所追求的是开放标准——任意服务器,按约定的方式定义画面与工具并发送过来,任意设备的通用运行时便把它画出来。

这「约定的方式」是核心。服务器与设备必须用同一种语言说话。关于什么叫画面、工具如何调用、数据以什么形状往来的共同规约。唯有当这规约不被锁在一家公司之内而是保持开放时,「每一个服务器都能成为应用」才得以成立。(这规约具体长什么样,本杂志的编程与协议连载将一层一层揭开。)

一个场景

听上去会很抽象,所以来描一个场景。

假设服务器里有这样一份定义——「这个画面有一句欢迎语,下面有一个按钮。按下按钮就调用下单工具。」 用户打开应用,设备接到这份定义照样画出。欢迎语和按钮出现了。

现在你在服务器上改那份定义。「改成两个按钮,一个下单,一个取消。颜色用蓝色。」 保存。

下一刻,用户的画面上变成了两个按钮。他们什么都没做。 没点更新,没重新下载应用,没去商店。你没构建,没等审核,没按发布键。你只是改了服务器定义的一行。

十分钟的修改,在十分钟内抵达每一个用户。

开篇所说的那条长长的锁链——这便是它整个消失之处。

自然会浮现的反驳

读到这里的技术者,脑中想必已浮现出若干反驳。若不正面回答这些反驳,这篇文章就只是一纸空洞的宣言。让我们一个一个来。

「服务器定义画面的话,离线不就什么都做不了吗?」 合理的担忧。答案是——画面定义会被缓存。 一旦接收过的定义就保存在设备里,连接断了,最后一个画面照样能工作。只在需要新定义时才去问服务器。和网页用离线缓存做出PWA是同一个原理,只不过是在原生运行时之上。「必须时刻连着网」这种误解,来自每时每刻都调用服务器的错误图景。实际上只在定义改变时才往来。

「每个画面都从服务器接收,不会慢吗?」 画面定义很小。不是沉重的代码包,而是「一个按钮、一个文本」这样轻巧的规格。而且如上所述会被缓存。真正沉重的东西——绘制引擎——早已原生地在设备里了。用户体感到的性能就是原生的。服务器定义的是画什么,而非画这个行为本身

「安全呢?服务器既然下发画面和动作,会不会下发恶意的定义?」 所以运行时不信任收到的定义而是验证它。 一份定义能做的事,被框在运行时设定的边界之内——不是任意代码执行,而只能是预先定义好的控件与工具的组合。这和网页浏览器只在沙箱内执行任意站点的JavaScript是同一个思路。服务器可以说「画这样一个画面」,却不能说「随你的意支配设备里的一切」。

「这不是违反应用商店政策吗?毕竟不经审核就改功能。」 这是个微妙的领域,老实说视情况而定。 商店一直警惕「绕过审核、把应用的核心动作整个改掉」。但「服务器定义内容与画面构成」——这是每一个信息流、每一个电商应用早就在做的事。界线在于是否植入任意原生代码,而不在于画面是否由服务器定义。只要这个模型停留在后者一侧,它就如同既有的SDUI那样处在政策之内。(不过这是对平台政策的一种解读,而非法律或政策咨询。实际应用时应查阅各商店的最新指南。)

「服务器的成本和依赖呢?」 没有白来的东西。下发画面定义的服务器得开着。只是这份负担——鉴于几乎每个应用都已经有后端——与其说是新生出来的,不如说更接近角色变大了。而且后面会谈到,在本杂志所讨论的生态里,那台服务器本身便成了产品。

回答了这些反驳之后,「无需安装的应用」便不再是魔法,而是可由工程来解释的结构。魔法理当受到怀疑,但结构可以被验证。

有什么会改变

前提一变,立于其上的种种也随之而变。这不只是「分发变轻松了」。

修改的成本一旦趋近于0,修改的方式就变了。 在审核要三天、一半用户用着旧版本的世界里,一次分发时总是尽量多塞东西、慎重地发出去。因为一旦出错,要撤回又得三天。可若修改即刻反映、又能即刻撤回,那么小而频繁地改就变得自然了。今天改一个画面试试,反响不好明天就撤回。实验的单位变小了。这不只是便利,而是做产品的节奏本身的改变。

谁能做应用,也变了。 搭建构建环境、管理签名密钥、运营商店账号、熟悉审核规则——所有这些门槛都附着在「做应用」这一行为上。在画面由服务器定义来画的世界里,那门槛的相当一部分消失了。会写定义,画面就出来。这意味着的东西很大。哪怕不是开发专家——只要是熟知自身领域的人——也能做自己的工具。律师做自己的咨询流程,农民做自己的种植记录,工厂工程师做自己的设备控制画面。这本杂志今后将一直展示的故事,正是这个。

而且「应用」这个词的含义会变得模糊。 它不再是安装到设备上的沉重一团,而是由服务器定义、运行时画出的活的画面。 那么,只要服务器一侧有某种能定义工具、数据与画面的东西——它就已经算是应用了。这一思路的尽头,有一个本杂志将反复触及的命题。如果每一个服务器都能成为应用呢? 它的意涵之大,远非这一篇所能装下。今后的连载将把它一个一个解开。

所以,去怀疑

读到这里仍想「可这真做得到吗」——这份怀疑是对的。用文字写出的愿景,要写得多像样都行。把历史串得像样,把反驳答得像样,都做得到。要紧的是它究竟能不能跑起来

所以这本杂志不止步于把愿景铺陈一通。在接下来的文章里,我们会亲手做出来给你看。 从无需安装就推出一个画面开始,再到处理状态、调用服务器的工具,直至工厂的设备、医院的诊疗流程、一个人的专业知识化为应用的过程。一步一步,连着代码,作为真正跑得起来的东西。

这篇文章抛出的所有主张——锁链从来不是必然、能力与锁链可以分开、人人都能做自己的工具——都是要在接下来的连载里以证据来偿还的承诺。

最后留一句。你上次在手机上点「更新应用」是什么时候?那个熟悉的动作——正在开始消失。


makemind.dev 「探索」— 「无需安装的应用」 Vol 的开篇。接下来的《十行代码,第一个画面》,走的是无需构建、无需安装就推出一个画面的最短路径。

Twitter