今年是ECUGCon的第11个年头。之前基本上讲了服务器的开发实践。从去年开始,我开始讲前端,不讲后端。当然我没说去年为什么关注前端。今天在讲Go语言在前端的应用之前,先简单说一下思路,今天为什么关注前端。前端演进最早的PC时期,常见的设备主要是台式机和笔记本。这两类设备是PC时代的主流设备,使用的主流操作系统有Mac、Linux、Windows三种。前两者的市场份额很小,Windows基本一统天下。早期浏览器主要是IE因为Windows的流行,但是今天Chrome的市场占有率非常高。除此之外,还有大家比较熟悉的Safari和Firefox。以苹果公司发布iPhone为标志,我们进入了移动时代。这个时期的设备主要是手机和平板,以手机为主。操作系统基本都是Android和iOS,WindowsMobile的比例很小。浏览器不是Chrome那样的桌面浏览器,而是从微信小程序开始的移动时代的浏览器。中国的小程序种类繁多,包括支付宝小程序、今日头条小程序等。我认为这真的是移动浏览器大战的开始。奇怪的是,为什么手机浏览器的大战不是在美国打响,而是在中国打响,这也很有意思。小程序相关的技术,不管是谷歌还是其他公司,也在琢磨,当然也可能是我孤陋寡闻,没看到国外有手机浏览器出现的迹象。为什么说Chrome不是手机浏览器,是因为操作手感很不一样。微信小程序是一个尝试,让BS结构的应用感觉和Native应用一样,是一个很重要的尝试。我也幻想过未来。在移动时代,设备还是比较少的。笔记本电脑、手机和平板电脑是最主流的设备。台式电脑在今天已经不是很常见了,但是笔记本却经常被大家使用。ECUG始于2007年,大约在苹果发布iPhone的时候。当时我就做出一个判断,未来是强大的服务器,终端多元化,其实就是前端。但是今天,在我看来,前端多元化还没有真正出现。在ECUG的第11个年头,可以看到这种多元化的趋势越来越现实,包括手机之后的下一个前端战场,在我看来就是汽车。汽车很热。当然,设备会更多,很多人会认为下一个就是所谓的物联网时代。这样一个抽象的名词我们不用多说,但是我们也可以预见,前端未来的趋势会非常多元化。这种多样化与PC时代和移动时代有很大的不同,因为屏幕的大小是前端交互中非常关键的因素。除了汽车,今天的手表也挺多的,只是普及率可能不如手机和平板。手表是一种非常特别的东西。在这么小的屏幕上,玩前端其实是非常吃力的。未来的操作系统会是什么样子?今天仍然未知。前端的演进与设备的演进息息相关。因此,前端的演进是跌宕起伏的,这与服务器端有很大的不同。服务器端的开发非常稳定。操作系统主要是基于Unix的,今天依然如此,没有太大的变化。但是,由于前端的终端变化,操作系统的演进非常剧烈。云计算的演进云计算的演进可以分为三个阶段:第一阶段,典型代表是亚马逊的EC2,我称之为机器计算阶段。整个体系结构构建在虚拟机(VM)上。虚拟机和物理机没有区别。现在你不能接触虚拟机,但是在操作虚拟机的手感上,它和物理机并没有太大的区别。由于容器的兴起,我们今天看到了许多差异。从2014年到今天,典型的标志就是Kubernetes统一了容器操作系统的世界。在此基础上,我们可以看到云计算已经进化到了第二阶段。容器计算时期的计算不同于机器计算时期。容器会越来越重视运维的自动化和相关的基础支撑。最终目的是让服务器基本趋于免运维。以后做业务的时候基本上不用太在意服务器端了。这也会带来另一个问题,下一阶段云计算将何去何从?我认为应用计算。因为随着容器技术的发展,云越来越标配,云计算的下一阶段应该更加面向业务,越来越多地与业务结合,不再只关注基础设施,而是关注应用程序本身的业务架构。在应用业务架构中,端占了非常大的一个组成部分。云计算和端是分不开的。云+端的演进趋势在我看来,云计算会让后端的技术栈越来越规范。后端的大部分技术问题都可以标准化解决。每个公司都有基础设施部门,云计算就是把技术架构部门从公司内部搬到外部。这种正常化是自然发生的。正因为如此,业务的困难和挑战将越来越多地转移到前端。服务器端没有太大的挑战。从服务器端支持业务的角度来看,挑战越来越少。但是,从服务器系统的角度来看,重点可能会越来越集中在业务运营系统的标准化,也就是BI(商业智能)方面。但是这件事的标准化比前端更难。今天为什么要讲前端呢?目前我们还在努力推进后端技术的标准化,但是我觉得这个事情会在可以预料的几年内得到解决,我们肯定会把精力花在前端上进一步的未来。很多人都知道七牛云与Go语言的关系非常密切。我自己在2012年就做出了一个比较狂妄的预测,认为Go语言一定会进入语言排行榜的前列。我设定的时间是10年左右。从2012年到现在,已经快进入第7个年头了。Go是一种非常专注的语言。使用Go的人基本都专注于后端开发,而且倾向于在后端API层面进行开发,Web的比例比较小。Go的专注,使得它今天基本占据了整个云计算领域。在众多云计算公司的技术栈中,Go的占比会越来越高。这种专注也让Go语言成为了今年前十名排行榜的里程碑。Go语言的演进和专注于后端开发并不能使Go成为第一。原因很简单。后端开发之后,尤其是云计算,后端技术越来越规范,Go语言会越来越没用,因为很多问题的复杂性,都是云计算公司解决的。大多数公司只是做自己的事情,不需要关心服务器端的高并发、高可用等复杂性。服务器端的挑战会随着云计算的冲击而减弱。这样一来,Go语言今天所处的位置,如果是一家公司,就应该有危机感,突围下一个战场。在我看来,它肯定会进入前端,也会让Go语言变得更通用,领域会越来越广泛。这样的变化可以让Go真正意义上的语言排行榜名列前茅。为什么Go语言适合做前端?前端需求大前端是开发人员最多、需求最大的工种。对语言的要求一定是入门门槛比较低,精神负担最少。而这个非常适合围棋。2011年我刚推出Go的时候,大部分人对Go不太了解,但是今天Go语言的受众非常广泛,大家有一个很大的共识就是Go语言的入门门槛很低,精神负担很重比较小。基本的程序写好了,编译好了,大概率不会出问题。这样的特性使得它非常适合做前端。前端需要更工程化的语言。前端业务量非常大,因此前端代码量远大于后端。前端负责跟用户打交道,跟人打交道的东西是最复杂的,也是最容易变的。这个知识今天可能比较好,明天可能会换一种新的知识,特别是我前面说的最后的变化。从PC、笔记本到手机,屏幕尺寸不同,过去以键盘为交互主体,变成触摸屏,再到未来的手表或汽车。为什么很多公司重视语音交互,因为语音交互对于汽车、手表这样的设备来说是更好的手段。但这些都存在很大的不确定性。前端变化非常大,交互手感,为了让用户舒服爽爽,程序员将不得不付出很多努力。前端的代码量一定是最大的。前端非常需要一种工程化能力强的语言。今天我们看到前端的代码量肯定是JavaScript,但是JavaScript几乎没有工程支持。之所以叫Script,是因为它小,类似于微信小程序。大家仔细想想,小程序一定不小。这么大的东西,或者说代码量比较大的应用,需要比较强的工程语言。JavaScript之所以流行,是因为它的“垄断地位”。一个趋势已经出现,但今天不是特别强烈,就是越来越多的语言会进入前端,而Go只是其中之一。这是需求决定的,我也觉得Go是最有前途的之一。我在ECUGCon上讲了为什么要讲前端。今天说的可能对你影响不大,因为Go作为前端还是很初级的,但我希望ECUGCon是一个前瞻性趋势探索的大会。我不认为它必须非常实用。它今天不用跟你讲,明天工程上就会用到。我不这样定义它。我希望ECUG本身是一种看到未来的社区。Go在前端的进展回顾Go在前端的进展,GopherJS是真正产生影响的进展。在GopherJS之前,有很多人在做前端相关的事情。Google的人还推出了一个框架,叫做GXUI,今天已经不再维护了。很多人会尝试做一个跨平台的框架,但其实最有前途的跨平台框架一定是浏览器。因为浏览器是跨平台的框架。在我看来,像QT,包括Google的GXUI,都是比较有限的。但是GopherJS,我觉得是真正站在前端的一次尝试。他就是在做我刚才说的,让Go语言的程序员可以写前端。怎么写?它做了一个将Go代码翻译成JavaScript代码的编译器,Go自然就可以写前端了。它是一种以JavaScript为前端的机器语言,因为JavaScript的位置是绕不过去的。但这并不一定是不可能的。今天的前端机器语言肯定是JavaScript,但是我们也看到了另外一个东西,叫做WebAssembly,顾名思义,它把自己看成是Web的汇编语言。但实际上,这个WebAssembly是二进制的。我认为它是Web的汇编语言,而不是Web的机器语言。WebAssembly的覆盖面比大家想象的要广,如今所有主流浏览器都支持它。JavaScript的“垄断地位”发生了一些变化,不会一直这样垄断下去。你可能也听说过Go已经支持WebAssembly,而且是内置的语言支持,这对Go来说也很重要。Go在前端的进步,第二大里程碑是Go内置了对WebAssembly的支持(https://github.com/golang/go/wiki/WebAssembly)。从Go的1.11版本开始。这是Go官方对WebAssemblyGo支持的介绍。编译过程是定义GOOS环境变量为js,架构选择wasm,这样就可以编译wasm文件,而不是本地可执行程序。这里有一些DEMO,是社区里一些人用Go编写的WebAssembly示例。DEMO示例展示:https://stdiopt.github.io/gowasm-experiments/https://justinclift.github.io/wasmGraph1/https://stdiopt.github.io/gowasm-experiments/splashy/这样就展示了效果是由后面的源代码实现的。看似没什么,但这种支持是非常关键的。Go从语言一开始就支持Web前端的发展。虽然今天还是体验版,但也是一个非常重要的里程碑。做这件事的人和之前做GopherJS的人是同一个人。有一群人试图将Go推向前台。前两个如果关注Go语言应该更多人知道,但是下一个一般人不知道。有一个新东西叫做TinyGo,在嵌入式设备上运行Go,它是Go的定制版本(https://github.com/aykevl/tinygo)。因为Go主要是做服务端开发的,所以大家并不关心Go编译出的可执行文件有多大,但是留心一下就会知道很大。TinyGo试图使编译后的文件足够小,因为嵌入式设备的磁盘空间和内存非常宝贵。它其实支持WebAssembly,可以做web开发,虽然砍掉了很多Go的特性。不知道后面是怎么演化的,因为这个项目还是很新的,还不到一年。对于新的东西,我们只能去关注,并没有办法在任何项目中真正使用到。Go2D游戏开发引擎(https://github.com/hajimehoshi/ebiten),其实3D已经出现,今天不上市。这个游戏引擎是日本人做的,已经被用来开发多款手机游戏。它是一种已经商业化的发动机。支持的平台非常广泛。使用该游戏引擎制作的游戏可以支持Windows、Mac、Linux、FreeBSD等PC操作系统,也可以支持Android、iOS等移动操作系统,也支持GopherJS、WebAssembly等Web开发。它是生产级引擎。在我去年演示的DEMO中,我用Go写了一个少儿编程语言Scratch的解析器。这个解析器是用这个2D游戏开发引擎制作的。接下来比较有意思的是Go的前端代码托管(https://github.com/dave/jsgo)。JavaScript有很多公共的前端代码托管,这里来介绍一下Go前端代码托管。丢在这里就可以直接上云了。这似乎是小众市场,但确实有人在做这些事情。还有一些DEMO:这是一款益智游戏。https://jsgo.io/hajimehoshi/ebiten/examples/2048这是俄罗斯方块。https://jsgo.io/hajimehoshi/ebiten/examples/blocks这是一个游戏。您之前看到的版本是一只鸟,而不是土拨鼠。https://jsgo.io/hajimehoshi/ebiten/examples/flappy这是一个待办事项列表Web应用程序。添加它只是为了表明Go也可以进行标准的前端开发。https://jsgo.io/dave/todomvcJsgo.io同时支持GopherJS和WebAssembly。我们刚才看到的游戏不是一个js文件,而是很多个。在源码中,Go会导入一些Go标准库,比如字符串转换库strconv。字符串转换Go标准库会直接编译成一个单独的js文件。这种方式的好处是稍微慢一点,但是后面的加载会很快(因为基本不用改)。一个大型的前端应用通过这种方式拆解后,从长远来看会加载得更快。它支持子模块加载,我们不需要为子模块加载做任何努力。Go的引用会变成模块引用,对应js也是模块。这个编程会很酷。在前端JavaScript语言中,这种模块化编程是语言不支持的。Jsgo.io对WebAssembly的支持还不够完善。不像刚才的GopherJS,目前还不能被package引用,编译出来的是一个很大的wasm文件。但这只是暂时的状态,因为对这方面的支持才刚刚开始。之前说过,很多人都在尝试使用Go的万能卡平台的gui库,但是都失败了。这不是因为Go,而是因为像QT这样的跨平台解决方案本身并没有成为趋势。最有前途的跨平台解决方案是基于HTML5和小程序的浏览器技术,它们是真正的生产级跨平台解决方案。尤其是随着小程序的出现,今天我们看到很多跨平台的库,比如React做的应用,还是有些死板,但是微信小程序却试图让Web体验和Native保持一致。Go的前端开发前景Go的跨平台游戏引擎基本接近量产级,是一个很重要的突破口。在我看来,围棋在前端的突破必须从游戏领域开始。对于围棋来说意味着历史性的0比1的突破。如果没有商业公司使用,这东西就是玩具。但围棋的游戏引擎不会是玩具,因为越来越多的商业公司会使用它。可能不是这个游戏引擎,也许有人会做出更好的,但这是一个可靠的方向。对于Go来说,就像Kubernetes的流行代表Docker,Go接管了云。Go在前端还需要一个杀手级的特性,那就是游戏引擎。
