- 永远对微信小程序保持尊重——小程序心得体会和开发经验
开篇 我第一次接触小程序时,还清楚的记得是在2017年的春节期间。当我升级最新版的微信后,开始摸索着新的功能变化。在发现页有一个叫小程序的入口,点进去有一列的“应用”。当我打开一个叫“亲戚关系计算器”的小程序后,简单的使用,然后退出,再去寻找其他的小程序,猫眼电影,自选股,滴滴出行…… 当我尝试着去探索更多小程序的过程中,我突然发现,微信正在发展为一个超级的应用流量入口。而微信中的小程序也可以轻松的坐拥10亿的可用用户人群。 那时候过年,我做的唯一一件事情就是细细的读了小程序的开发文档,心想他可以具有多大的活力与动力,能够引发多大的改变。而我能不能适应他,去随着他的发展,带动自己的腾飞。 很遗憾,当时的小程序并不对个人开发者开放,没有办法注册一个小程序,只能在开发者工具上写一些小的应用,去熟悉小程序的开发。 3月27日,小程序重要更新,其中之一就是支持个人开发者注册小程序。那时候的我,在学校上大一,用一个运营公众号的微信号注册了第一个小程序,并做了一些实验性的开发,并上线。 从这个过程中,我开始细细的体会小程序的优势以及不足,小程序适用于那些领域,小程序适合怎么推广。小程序适合那些行业领域的应用。现在看来,其实从小程序提供的能力,就可以依稀端详出小程序所致力的场景与应用领域。 2018年1月,在我历经半年多的思考和衡量下,做出第一款真正属于自己的小程序——GS比赛计分。去尝试探索线上小程序和线下场景的交融,在这过程中有顾虑,有大胆创新,但都为我更深层次理解小程序有很大的帮助。 目前,自己已经做过10余款小程序,除了GS比赛计分开发时间很长,其他的小程序都是一个月左右的时间完工。比如2019年2月的高校课程助手;2019年3月的数据查询助手;2019年4月的数据汇总助手。 我接下来会从小程序的需求分析与应用设计,小程序的开发,小程序的运营3篇来讲述我对于微信小程序的独自见解与经验。希望能为更多的学生开发者有所启发和借鉴。 需求分析与应用设计 要清楚的认识到小程序对自己需求的最大赋能,需要从最初去理解小程序的定位,微信团队对于小程序的定义是这样的: 微信小程序是一种全新的连接用户与服务的方式,它可以在微信内被便捷地获取和传播,同时具有出色的使用体验。 通过对小程序提供能力的分析,不难看出。小程序相对于APP来说,在降低开发门槛的同时能够满足最普遍的应用需求,适合生活服务类线下商铺以及非刚需低频应用领域。使得微信通过小程序作为生态的建立者和维护者,赋能商家和应用者。以一种生态触角的状态来迅速的捕捉最大化生态红利。 当清楚的理解小程序的定位后,那么就需要合理的筛选需求并进行应用的功能设计。我将会使用【GS比赛计分】作为例子进行分析说明。 1.用实质的问题引出明确需求,并确定解决问题的功能边界 首先思考的是,自己需要做的功能都有哪些,使用人群是谁?使用场景是什么?需要数据的实时性吗? 一开始设计【GS比赛计分】的时候,目的是为了解决现在的中小型比赛使用人工计分的失效性差,出错率高,人工和时间成本昂贵的问题。程序的目的是将比赛计分的相关人员用互联网工具联系起来,以提升计分效率。 [图片] 当明晰了产品目标后,开始考虑使用人群。一般来看,大多数的比赛计分都是由两种角色构成的,一个是评委(分数确定者),另一个是工作人员(分数汇总者)。 传统的计分过程是通过现场工作人员将评委的分数以纸质的形式送达计分人员。在这一过程中就有大量的成本浪费了(一个是人力成本,另一个是时间成本)。另外,计分人员以Excel或计算器和笔记的形式进行比分汇总,在这一过程中又存在大量的成本浪费(人力成本和时间成本甚至还有错误风险)。 [图片] 所以横观所有的主观评分的线下比赛,无一例外都存在比赛结束后有长时间的节目或视频热场环节,其实这都是在为人工计分的缓慢争取时间。 所以,【GS比赛计分】的使用人群和使用场景就确定下来了,与传统人工计分的过程类似,只不过需要互联网赋能,解决时间和人力成本。需要数据的实时交互。 【GS比赛计分】作为解决现象问题的工具,首先需要做的就是不要违背现象中事件的发生次序。所以功能完全参照比赛计分过程来设计。具体功能如下,提交成绩,撤回成绩,弃权处理,实时的选手分数,实时的选手名次,清楚评委数据,解绑评委,重启比赛,结束比赛,比赛内置会话。 2.对程序平台进行横向比对,明确小程序的优势和劣势 当程序的功能确定好后,不要着急着手界面设计,功能模块的组合,交互设计这些过程。当你在进行这些过程之前,需要认真的去考虑你的应用是不是适合在小程序上开发。 小程序的火爆,注定有许多人盲目的进入这一领域,但不是所有的应用都适合小程序的推广模式,也不是所有应用都能吃得起小程序的运行效率的。所以在确定开发小程序之前,正确的认识的合适与不合适,避免让自己的成本白白的付出。 如何确定适不适合用小程序来做呢?我们可以让小程序作为一个互联网平台,把应用带入到互联网的每一个平台中去,进行横向的对比,去找出各自的优点与不足,当做出客观的判断后,应用在小程序上相比于其他平台有没有优势就很明显了。 还是以【GS比赛计分】举例。我所横向对比平台包括PC、原生APP、Web平台、轻应用、小程序。首先从满足功能来说,比赛计分需要很稳定的实时性,所以我将Web平台排除(因为复杂的比赛环境,不同的设备浏览器难免会有问题)。 然后将剩下的平台做分析。PC平台使用可能性太小(原因:比赛现场成本太高昂,租借笔记本可能都不是现实的);原生APP不适合(原因:评委评分前需要下载APP,比赛结束后没什么用了,需要把这个APP卸载。而且IOS和安卓两大平台增加了研发成本);轻应用有阻碍(原因:百度轻应用由于装机量小,覆盖人群不多。支付宝小程序没有社交关系链,无法有效的推送给需要的人。产业联盟轻应用,苹果用户怎么考虑?) [图片] 经过一系列的对比,很明显。对于【GS比赛计分】来讲,微信小程序是最好的应用平台。同时微信小程序仍然可以和不同的平台进行联系,所以可扩展性,功能延展性都是最佳的。 3.应用设计要满足即用即走的理念 当确定小程序是最理想的应用平台时,我们需要对小程序进行便利化的设计。这就需要抛弃一部分原生应用开发或Web开发的一些设计理念。追求“极致、简约”的风格设计。 在【GS比赛计分】的详细设计时,我考虑到,以个人账户的形式去下发比赛的流程是行不通的,既然服务于比赛,那么就以比赛为最基本的账户组成单元,明确一个比赛ID。而同一个比赛的不同角色,以不同的IK进行区别,而角色的设置包含在比赛设计中,由比赛创建者在创建比赛时自行创建。 那么小程序的使用场景就出来了。以比赛现场的告知或者微信聊天的分享,告知比赛参与角色其ID和IK,就可以让角色快速的进入绑定角色并使用程序。免去注册的一系列烦恼。 同时在微信用户面前,这个账户体系是平权的,任何用户在得知ID和IK的情况下都可以进入(账户绑定情况下不可以进入),一定程度上免除密码和忘记密码,注销账户这一系列的麻烦。 当完成比赛后,程序已经完成了自己所有的任务时,使用者可以直接退出程序,不需要注销比赛等操作。真正做到即走。 在使用过程中,要清楚的考虑用户的使用过程,从而做一些保险机制。微信小程序运行在微信上,微信是社交工具,就免不了用户会退出小程序甚至微信去做一些其他的事情。所以【GS比赛计分】在设计时要保证用户回来要用到自己想要的,在程序设计中有中间状态界面能够保证用户可以迅速进入使用状态。 4.对于很大的系统,要把最适合小程序部分拿出来,而不是全部 现在的【GS比赛计分】其实是一个大的生态系统,结合有线下的网络接口,展示接口,线上小程序,web平台。每一个部分都承载着自己独特的应用价值。 比如Web平台就承载比赛管理的任务,创建比赛,上传比赛文件,选手图片,设置选手(名称、介绍、手机号、图片、出场顺序),设置评分项(名称、权值、预置分数),设置评委(名称、权值,IK)。从实际的分析来看,比赛管理最适合在PC端进行,不管是文件还是图片,公认都是PC上传比较容易。 在最初设计的时候,我错误的把系统分成了多个小程序进行系统搭建,在实际使用过程中造成了重大的缺陷和用户流失。最大的表现是,我开发了【GS比赛创建】小程序,作为比赛的入口程序。从而造成比赛数量增速缓慢,大的使用场景无法突破,老用户意见上升等一系列问题。不得不注销了【GS比赛创建】小程序,并进行很大的架构调整。【GS比赛计分】暂停使用,造成大量的用户流失。 [图片] 所以,当设计多场景,前后联动性很强的应用时,需要将功能进行使用划分,每一个划分需要找最适合的平台。最适合小程序的部分,就做好与其他平台的无缝结合。 5.小程序的应用场景和机会 目前来看,小程序的应用场景主要包括支付场景,比如扫码支付、快消餐饮、移动购物、交通出行等等,工具类小程序能更碎片化、垂直化地满足细分的应用场景需求。 根据微信的最近更新变化来看,公众号和小程序的协同作用将越发明显,公众号的作用也将进一步放大,因此未来发展的机会可能在这几方面。 内容营销,小程序能通过更完善更精准的服务进而提高用户黏性。具体来看包括各大知识付费的小程序以及在教育风口上的小程序。当然,这些小程序也可同时开发APP(按微信对小程序的开发步骤来看)从而实现用户沉淀。 具有支付场景的各类商家。包括传统的已有一定客户群的商家提供更方便的服务或者实现线上线下联动以及新零售。 工具类小程序。包括共享经济领域,这类小程序即用即走,轻量化,便捷化。 天生具有社交属性的小程序。比如抽奖、互赠礼品、拼团减价、社交性的小游戏以及帮拿快递等。 小程序的开发经验 1. 微信小程序开发文档是最好的学习文档 很多同学喜欢看视频教程,或者买一本小程序开发书来学习。觉得这么学会加深理解更加容易上手,而官方文档干巴巴不好学。现在的微信小程序能力更新速度很快,当一个教程或书出来的时候,其实已经过时了。建议同学去微信公开课中学习微信小程序的入门教程,开发入门后,根据自己的开发需要,自行阅读官方文档来学习。 [图片] 2. 必须了解小程序的运行原理 微信小程序是运行在微信中的,所以运行速度并不能和原生媲美。但是在开发小程序的过程中,可以用良好的编程思路来追求程序的高效运行水平。但前提是,你需要对小程序的运行环境有所理解,需要知道在开发环境和真实环境(IOS和Android)下的运行差别。大部分的开发坑都是因为不同运行环境造成的。 官方的声明:微信小程序运行在三端:iOS、Android 和 用于调试的开发者工具;在 iOS 上,小程序的 javascript代码是运行在JavaScriptCore中;在Android上,小程序的javascript代码是通过 X5 内核来解析;在开发工具上,小程序的javascript代码是运行在nwjs(chrome内核)中。 微信小程序的运行环境类似 ReactNative ,而不是纯 Html5。两者最大的不同在于,ReactNative 的界面是由原生控件渲染出来的,而 Html5 的界面是由浏览器内核渲染出来的。两者在性能上有较大的差异,从而表现出来微信小程序要比h5页面好很多。 3.安利小程序云开发 云开发为开发者提供完整的云端支持,弱化后端和运维概念,无需搭建服务器,使用平台提供的 API 进行核心业务开发,即可实现快速上线和迭代,同时这一能力,同开发者已经使用的云服务相互兼容,并不互斥。目前提供三大基础能力支持: 云函数:在云端运行的代码,微信私有协议天然鉴权,开发者只需编写自身业务逻辑代码 数据库:一个既可在小程序前端操作,也能在云函数中读写的 JSON 数据库 存储:在小程序前端直接上传/下载云端文件,在云开发控制台可视化管理 云开发使得小程序开发门槛进一步降低,甚至偏前端的开发人员也可以独立开发小程序了。另外,云开发中云函数支持去请求第三方服务接口。所以云开发最大程度上提供了小程序所需基本API的构建,另外可以通过第三方服务请求能力扩展API能力。 [图片] 而且云开发的数据库和存储完全可以与云函数构建一个小型的后端平台。并发能力中等,适合大部分的小程序业务API的构建。 4. 养成良好的小程序代码习惯 微信小程序的代码文件分为4种,WXML、WXSS、JS、JSON。 JSON文件是小程序的配置文件,APP.JSON是小程序全局配置,另外每个页面也会有配置文件。建议页面中的JSON文件只填写页面需要配置的(比如页面标题),而不变化的不要写到里面(比如标题风格,背景颜色等等)。 JS主要是javascript语法,建议以模块的形式对通用的方法进行封装,尽可能的利用好代码,不要有大量重复的方法语句。如果多个页面需要,可以单独建立js文件,在需要的页面进行引入。 WXSS是样式文件,遵从css的编写规则,尽可能的少些样式表,多多利用已经写过的样式,如果多个页面需要,可以单独建立wxss或者写到app.wxss中 WXML是页面结构文件。如果多个页面中有相同的结构,可以单独封装为模块,而模块中的逻辑方面也尽可能遵从代码最大效益化。 总之,开发代码简洁,会使得编译后的小程序包很小,使加载速度更加快速。 5. 小程序填坑总结: 首先,微信开发者社区是好的小程序开发交流平台,从中可以获得大多数问题的解决方法: https://developers.weixin.qq.com/community/develop/question 另外,许多人常用搜索引擎来直接搜索问题的解决方法,一般大部分的错误或者问题都会在开发文档上写的很清楚,只不过很少有人去注意到,推荐几个小程序填坑的集合文章: https://blog.csdn.net/weixin_42448956/article/details/82414225 https://www.cnblogs.com/shaoting/p/6051261.html https://www.imooc.com/article/36148 https://www.cnblogs.com/wangking/p/6946438.html https://www.jianshu.com/p/4362e52f5c49 小程序的运营 小程序运营属于软件产品运营的一种类别。从产品生命期来看,小程序运营分别为研发期、种子期、成长期、成熟期、衰退期。另外由于小程序在运行模式和定位的不同,表现在推广形式上与平常的软件产品有很大的差别。接下来,我会用【GS比赛计分】【数据查询助手】小程序为例子佐证分享小程序的运营经验。 1. 小程序研发期,搞清楚产品的定位以及目标用户 当你不是运营小程序的产品策划者,你需要首先要搞清楚产品的定位以及目标用户。(这也是多数互联网公司将产品策划和运营作为一个岗位的原因)。在整个产品的研发期,需要跟进产品的每一个细微功能点,要明晰产品的使用用户;还要时刻去观察产品的领域有没有竞品的出现,用户习惯有什么改变;要时刻去衡量产品的竞争优势,为之后的发布运营做好准备。 【数据查询助手】是提供自定义信息查询服务的小程序。任何微信用户均可以上传自定义的数据(报表,成绩单等任何表格数据)建立查询。 [图片] 当在产品研发的一个月,我不断的探索小程序领域,APP领域,Web领域有没有相同的功能产品或服务。甚至将问卷系统(腾讯问卷、问卷星、问卷网)作为潜在的竞争对手。 另外我还制作了web版和原生APP的Demo去体验他们与小程序体验的不同。去确定微信小程序是很好的适应平台。从而为之后的运营做足了准备,提升了自己的信心。 2. 小程序种子期,要充分利用体验版过程 小程序体验版相当于其他应用平台的内测版。体验版可以更高层次的模仿真实的用户环境。在这一阶段更容易发现用户间连接要求高的应用缺陷。同时可以在安全的范围内去聆听用户的真是使用反馈。 【GS比赛计分】开展了长达1个月的体验版。邀请了20个核心用户去体验。由于应用需要与服务端建立实时连接。用户不同的设备,不同网络环境对程序的稳定性做出了很大的考验。在这一阶段修复了不少场景不同导致的错误或者效率低下问题。 另外一开始推出的小程序界面设计只遵从了功能设计,没有很好的考虑真实的使用场景。所以在这一阶段,我最大程度上听取体验用户的建议,对整个界面进行改版,使交互更加的亲近用户。 3. 小程序成长期,明晰获取用户的手段和推广手段,最大化的成长: 当小程序功能稳定后,到了成长阶段,用户使用是最核心的任务。获取用户的时候,必须先让对方了解自己的产品,建立认知,将产品介绍给用户,让用户进入小程序之后,想方设法让产品与用户产生交互,让用户不断体验产品,让活动始终覆盖用户,让用户对产品认可,要完成产品与用户的关系构建。 从现在许多小程序的运营手段来看,基本上都围绕着社交裂变和线下推广的方式来提升小程序的获客表现。而小程序由于较低的开发成本,较快的更新速度,以及较低的试错成本,使得多数很强势的小程序都采用功能矩阵发展模式,快速实现功能及迭代。 小程序获取用户的手段主要由下: 朋友圈分享(包括图片二维码、广告直接进入); 聊天好友推荐转发; 线下二维码(包含商家推广、广告推广); 微信搜索(一般由其他社交平台或者用户需求引起); 线上识别二维码(线上推广,文章推广,或其他社交平台的推广); 其他小程序的跳转(互相推荐) 公众号跳转(公众号运营推广) APP跳转(一般是APP延展的简洁功能推广,或者轻量级触达用户形式的推广) 小程序发掘社交推广的手段主要由下: 社交立减金,实现社交裂变; 社交比拼玩法,引导社交裂变; 互动加入分享按钮,提醒用户转发; 设计同伴环境,鼓励社群传播; 设计任务玩法,领取奖励; 设计福利,鼓励好友助力; 聚焦核心功能,促进口碑传播; 【数据查询助手】从产品定位上就自带社交裂变的元素,当查询创建者创建了一个查询后,他可以根据要分享的人群情况选择多种分享方法。如果是企业微信或者微信工作群,那么可以直接分享小程序到聊天窗口。其他的用户可以直接进入小程序进行查询。如果是线下的查询(推广会,现场发布等),可以通过小程序二维码的方式进入查询界面查询。对于其他社交平台来讲,可以用二维码来做分享,如果是常用用户(添加到我饿小程序或者桌面作为常用工具的用户),可以直接通过复制文字(含查询码)然后进入应用的方式快速开始查询。 同时每一个查询者,都可能是潜在的查询创建者和程序推广者。所以要在这一阶段不断的优化体验流程,尽可能做更多事情覆盖多场景的查询(比如微信搜一搜直接搜索查询码,直接查询),去吸引用户,留住用户。 由于小程序用完即走的理念,导致许多工具类小程序(不含深度融合线下和社交的)用户的留存普遍较低。既然工具类就是服务用户,那么就把小程序慢慢的做成一种用户习惯,从习惯的养成变为行业应用的转化。从转化中寻找切入点,进而挖掘可以创造价值的功能产品。 所以,做小程序不要过分贪图大规模的使用率,大批量的用户。他本身是一种服务理念的触达和养成,你需要在用户心里养成使用习惯,而不要上来糖衣炮弹把用户打蒙,甚至反感。这样小程序的生态就被搞乱了。 4. 小程序成熟期,稳定期最重要的就是小版本的迭代更新: 刚才讲到,小程序有较低的开发成本,较快的更新速度,以及较低的试错成本。所以在小程序成熟期需要根据用户数据不断的去更正调整功能,去保持较高的运营分数。在产品功能中,适时的进行用户付费转化。 付费转化一方面可以拉开用户层次,对小程序的用户是一种活水作用,提升用户的使用粘性,容易过滤最核心的用户,提供更加好的产品服务。如果在成长期很好的进行用户习惯的养成,这个过程会更加自然。反之,应用将会更快的进入衰退期。 付费转化的方式主要由几类: 电商类:主要靠活动、优惠刺激(现实抢购、秒杀、预约、限时满减、显示商品库存和抢购人数); 游戏类:游戏道具(向朋友求助、每日签到、社区活动等方式免费获得,但数量有限,且都是一些级别较低的道具)高价值道具付费、皮肤售卖、游戏币购买; 内容类:付费文章、阅读币购买、付费课程; 5.小程序衰退期:适时舍弃,进行新产品开始推出 小程序开发周期短,很多时候应用分析不够透彻,更多的是一些商业或推广试错。导致许多小程序还没有进入成长期就进入晚期了。这一类小程序直接舍弃就好,不需要什么转化了,这也不算小程序的衰退期(没有盛何来衰)。 对于经历过成熟期的产品主要有几个原因导致进入衰退期: 市场中有新的创新型产品,导致冲击衰退。 自身功能设计有缺陷,导致用户流失。 对用户了解不透彻,付费转化失败,用户迁移到同类产品。 产品质量下降,不能适应用户行为的变化。 由于运营组织的原因,产品运营出现危机。 在这一阶段,运营已经无能为力。那么就进行产品的复盘,积极的去投入到新产品或者新领域的探究上面去。小程序的开发成本较低,所以可以有很多机会去重新塑造一个好的产品。 6.总结,谈谈自己的想法: 现在多种多样的互联网产品不断产生,产品竞争异常激烈。互联网产品的运营手段也是推陈出新,花样繁多。在这里我不给大家分享一些运营花样,因为每个小程序都是独特的,应该有自己独特的运营手段,具体是什么,希望产品者和运营者本身用热爱小程序的心去发现和实践。 永远保持对产品的尊重,对用户的尊敬是每个产品人最重要的事情。如果对应用足够热爱,你会厌恶他被污染,他被别人嫌弃;你会尽自己的可能让他变得更加本真,你会合理的去运营突破,去帮助产品走向更高的位置。 如果你没有爱你的产品,再出色的产品也只是昙花一现而已,并不能给你带来任何长远的意义。 这是最好的小程序运营指南:https://developers.weixin.qq.com/miniprogram/product。 [图片]
2019-06-23 - 用 HTM 实现小程序 SVG
写在前面 今天你可以在小程序中使用 Cax 引擎高性能渲染 SVG! SVG 是可缩放矢量图形(Scalable Vector Graphics),基于可扩展标记语言,用于描述二维矢量图形的一种图形格式。它由万维网联盟制定,是一个开放标准。SVG 的优势有很多: SVG 使用 XML 格式定义图形,可通过文本编辑器来创建和修改 SVG 图像可被搜索、索引、脚本化或压缩 SVG 是可伸缩的,且放大图片质量不下降 SVG 图像可在任何的分辨率下被高质量地打印 SVG 可被非常多的工具读取和修改(比如记事本) SVG 与 JPEG 和 GIF 图像比起来,尺寸更小,且可压缩性、可编程星更强 SVG 完全支持 DOM 编程,具有交互性和动态性 而支持上面这些优秀特性的前提是 - 需要支持 SVG 标签。比如在小程序中直接写: [代码]<svg width="300" height="150"> <rect bindtap="tapHandler" height="100" width="100" style="stroke:#ff0000; fill: #0000ff"> </rect> </svg> [代码] 上面定义了 SVG 的结构、样式和点击行为。但是小程序目前不支持 SVG 标签,仅仅支持加载 SVG 之后 作为 background-image 进行展示,如 [代码]background-image: url("data:image/svg+xml.......)[代码],或者 base64 后作为 background-image 的 url。 直接看在小程序种使用案例: [代码]import { html, renderSVG } from '../../cax/cax' Page({ onLoad: function () { renderSVG(html` <svg width="300" height="220"> <rect bindtap="tapHandler" height="110" width="110" style="stroke:#ff0000; fill: #ccccff" transform="translate(100 50) rotate(45 50 50)"> </rect> </svg>`, 'svg-a', this) }, tapHandler: function () { console.log('你点击了 rect') } }) [代码] 其中的 svg-a 对应着 wxml 里 cax-element 的 id: [代码]<view class="container"> <cax-element id="svg-c"></cax-element> </view> [代码] 声明组件依赖 [代码]{ "usingComponents": { "cax-element":"../../cax/index" } } [代码] 小程序中显示效果: [图片] 可以使用 [代码]width[代码],[代码]height[代码],[代码]bounds-x[代码] 和 [代码]bounds-y[代码] 设置绑定事件的范围,比如: [代码]<path width="100" height="100" bounds-x="50" bounds-y="50" /> [代码] 需要注意的是,元素的事件触发的包围盒受自身或者父节点的 transform 影响,所以不是绝对坐标的 rect 触发区域。 再来一个复杂的例子,用 SVG 绘制 Omi 的 logo: [代码]renderSVG(html` <svg width="300" height="220"> <g transform="translate(50,10) scale(0.2 0.2)"> <circle fill="#07C160" cx="512" cy="512" r="512"/> <polygon fill="white" points="159.97,807.8 338.71,532.42 509.9,829.62 519.41,829.62 678.85,536.47 864.03,807.8 739.83,194.38 729.2,194.38 517.73,581.23 293.54,194.38 283.33,194.38 "/> <circle fill="white" cx="839.36" cy="242.47" r="50"/> </g> </svg>`, 'svg-a', this) [代码] 小程序种显示效果: [图片] 在 omip 和 mps 当中使用 cax 渲染 svg,你可以不用使用 htm。比如在 omip 中实现上面两个例子: [代码] renderSVG( <svg width="300" height="220"> <rect bindtap="tapHandler" height="110" width="110" style="stroke:#ff0000; fill: #ccccff" transform="translate(100 50) rotate(45 50 50)"> </rect> </svg>, 'svg-a', this.$scope) [代码] [代码]renderSVG( <svg width="300" height="220"> <g transform="translate(50,10) scale(0.2 0.2)"> <circle fill="#07C160" cx="512" cy="512" r="512"/> <polygon fill="white" points="159.97,807.8 338.71,532.42 509.9,829.62 519.41,829.62 678.85,536.47 864.03,807.8 739.83,194.38 729.2,194.38 517.73,581.23 293.54,194.38 283.33,194.38 "/> <circle fill="white" cx="839.36" cy="242.47" r="50"/> </g> </svg>, 'svg-a', this.$scope) [代码] 需要注意的是在 omip 中传递的最后一个参数不是 [代码]this[代码],而是 [代码]this.$scope[代码]。 在 mps 中,更加彻底,你可以单独创建 svg 文件,通过 import 导入。 [代码]//注意这里不能写 test.svg,因为 mps 会把 test.svg 编译成 test.js import testSVG from '../../svg/test' import { renderSVG } from '../../cax/cax' Page({ tapHandler: function(){ this.pause = !this.pause }, onLoad: function () { renderSVG(testSVG, 'svg-a', this) } }) [代码] 比如 test.svg : [代码]<svg width="300" height="300"> <rect bindtap="tapHandler" x="0" y="0" height="110" width="110" style="stroke:#ff0000; fill: #0000ff" /> </svg> [代码] 会被 mps 编译成: [代码]const h = (type, props, ...children) => ({ type, props, children }); export default h( "svg", { width: "300", height: "300" }, h("rect", { bindtap: "tapHandler", x: "0", y: "0", height: "110", width: "110", style: "stroke:#ff0000; fill: #0000ff" }) ); [代码] 所以总结一下: 你可以在 mps 中直接使用 import 的 SVG 文件的方式使用 SVG 你可以直接在 omip 中使用 JSX 的使用 SVG 你可以直接在原生小程序当中使用 htm 的方式使用 SVG 这就完了?远没有,看 cax 在小程序中的这个例子: [图片] 详细代码: [代码]renderSVG(html` <svg width="300" height="200"> <path d="M 256,213 C 245,181 206,187 234,262 147,181 169,71.2 233,18 220,56 235,81 283,88 285,78.7 286,69.3 288,60 289,61.3 290,62.7 291,64 291,64 297,63 300,63 303,63 309,64 309,64 310,62.7 311,61.3 312,60 314,69.3 315,78.7 317,88 365,82 380,56 367,18 431,71 453,181 366,262 394,187 356,181 344,213 328,185 309,184 300,284 291,184 272,185 256,213 Z" style="stroke:#ff0000; fill: black"> <animate dur="32s" repeatCount="indefinite" attributeName="d" values="......太长,这里省略 paths........" /> </path> </svg>`, 'svg-c', this) [代码] 再试试著名的 SVG 老虎: [图片] path 太长,就不贴代码了,可以点击这里查看 pasiton 标签 [代码]import { html, renderSVG } from '../../cax/cax' Page({ onLoad: function () { const svg = renderSVG(html` <svg width="200" height="200"> <pasition duration="200" bindtap=${this.changePath} width="100" height="100" from="M28.228,23.986L47.092,5.122c1.172-1.171,1.172-3.071,0-4.242c-1.172-1.172-3.07-1.172-4.242,0L23.986,19.744L5.121,0.88 c-1.172-1.172-3.07-1.172-4.242,0c-1.172,1.171-1.172,3.071,0,4.242l18.865,18.864L0.879,42.85c-1.172,1.171-1.172,3.071,0,4.242 C1.465,47.677,2.233,47.97,3,47.97s1.535-0.293,2.121-0.879l18.865-18.864L42.85,47.091c0.586,0.586,1.354,0.879,2.121,0.879 s1.535-0.293,2.121-0.879c1.172-1.171,1.172-3.071,0-4.242L28.228,23.986z" to="M49.1 23.5H2.1C0.9 23.5 0 24.5 0 25.6s0.9 2.1 2.1 2.1h47c1.1 0 2.1-0.9 2.1-2.1C51.2 24.5 50.3 23.5 49.1 23.5zM49.1 7.8H2.1C0.9 7.8 0 8.8 0 9.9c0 1.1 0.9 2.1 2.1 2.1h47c1.1 0 2.1-0.9 2.1-2.1C51.2 8.8 50.3 7.8 49.1 7.8zM49.1 39.2H2.1C0.9 39.2 0 40.1 0 41.3s0.9 2.1 2.1 2.1h47c1.1 0 2.1-0.9 2.1-2.1S50.3 39.2 49.1 39.2z" from-stroke="red" to-stroke="green" from-fill="blue" to-fill="red" stroke-width="2" /> </svg>`, 'svg-c', this) this.pasitionElement = svg.children[0] }, changePath: function () { this.pasitionElement.toggle() } }) [代码] pasiton 提供了两个 path 和 颜色 相互切换的能力,最常见的场景比如 menu 按钮和 close 按钮点击后 path 的变形。 举个例子,看颜色和 path 同时变化: [图片] 线性运动 这里举一个在 mps 中使用 SVG 的案例: [代码]import { renderSVG, To } from '../../cax/cax' Page({ tapHandler: function(){ this.pause = !this.pause }, onLoad: function () { const svg = renderSVG(html` <svg width="300" height="300"> <rect bindtap="tapHandler" x="0" y="0" height="110" width="110" style="stroke:#ff0000; fill: #0000ff" /> </svg>` , 'svg-a', this) const rect = svg.children[0] rect.originX = rect.width/2 rect.originY = rect.height/2 rect.x = svg.stage.width/2 rect.y = svg.stage.height/2 this.pause = false this.interval = setInterval(()=>{ if(!this.pause){ rect.rotation++ svg.stage.update() } },15) }) [代码] 效果如下: [图片] 组合运动 [代码]import { renderSVG, To } from '../../cax/cax' Page({ onLoad: function () { const svg = renderSVG(html` <svg width="300" height="300"> <rect bindtap="tapHandler" x="0" y="0" height="110" width="110" style="stroke:#ff0000; fill: #0000ff" /> </svg>` ,'svg-a', this) const rect = svg.children[0] rect.originX = rect.width/2 rect.originY = rect.height rect.x = svg.stage.width/2 rect.y = svg.stage.height/2 var sineInOut = To.easing.sinusoidalInOut To.get(rect) .to().scaleY(0.8, 450, sineInOut).skewX(20, 900, sineInOut) .wait(900) .cycle().start() To.get(rect) .wait(450) .to().scaleY(1, 450, sineInOut) .wait(900) .cycle().start() To.get(rect) .wait(900) .to().scaleY(0.8, 450, sineInOut).skewX(-20, 900, sineInOut) .cycle() .start() To.get(rect) .wait(1350) .to().scaleY(1, 450, sineInOut) .cycle() .start() setInterval(() => { rect.stage.update() }, 16) } }) [代码] 效果如下: [图片] 其他 vscode 安装 lit-html 插件使 htm 的 html[代码]内容[代码] 高亮 还希望小程序 SVG 提供什么功能可以开 issues告诉我们,评估后通过,我们去实现! Cax Github 参考文档
01-04 - 从前端到全栈
一、 从前端技术演进看前端发展野心 前端的技术近几年发展非常迅速,各种框架也如同雨后春笋。 从两个维度去分析前端的技术发展,一个维度是前端复杂度,具体来讲就是前端在解决创建应用复杂度方面做的一些事情;另一个是从广度层面看前端做的事情, 这两个维度构成了一个类似于二维平面的时间事件平面。 [图片] 1. 逐渐降低创建应用复杂度 单看复杂度,前端最开始的阶段只有HTML、JS、CSS,应用虽然是非常简单的,开发起来却是非常复杂的,因此,单单只是DOM操作方面就有大量的DOM操作API。为了降低操作成本,就出现了DOM操作框架,比如jquery。这个阶段类似于从原始的刀耕火种进入石器时代。对dom的操作带来了很大的便利性。尽管如此,真正在构建一个复杂应用的时候,因为业务逻辑和手动操作dom逻辑交织在一起,应用维护变得越来越难。 下一个阶段,引入了MVC分层思想,比如backbone,这能够将逻辑梳理的更加清晰一些。不过,MVC还是需要去关注视图层的。 接着,就出现了mvvm框架,开发者不需要再关注视图层的更新,只需要关注逻辑层、数据层。这一点为构建复杂大型app提供了极大的便利性。mvvm从Angular到现在react、vue的广泛应用,前端在逻辑构建层面发展已经到了一个新的阶段。 在构建大型应用的时候,仅有逻辑层是不行的,还缺乏工程性的思想。因此,出现了打包的模式,帮助我们构建更复杂的应用。这样我们所能做的APP复杂度是一个指数型的增长。 为了进一步提高可构建应用的复杂度、增强前端的性能,assembly技术标准出现,提供了前端字节码的标准,为创建更加复杂的应用打好了坚实的基础。 2. 一直在扩展的前端广度 刚开始只能在浏览器上运行,后来有了node代码,可以让我们的代码扩展到服务器端。紧接着PC端有electron。再到移动端有RN框架,支持我们向移动端进展。 现在出现了小程序,小程序框架能够让前端继续在移动端轻应用做探索。 这里没有讲到的嵌入式开发,这方面也有相应的解决方案。 前端不断扩展广度,把前面的边界不断扩大。 最终前端想一统天下,把前端全栈化。 二、 同时满足技术需求和商业需求的前端全栈 所有的技术在发展时期都有两条线去支撑着它发展,一条线是技术需求,即技术层面的技术创意和技术诉求;另外一条线是商业需求,即技术要满足对应的商业诉求。 [图片] 一个解决方案只有同时满足商业诉求和技术需求,才能蓬勃的发展。如果偏离这两条线,就很难发展起来。举个例子,比如Symbian,有些人有想尝试这个技术诉求,但是因为它已经脱离商业需求的层面,所以这个技术会慢慢被淘汰掉。 那么,如果仅有商业需求又会出现怎样的情况呢? 比如,2000年的时候对AI有商业上的需求,但是技术需求并满足,当时AI就是一个要被搁置的东西。 前端全栈,是怎样在满足技术需求的同时满足商业需求的呢? 我们回归到移动端APP的开发实际场景,只有两个层面:一个是UI交互界面的开发,这个是可以被用户感知到的,另外一个是用户感受不到的服务逻辑层面。如果来看现有的开发模式,单单从UI交互界面上来看,就有不同的平台端android、ios、h5,对应的语言有Java、OC、swift、js等几种语言,后端的语言和技术实现是更多的。在现在的模式下,一个小型公司如果需要开发一个完整的APP项目,就需要六种技术! [图片] 每一种技术如果需要找一个专门的人来做,这就需要6个人。那么反映到公司企业运营上面,人力成本是比较高的,除了人力成本还有同样非常高的沟通成本。从沟通的角度上来看,全栈式开发模式的出现,能够让一个人负责更多的业务开发,降低沟通成本。 由此可见,前端全栈既满足技术需求,也满足商业需求的,所以我相信未来前端全栈一定会蓬勃发展。 三、 打破物理隔离,实现真全栈 再回过头看前端散落的各种技术,在这个发展的过程中,有一个很深的隔离,这个隔离本质上就是物理隔离,比如前端和后端,存在手机和服务器之间的物理隔离。 [图片] **因为各种端是实体端,每个端之间都存在物理隔离。**就比如前端和后端,存在手机和服务器之间的物理隔离。如果能解决这些隔离,就可以把前端的技术做到真正的统一开发模式,才能做到真全栈开发。 [图片] 其实后端的物理隔离,比如每台服务器之间的物理隔离,可以通过云端化,我们把代码上传到云端平台,云端平台会屏蔽机器之间的物理隔离,暴露给开发者的只有一个集群的概念,而不是一台机器一台机器管理部署。云端化之后,后端的物理隔离被消除了。 我们现在的前端代码和服务器之间终存在一个物理隔离,目前的解决方案是通过中间的协议打破物理隔离,比如http协议,但http协议毕竟是中间协议。 而serverless的理念就能完完全全解决掉这层物理隔离,因为代码即服务,serverless能打破这层隔离实现前端的真全栈。 Serverless中的FaaS,函数即服务,我在使用后端服务的时候,不再关心后端的ip地址,后端的域名是什么样的,直接调用函数即可,对前端来说,后端服务是一个函数,函数就是前端的代码的一部分,后端服务和前端完全的融合在一种代码体系里去了,这样后端的服务即是一个函数,至于这个函数是在前端实现,或者是在后端很远的地方实现,开发者都可以不用关心。所以说,severless打破了物理隔离。开发者不再去做任何隔离中间层的事前,我只需要关心函数的实现就可以了,函数也是用我的前端代码来写,所以达到了充分融合的定义。 回过来看具体的实现场景,比如云开发,整个小程序的前后端逻辑都能在一个IDE里面完成,用户其实完全不用担心哪些是服务器的逻辑,他们都去向了哪里,只需要像前端函数一样去理解就可以了。云函数现在也支持了本地调试,就像前端代码一样调试,所以可以做真正的前端全栈技术开发,这对现有的开发模式是一个很大的革新。 四、 小程序云服务的发展优化 那么,在大前端技术发展的这波浪潮里面,小程序云服务又有什么样的发展呢? 早在2017年初小程序正式发布的时候,第一代腾讯云小程序云服务就已经诞生了,但随着8月份全面向个人开发者开放,我们发现这套支服务还是有一定门槛的。于是就开始着手去做更深度的云服务整合和优化,才有了后来的wafer2 和现在的云开发。 [图片] 早期第一代产品 Wafer 的整个开发部署流程,统计了一下大概需要十几步,对许多中长尾的客户来说并不是那么友好。于是我们开始着手优化。 **通过整个优化,可以简略成四步。**第一步是通过一键的配置购买就能把云开发产品开通起来,第二步是工程师进行小程序的前后台开发,第三步进行代码的预览上传,测试体验完,最后便是发布。经过我们这一两年的努力,小程序开发的流程已经由十几步简化到四步了。目前如果从市面上来看,我们这个产品在用户体验以及流程简化度上,在行业内是较为领先的。 [图片] [图片] [图片] 那么,我们腾讯云团队和微信团队如何一步一步优化我们的产品,将产品的接入门槛降低、流程变简的呢? [图片] 最初我们看到的是可以将 devops 的部份环节给优化一下,包括代码上传部署。这就催生了后来的Wafer 2,亦即第二代的小程序云服务产品。 另外开通购买步骤也是比较繁琐的。将腾讯云和小程序的账号打通后,可以做到一键授权并且开通环境与服务,并且我们提供了一个免费的开发环境,这样可以让更多开发者在进来发布小程序之前,可以以更低的成本门槛用上云开发。 剩下还可以优化的就只有 SDK 引入和填写配置的环节了。 SDK 其实可以采用内置的方式,毕竟小程序的前端接口也是直接内置到运行环境的 webview里面的。但是配置这块并不太好做了。因为一直以来,小程序前端和后台的开发都是割裂的,因此整个用户的鉴权机制都是交由小程序开发者自己去处理。但为什么小程序与云服务一定是要割裂的呢,为什么不能整合到一起呢?而 Serverless 这种开发模式是前后端紧密结合的最佳粘合剂。 一般而言,请求从小程序侧发起,到云服务的后台逻辑进行鉴权处理,如果鉴权成功再调用微信公开发 API,然后再把数据返回到小程序。 [图片] 但我们稍微将整个请求链路改变一下,小程序侧的请求先通过微信的服务,认证并鉴权成功之后,再到腾讯云这边的 Serverless 服务进行逻辑的处理,处理完毕后再返回到小程序侧。这样,我们把整个配置和鉴权服务都帮用户完成了,这又大大减轻了开发者的负担。 [图片] 通过介绍整个小程序云服务的优化历程,相信大家能感悟到整个产品的理念,就是希望一方面云能力逐步成为小程序开发的基础能力,另一方面也希望尽量减少开发者需要理解的概念。 五、 从前端开发到全栈开发 在云开发模式的推动下,我们开发模式是怎么一步步走到现在的开发模式的? 在Web刚出现的时候,后台开发本就是大包大揽,后台逻辑完成后,再把模板和数据吐出来到浏览器渲染。当时基本上都是做一些比较简单的Web应用。但是当时没有人会吐槽你的后台工程师只有一个人,怎么都把后台和前端服务都干完了,可能当时的业务逻辑并不是很复杂,前端技术也不是那么的规范化,应用场景不是那么多,所以才出现这样的情况。 可是到后来,随着浏览器逐步发展,JS、CSS、HTML有一个规范委员会帮它每年制定一些新的特性。而且随着业务场景越来越复杂,这种情况下开始提出前后端分离,开始要求后台和前端是分开两个人做事情,前后两端是通过API的请求和返回去做一个数据交互。 再到了2008年的时候,乔老爷子凭一己之力开启了移动端的开发生态。到了2017年张小龙大神也跟微信团队推出了小程序且打造了小程序生态。这个时候很多专家提出了“大前端”的概念,希望只写一份代码,就是编译并完成不同客户端的业务,这些端只需要共享一个后台服务就可以了。 这个时代国外出现了一些跨端方案,比如React Native,国内也涌现了 Taro, Omi 等优秀的跨端方案。这几个时期的前端职能是有明显扩张的。 [图片] 只做了大前端完全满足不了前端的野心,随着Node.js的发展,有一些中台的服务,比如同构渲染和业务接口但逐步转给Node.js 来做。后台的同事开始专注于去写一些后台的调度服务或者优化整个数据的读取性能。这个时期,前端开发者也开始从前端逐步往后台做一个拓展。 [图片] 但大前端的步伐远远不只于此,在很多业务场景里面,前端工程师比较贴近客户,所以他更能够去理解到一些业务逻辑,无论是业务的前台或是后台,交给前端工程师来做是更好的。举个例子,云开发的其中一个客户是唯品会的前端团队。他们其中有个业务需要依靠后台来支持,但他们的后台人力很紧缺没有办法马上投入支持。于是他们的前端就借助云开发,投入1个前端工程师就迅速把这个业务给做完上线了。其实许多公司的业务都有类似的情况,公司业务发展非常快,但有的时候要前端等待后台的人力,这样就影响到整个公司的业务发展。 [图片] 可是前端的全栈开发的模式,从前端到后台,把所有的业务全都写完了,其实你会发现又回到我们最初的一个工程师大包大揽的做事情。可是这个业务是复杂的,如果没有一个工具或者一个云的基建设施去支撑这个梦想的话,其实是完全不能实现的。 面对这样的挑战,我们应该怎么答复我们的老板呢? 腾讯云目前提供的解决方案就是云开发。 [图片] 传统开发模式会让前端变成大包大揽地做业务,其实是相当困难的,因为一方面要开发前端和后端的逻辑,还要处理所有的运维的事情,靠一个人是不可能的,所以才有了现在这样的传统分工模式,就是前端、后台、运维。如果把这个业务用上云开发的话,我们主要关心的只有一小部分,主要都是我们的业务逻辑。至少只要这个工程师能够懂Node.js,基本上就可以把服务稳定、性能卓越和有一定安全性的小程序应用独立开发出来。 云开发的开发模式真正可以实现前端工程师全栈开发的理想模式。
2019-04-26