首先感受下效果:

项目地址https://github.com/dongweiming/weapp-zhihulive

限于公众号文章篇幅的限制,只能将具体的小程序代码实战和我的经验放在下篇了。今天我先介绍下我对小程序的一些理解以及用尽量少的篇幅介绍小程序背后的技术的发展历程。

我对小程序的看法

我一向不喜欢跟风。小程序刚出的时候一大波人吹捧,一个月后一大堆人看衰,全然忘记曾经的话,其实脸被打的是啪啪啪。

引用我点过赞的一个对于小程序发布一个月的表现如何的 大司马大将军 的回答:

互联网时代,人们更加没有耐心 —— 没耐心到以至于 30 天时间,就有人开始对小程序 “盖棺定论” 了。这真是一件让人悲哀的不知道该说啥的事。

具体的回答内容限于篇幅就不展开了。

当我真正的用它开发,实践了产品需求。我对它持观察态度:

  1. 生态太过封闭。微信想的是用户不断的进行「手机开机 —> 微信 —> (社交 + 购物 + 吃饭 + 金融...) —> 手机关机」的循环,但是别的公司想的是「微信 —> 小程序 —> 获得粉丝 —> 引流或者引导用户下载 APP 感受完整版」,大家各怀鬼胎,但是谁都不蠢。
  2. 相关限制太多(分享按钮、诱导分享)。
  3. 入口不好找。

期待小程序的下一步。

页面设计思路

术业有专攻,我有个缺点,就是设计页面会懵... 如果没有设计图让我凭空去想我很痛苦,比如这个小程序,我一开始是按着知乎 APP 的配色和 Live 相关内容的布局做的,但是越到后来越发现效果我不喜欢。现在的主色、发现页、话题页是抄袭了https://github.com/romoo/weapp-demo-breadtrip的感觉,加上了一些我的理解。其他的页面是我自己对 Live 产品的理解做的。

小程序完成的功能

我之前在我的知乎 Live 以及回答的一些问题中都提到过,一定要找个机会写一个相对复杂的项目深入你要学习的技术,只看文章、书、视频效果其实是很差的,只有实践了才真的能记住和理解。

那对我来说,这个小程序就是学习效果的产出,这也是我平时学习东西的方式。在一开始的时候我就基于对知乎 Live 的理解,给自己列出了小程序要完成的功能:

  1. 发现页。用户一登录就看到的页面,展示了一些基于我的理解的算法排序的 Live。
  2. 7/30 天最受欢迎的 Live。知乎也有,但是我对它那个顺序不太满意:小众的 Live 太难上榜,评分低但是收入高的 Live 排的靠前。在豆瓣,要是国产电影 3-4 分但是由于票房很高就排得很高,你们想想我们会被怎么骂。
  3. 热门话题页面 / 话题筛选。我开始有这个小程序的想法的时候,知乎还不能基于分类去筛选 Live,不方便。
  4. 搜索。当时还没有搜索,现在的搜索也比较鸡肋吧,就是个简单的关键词匹配,都不能模糊查询(比如搜索 pythno 就找不到符合的 Live)。
  5. 个人页面,社交必备元素了,包含个人信息以及其主讲的 Live 列表。
  6. 基于多种条件对主讲人排序。

我以前说过,我不反对造轮子,关键是造的得有意义。就是你要造的东西能解决你的痛点,比如我这个就是由于知乎提供的功能不满足我的需求(比如当时想找个某关键词的相关 Live,只能用「site:zhihu.com live python」这样的方式 Google),以及它提供的排序价值观我不太认同。作为工程师最大的好处(其实是会写爬虫的工程师),不满意我就写一个。不过这个小程序只能平静的躺在本来开发环境里面。

要不然造轮子,造着造着容易弃坑

基于上面说的需求,我不断的更新这个专题直到今天(昨天的 MVVM 都是给今天做铺垫)。

组件化思想

关于「组件化」网上有很多写的很不错的文章,推荐大家去看看。我特别喜欢美团点评团队的博客中提到的下面这句话:

Controlling complexity is the essence of computer programming.

随着前端开发复杂度的日益提升,组件化开发应运而生,并随着 React 等优秀框架的出现遍地开花。大家都在各种尝试努力的「Controlling complexity」。

我试着介绍下组件化发展的历史(去掉一些已经夭折、不看好的部分,只保留相关的主流)。

我们先讨论什么是组件?其实我们日常开发(尤其是前端开发)接触到的 component、widget、module、plugin 就是组件,缺点是大家实现不统一,使用方式也不统一。到了 2011 年,Alex Russell 提出了「Web Component」:

  1. Custom Element: 自定义 HTML 元素
  2. shadow DOM: 封装
  3. HTML Imports: 打包一切
  4. HTML Template: Lazy 的 DOM 模板

JavaScript 本来是一门作为浏览器上的脚本语言出身,并不适合于大规模开发。同年 Google 提出的 MDV(Model-Driven Views)框架,提出了我们也需要像对待后端系统一样对前端逻辑进行统一管理、分层 (表现逻辑、viewmodel、视图)。所以 Backbone、AngularJS、Ember 之类的数据绑定框架横空出世了,力求给我们带来代码的模块管理、数据、视图的分离,他们以他们不同的方式解决共同的问题:

1. 如何更好地模块化开发 2. 业务数据如何组织 3. 界面和业务数据,业务逻辑的分离

与此同时为了用户体验的要求,HTML5 和 ECMAScript 也在快速的推进。2013 年,Google 推出了新的 UI 框架 Polymer,它的实现使用了 WebComponent 标准,并且 Polymer 可保证针对包含各种平台的 Web Component 规范本地实现的浏览器、库和组件的使用效果完全相同。它代表了下一代的 web 组件方向:一切皆组件、尽量减少代码量、尽量减少框架限制。

同年,React 并没有采用 Web Components 的方案,以高性能虚拟 Dom 为切入点,在 Facebook 的造势下,社区得到了大力发展。官方说 React 倾向于做传统 MVC 架构中的 View 层。不同于 AngularJS,所以用起来很自由(可以在大项目中的一个小组件上使用)。

我在工作中多次用到 React。其实一开始有种颠覆前端开发的感觉,熟悉后感觉却觉得这种方式非常舒服。

说了这么多,什么是组件化呢?

我还是引用张云龙老师的理解(BTW,他的博客真得好好看看呢,最后的参考资料有):

  1. 页面上的每个 独立的 可视 / 可交互区域视为一个组件;
  2. 每个组件对应一个工程目录,组件所需的各种资源都在这个目录下 就近维护
  3. 由于组件具有独立性,因此组件与组件之间可以 自由组合
  4. 页面只不过是组件的容器,负责组合组件形成功能完整的界面
  5. 当不需要某个组件,或者想要替换组件时, 可以整个目录删除 / 替换

RN/Weex/ 小程序

随着移动设备类型的变多,操作系统的变多,用户需求的增加,对于每个项目启动前,大家都会考虑到的成本,团队成员,技术成熟度,时间,项目需求等一堆的因素。因此,开发 App 的方案已经变得越来越多了。曾经有一段 HTML5 的小浪潮,无数的人参与或者看到过一个讨论:原生(Native App)开发还是混合(Hybrid App)开发?原生开发显然是最可靠的方案。但是学习成本,人才成本,开发效率以及照顾不同平台的特性去考虑,都成为了开发人员心目中的一道坎。

混合开发的直白的解释是 Native 和 Web 技术都要用,兼具「Native App 良好用户交互体验的优势」和「Web App 跨平台开发的优势」。促使开发者在移动开发中使用 Web 技术主要动力在于,相比于 Native 技术,Web 技术具有诸多优势:

  1. HTML,CSS,JavaScript 的组合被证明在用户界面开发方面具有很高的效率。
  2. 统一的浏览器内核标准,使得 Web 技术具有跨平台特性。iOS 和 Android 可以使用一套代码。
  3. 可越过发布渠道自主更新应用。

豆瓣为此也有了一些混合开发实践,有兴趣的可以看最后的文章。

早期的混合开发有一些缺点:

  1. 受限于 Webview(手机中内置的浏览器控件)的性能限制,相比原生而言有不少损耗,体验无法和原生相比
  2. 不适用于交互性较强的 app

RN (React Native) 是 Facebook 在 React.js Conf 2015 上推出的一个框架,结合了 Web 应用和 Native 应用的优势,可以使用 JavaScript 来开发 iOS 和 Android 原生应用。在 JavaScript 中用 React 抽象操作系统原生的 UI 组件,代替 DOM 元素来渲染等。它给我的感觉是不同于 HTML5,也不同于原生,更像是用 JS 写出原生应用。它的优点很多:

  1. 虽然说开发成本大于 Hybrid 模式,但是小于原生模式,大部分代码可复用
  2. 性能体验高于 Hybrid, 不逊色于原生
  3. 开发人员单一技术栈,一次学习,跨平台开发
  4. 社区繁荣,遇到问题容易解决

那一天,我发了个 QQ 状态:感觉 JS 要一统江湖了。

Vue(view 的法语)于 2014 年 2 月对外发布,它采用 MVVM 数据绑定,有着简洁的 API,是一个用于构建 Web 界面的库。我们可以用 Vue 扩展出来的 ViewModel 子类当做可复用的组件。这在概念上与 Web Components 非常相似,但是带了数据绑定、动画系统等上层功能。Vue 和 Polymer 在功能上和 API 上比较相似,不同之处在于 Vue 的组件无需 (IE9+) 任何 polyfill(描述复制缺少的 API 和 API 功能的行为,可以使用它编写单独应用的代码而不用担心其他浏览器原生是不是支持)。

2016 年 6 月,阿里无线前端开源了无线电商动态化解决方案 Weex,特点是轻量级,性能很高,官方给出的口号是 “Write Once Run Everywhere”。由于这个轮子太像 Vue + React-Native(可以称为 Vue-Native),后来 Vue 作者尤雨溪加盟 Weex 项目担任技术顾问... 😝 。

2016 年 9 月开始内测的微信小程序提供了模块化、模板、数据绑定等特性,极大的方便了使用惯了 MVVM 框架的开发者。在了解微信小程序后,能感受到其实又是一个 RN 的轮子。开发者在自己的微信中通过小程序的开发者工具,撰写出 Native 级别的界面,通过开发者工具生成压缩包,提交到微信公众平台,然后在微信 app 中请求执行,便可实现原生 Native 的界面体验。微信之父张小龙在他的朋友圈里写道微信小程序是不需要下载安装的应用,实现「触手可及」,「用完即走」的理念。但除了把腾讯的一些访问优化技术放进来,基本没有技术上的创新和突破。

只不过,他们三者有点区别:

  1. RN 偏向整体业务的实现
  2. Weex 偏向单个页面的数据交互
  3. 小程序的 UI 使用了 Native(体验要求比较高的组件,比如 Tab)+ Webview

要不要学小程序

除了微信,不会有小程序时代的赢家,先别想着逆袭,除非微信能比较好的平衡这一点。作为非前端开发,我个人倒是建议 Python 的 Web 开发通过小程序来提高「切图」甚至设计能力。因为微信提供了 JSSDK,包含了满足绝大部分功能需求的事件 / 组件。那你可以放心的直接写 HTML 和 CSS,而不用自己绑定 Javascript 事件,另外是如果之前没接触过,可以了解到前端使用 Javascript 和后端是用什么样的方式通信的。

然后是前端的组件开发的方式在后端的某些层面也是可借鉴的,虽然 MVVM 在 Web 后端没有存在的必要(比如数据双向绑定对后端无意义还增加个服务器和网络请求的负担)。

最后一点是,通过学习可以了解到一种新的设计理念、甚至编程范式。工程师要提高眼界,当你遇到的场景足够复杂,思考足够深入,造的轮子足够多,在未来才可能找到痛点,实现基于更先进的开发理念做出革新的框架或者工具,所以不必那么现实和功力。

参考资料

漫谈 Web 前端的『组件化』 前端组件化开发实践 Web 组件化 - angularjs 实践 2015 前端组件化框架之路 前端工程 —— 基础篇 Hybrid App 开发实战 豆瓣混合开发实践 Hybrid APP 基础篇 (二)->Native、Hybrid、React Native、Web App 方案的分析比较