- 一场比赛,一窥小程序的有限与无限
本文参加2019年「大赛文章征集」征文活动 大家好,我是华南赛区二等奖「Resser 阅见」小程序的开发团队DeveSA的队长。继上一篇高校微信小程序大赛经验分享杂谈流水账般介绍小程序的开发流程,这次我们来谈谈更Deep一点的——小程序的有限与无限。 「有限」和「无限」乍一看是不是很玄乎?让我稍稍剧透一下,这里的「有限」指的是小程序开发和运营上受到的限制,而「无限」则是小程序与生俱来的裂变能力和发展前景。本文的目的不只是简单地罗列这些Pros&Cons,也会根据在比赛中汲取到的经验分享给大家如何越过这些Cons并利用好Pros。 技术层面 wx.request 我相信每一个开发过小程序的developer,都记得大明湖畔的[代码]wx.request[代码]。曾几何时,比赛群里都是大家讨论如何在ddl前搞好备案,又或是ddl前一天匆匆忙忙设置好调试模式。 [代码]wx.request[代码]是微信提供的网络请求接口,限制诸多,有: 只支持HTTPS协议 不能使用IP地址或localhost 不支持8080以外端口 请求的域名必须经过ICP备案 用来鉴权的[代码]api.weixin.qq.com[代码]不能配置为服务器域名 Header中不能设置User-Agent 20个域名限制 而我们开发的「阅见」本质上是RSS阅读器,请求的feed链接都是用户自定义的外链,这些外链有HTTP的,也有没有备案的,数量更是无限的。这不就完美和[代码]wx.request[代码]的限制撞车了吗? 在这些限制下,很多同学第一反应是匆忙给自己的服务器上证书、上备案,却也不免遇上使用的第三方开放API(如[代码]http://api.github.com[代码])没上备案的问题。这就引出了更高阶的解决方法——在自己已备案的域名上设置[代码]tracker[代码]域名转发。然而,还有一种更优雅的方法——云函数。 也就是,原本从小程序到目标服务器的过程(上图)中间加入了云函数(下图)。 [图片] [图片] 借助于云函数与小程序得天独厚的血缘关系,小程序配置和调用云函数都十分方便。 云函数使用原生的[代码]request[代码]对传入的网址进行请求: [代码]const request = require('request'); exports.main = (event, context) => { return new Promise((resolve, reject) => { request(event.options, (error, res, body) => { if (error) return reject(error); resolve(res); }) }); } [代码] 小程序端则将原本的[代码]wx.request[代码]封装一下,代码有点长,只给个思路: [代码]wx.vrequest = function (options) { //将options转发到params,过程省略 return new Promise((RES, REJ) => { wx.cloud.callFunction({ //请求云函数 name: 'v-request', data: { options: params }, success: res => { const { result } = res; options.success && options.success(result); RES(result); }, fail: err => { //错误回调 REJ(err); }, complete: options.complete }) }) } [代码] 具体部署可以参考Github上guren-cloud/v-request WXML与富文本解析 解决了[代码]wx.request[代码]的问题,「阅见」遇到的第二个问题就是很多网站不支持RSS全文输出,因此我们计划让「阅见」能得到文章原文的HTML内容输出,再经过富文本渲染,呈现在小程序上。 小程序采用WXML,微信设计的一套标签语言,然而,网页上的富文本都是通过HTML呈现出来的,这样的话,当小程序想显示网页内容时,只能调用[代码]web-view[代码]了,而[代码]web-view[代码]不支持个人类型的小程序…… Butttt,多亏了小程序良好的生态环境,有很多开发者为小程序编写插件和库,其中,有关富文本渲染的就有wxParse和Towxml。其中wxParse已经两年没有更新了,虽然也有各路大神fork改良,但由于RSS获取到的文章千差万别,支持性不是很好(比如代码显示以及[代码]ruby[代码]标签等)。这里我强烈推荐Towxml,除了这个渲染库比较新之外,Towxml还有许多优良特性,比如,官方号称的“极致的中文排版优化”。 Thanks to Towxml,在「阅见」中,用户可以看到排版优良的订阅内容,甚至还能看视频哦。 [图片] 除了Towxml,「阅见」还借助了URL2Article提供的API提取正文内容,其能精准识别网页的正文部分,提取的内容不含广告导航等非正文内容。 [图片] 资源占用 说起小程序,你能想到最合适的形容词是什么?对我来说,就是「小」,这个「小」不只提现在小程序「触手可及、用完即走」的轻量,还有对开发者实在的限制——打包体积不能超过2M,本地缓存上限10M。 [图片] 这对于在大内存时代动辄上百兆代码的coder们来说,无疑是极大的限制。Butttt,在实际编写小程序时,只要有良好的编程习惯,这2M和10M是完全够用的,因为代码包经过了GZIP压缩后压缩率可以达到80%。 话虽如此,在「阅见」中,主要操作都是在小程序端完成的,所以相应的逻辑代码很多,在开发后期我们也的确遇到了代码包超过2M的情况。下面给一些减小代码包的体积的Tips: 小程序中只保存图标需要的图片文件,除tabbar外图标都使用[代码]·svg[代码]矢量格式,不仅体积相比[代码].png[代码]等传统点阵格式小了很多,而且也有矢量图永远高清的优点。 其他静态图片保存在服务器上或托管在图床上,七牛云就是个不错的选择,每个月还有免费的10G CDN流量,访问速度比云开发中的云储存快了不少。 删除测试使用的[代码]console.log()[代码]语句 压缩CSS代码 如果使用了第三方UI框架库,可以删除没有使用到的组件 如果以上Tips还不能解决代码包体积超过限制的问题,可以使用分包。 大部分小程序都会由某几个功能组成,通常这几个功能之间是独立的,但会依赖一些公共的逻辑,并且这些功能通常会对应某几个独立的页面。那么小程序代码的打包,大可不必一定要打成一个,可以按照功能的划分,拆分成几个分包,当需要用到某个功能时,才加载这个功能对应的分包。 使用分包方式加载小程序,能使小程序承载更多的功能与服务;而对用户而言,可以获得更快的加载速度,同时在不影响启动速度前提下使用更多功能。 目前小程序分包大小有以下限制: 整个小程序所有分包大小不超过 8M 单个分包/主包大小不能超过 2M 除了代码包2M的限制外,别忘了还有10M的缓存限制。在刚开发小程序时,我在所有跨页面传参使用的都是[代码]wx.setStorageSync[代码]和[代码]wx.getStorageSync[代码],不仅拖慢了程序的运行速度,还占用了宝贵了n/10M。其实,对于不需要存储在本地的跨页面传参,完全可以用[代码]app.globalData[代码]来代替: [代码]app.globalData[代码]是全局变量,下次进入的时候,就要重新获取。 [代码]Storage[代码]是本地缓存,除非缓存被清除不需要重新获取。 运营规范 登陆 相信大家对下图的warning都不陌生: [图片] 在之前,小程序可以直接通过[代码]wx.getUserInfo[代码]调起授权弹窗,这一操作虽然很便利,但却被一些开发者滥用,有些小程序一打开就要求授权甚至不授权就不能使用。在考虑到这一点的基础上,[代码]wx.getUserInfo[代码]不再显示授权弹窗,只能用button组件的开放功能调用。引用官方的话: 用户使用登录功能就像“面基”,第一印象很重要。这几个小改动在提升小程序使用的流畅体验、避免用户对数据采集授权担忧的同时,也将驱动用户更乐意尝试使用小程序服务。 因此,好的选择是在用户第一次登陆时“微妙地提示”用户授权登陆,并且在用户未授权时也可以访问到小程序的公共内容。 模版消息 我们知道,iOS上有专门的消息推送机制,而安卓上只能通过让应用后台运行实现24小时接受消息。借助于微信的装机率和使用率,小程序不需要时刻保持后台运行也能让用户接受到消息,这靠的就是微信的模版消息功能。Butttt,为了防止此功能的滥用,模版消息的发送有两个触发条件: 支付:当用户在小程序内完成过支付行为,可允许开发者向用户在7天内推送有限条数的模板消息(1次支付可下发3条,多次支付下发条数独立,互相不影响) 提交表单:当用户在小程序内发生过提交表单行为且该表单声明为要发模板消息的,开发者需要向用户提供服务时,可允许开发者向用户在7天内推送有限条数的模板消息(1次提交表单可下发1条,多次提交下发条数独立,相互不影响) 所以开发者难免会遇到模版消息发送次数不够用的窘况。但根据第二点,小程序每获得一次[代码]formId[代码],相当于就多了一条模版消息的「命」。简单来说,我们可以将小程序的表单组件进行封装,把用户的交互点击的[代码]bindtap[代码]事件替换为[代码]bindsubmit[代码],乔装一下小程序中其他功能按钮,当用户点击这些按钮时,就能获取到更多的[代码]formId[代码]。 ⚠️ 不过即便如此,开发者也应该遵守小程序运营规范,不要滥用模板消息。 更新:根据7月25日「微信广告小程序流量主大会」消息,微信小程序将上线「一次性订阅消息」的能力,只要经用户确认,超过七天的模版消息也能送达用户。 总结 小程序脱胎于微信,出生时便自带「降低门槛、充实能力、场景流量、提高转化、交易变现」等强有力的Buff,在电商零售、政务平台多方面可以说是全面赋能,有无限的发展潜能。小程序在方便用户,降低用户使用门槛的同时,也为开发者们提供了诸多上手即用的API和组件。如此强有力的工具想要长青,自然需要在开发、运营上施加限制,此之谓「有限」,而施加限制的目的是建立友好的微信生态体系,实现用户、微信、开发者三方互利共赢,此之谓「无限」。
2019-07-26 - 高校微信小程序大赛经验分享杂谈
本文参加2019年「小程序征文·大学篇」征文活动。 大家好,我是「Resser 阅见」小程序的开发团队DeveSA的队长,虽然小程序暂时无缘赛区决赛,那我就只能先厚颜无耻地码下这些字,作为对比赛以来小程序开发中收获的经验与教训的总结。 What —— 我们开发的是什么? 我们开发的「Resser 阅见」(以下简称「阅见」)是一款基于RSS/ATOM的资讯聚合阅读小程序,其特点是门槛低,姿态新,聚合度高。 说得太拗口?看图就懂了👇 [图片] 接触过RSS的朋友可能会说,“哦,不就是个RSS阅读器嘛,RSS不是已经半死不活了吗”。的确,「阅见」就是一款基于微信小程序平台的RSS的阅读器。不过,我们降低了RSS的使用门槛,让普通用户能像关注微信公众号一样简单的关注自己喜欢的几乎所有内容(从微信公众号、B站到微博等),而高级用户也能延续RSS的使用习惯玩出各种高阶功能。 由于小程序尚在参赛阶段,为了评委能第一时间用上最新版本的小程序,我们还未将小程序正式上线,因此很遗憾大家暂时无法体验到小程序的功能了。 How —— 我们是怎样从入门到不入土的? 作为在校生,要从繁忙的课程和考试中抽出时间来开发一个完整的小程序,着实不易。能在ddl之前完成这个项目,主要归功于我们团队良好的时间规划和任务安排。作为队长,我将比赛过程分为备赛、开发、精修三大过程。 备赛过程 对上届获奖作品分析 既然开发这个小程序的目的是为了参赛,那么当然要奔着获奖为终极目标。因此,团队在4月份体验了去年获奖的30个小程序,从小程序的界面、操作、新颖程度等方面进行分析。在体验这些优秀作品的同时,我们也获益良多。产品中让我们惊喜的点可以作为之后开发的参考和灵感,产品中使用不畅的地方也为我们提前敲响警钟。 [图片] 初步入门 在参赛之前,我们团队中无一人有小程序开发经验,但是凭着初生牛犊不怕虎的精神和魄力,我们照着学做小程序-学堂在线-精品中文慕课(mooc)平台上的课程和官方开发文档实现了对小程序的初步入门。 当然,学习小程序的开发并不是一个单向的吸收知识的过程,边学边做是最好的入门方式。 开发过程 前期规划 考虑到我们开发小程序的过程也是学习小程序的过程,我们并不清楚某个提出的功能是否能得到实现。因此,我们先确定了小程序的大体架构,也就是页面的布局,每个页面要实现怎样的功能,通过什么方式去实现。通过经验的累积,再逐步往这个框架中填沙子,这样便不至于出现“走一步看一步”的窘况。 [图片] 协同工具 由于团队规模很小,只由两人构成,因此使用各种todo工具就显得杀鸡用牛刀了,我们选择的团队协作工具是非常质朴而接地气的——QQ群。 [图片] 在每周我会给团队布置任务并要求组员提交任务报告,这种半强迫性质的ddl一定程度上能有效防止组员划水并且增加团队成员的参与感。 而我作为主开发手,将各种功能划分为基础型、进阶型、配置型、魅力型四种类型,使用Markdown编辑器Bear记录功能的完成进度。 [图片] 当然,如果是较大型的团队,则需要更加专业的协同工具,这里推荐Slack和Teambition。 开发工具 虽然在备赛学习过程中看到许多开发者都使用VS Code和JetBrains系列软件,但我们依旧采用了官方的微信开发者工具,因为微信开发者工具毕竟是微信官方专门为小程序开发的IDE,体验上来说更加原生,也方便从IDE的更新日志中了解到小程序的最新动向。 [图片] 但是由于微信开发者工具还不够完善,实际使用过程中出现过几次问题,这里一个小技巧就是——稳定版出问题换Beta版,Beta版出问题换稳定版。 填坑与技巧 微信小程序合法域名校验:可以使用云函数进行反向代理 常用API接口:BAT都有在做NLP的接口、以及url2io的正文提取接口等等、更多接口提供商如易源数据等 云开发云存储图片可以直接调用,但是加载速度比较慢,建议还是用七牛云CDN SVG图片的体积小而且矢量图更清晰 精修过程 这里的精修,一方面是指对小程序的操作流程中可能存在的Bug进行排查和修复,另一方面是对用户界面和交互逻辑进行更细致地精调。 内测排查Bug 在这一过程中,我们在校园内开放了内测活动,聆听不同的声音,也从这些内测用户口中得到宝贵的意见和建议。在获得用户反馈这一过程中,我们发现用户特别懒于前往我们提供的反馈网址提交反馈,因此我们在小程序中加入了客服功能,用户在体验小程序的过程中遇到任何Bug或是有任何建议都可以不需要离开小程序就能够反馈给我们。 UI设计 我们也在比赛ddl前一周完成了对小程序Icon的绘制、UI的精调。 [图片] 有必要说一下Icon的设计理念,因为完成了Icon的设计后,UI的设计也就完成了一半。何出此言呢?因为小程序的界面配色要和Icon呼应,配色确定好了,可不就是完成了一半的设计嘛。 图标背景色使用Brandeis Blue(布兰迪斯大学蓝,蔚蓝色)和Solitude(孤独蓝,浅蓝)。布兰迪斯大学被称为全美最年轻的主要研究大学,而布兰迪斯大学蓝也被寄予“年轻”、“实践”、“应用性”的美好寓意。正如同「阅见」这款小程序一样,年轻而实用。孤独蓝则对应「阅见」小程序的Slogan——看见开放互联网未经过滤的样子,「阅见」希望每个人能作为一个独立的个体,去客观看待这个世界。 外形上,图标由中文汉字和圆弧形背景组成。蔚蓝色的圆弧象征地球(舒适区内),另一半的浅蓝色象征大气(舒适区外),「阅见」两字分别位于两种颜色上,寄予「阅见」能打破回音壁,让用户看到更全局的世界的美好愿景。 发布之前的收尾工作 对于小程序来说,除了用户用的了看得到的功能,还有隐藏在功能和界面之下的东西,比如小程序的体积、打开的速度、边界条件的设定等等,这些是用户不容易感知到的,但无形中又影响着用户体验的点。 减小小程序的体积:去除不需要的console.log等测试代码、代码文件压缩、图片尽量使用SVG格式。 加快小程序的打开速度:其实在减小小程序的体积的操作里,就能加快程序的运行速度了,还有就是可以将引用的图片CDN加速。 边界条件的设定:所有需要用户输入的地方,都需要边界条件的设定,比如用户输入RSS订阅链接时不小心输错成了标题,如果不做边界条件设定的话,小程序就会request一个不合法的网址,就可能造成小程序崩溃 One More Thing —— 上线之后的规划 说实话,在做这个小程序之前,我一直没有找到称心如意的跨平台RSS阅读器,然后碰巧看到有这么一个比赛,就想着自己开发一个好用的RSS阅读器。开发过程中,也调研了很多国内外的相似产品,比如国内的轻芒阅读、国外的红板报、Feedly、Inoreader等等。资料查得越多,心就越凉,因为几乎都是RSS已死的论调。但既然选择了这个主题,一条路也要走到黑。所以我又去探究RSS没落的原因,归纳成如下几点: 订阅源规范不统一:当前存在的Feed规范有RSS 0.91、1.0、2.0和ATOM等,不同源输出的XML格式不同,导致解析困难。 正文获取困难:越来越多网站为了广告和引流停止输出RSS或者不输出正文,传统的RSS 阅读器无法正常显示。 使用门槛高:传统RSS阅读器手动输入链接添加RSS操作麻烦。 无参与感:RSS相当于提供了一种单向的服务,用户只能作为信息的被动接受者,没有参与感。 平台和内容提供方盈利困难:RSS Feed不能给内容提供者带来流量和收益,提供者放弃RSS内容输出,也导致内容平台流失用户。 说白了,就是没有盈利去维持RSS的生态,所以我想,如果能够解决内容平台和内容提供者的盈利问题,是不是可以给RSS续一秒。 我们计划采用盈利补贴、竞价排名、数据反馈三种方式打通和内容提供者之间的壁垒,实现内容平台与内容提供者互利共赢。 盈利补贴:我们计划在小程序上线并积累一定用户后,在首页信息流和文章内投放广告。文章内广告的营收将按一定比例作为该文章内容提供者的补贴。即:优质的文章带来大量流量,广告投放将流量变现,变现的一部分作为对内容提供者的补贴。 竞价排名:并且,对于知名度不高的内容提供方,「阅见」可以作为除微信公众号、网站、今日头条外另一个平台帮助其推广。发现页面每个分类下展示的订阅源以及搜索建议将采用竞价排名形式,即前3个订阅源根据用户订阅热度排名,往后的4-10个订阅源采用竞价排名形式,一方面为「阅见」提供营收,一方面也可以增加内容提供方的曝光率。 数据反馈:由于「表态」功能的引入,「阅见」可以获得用户对特定文章的反馈,我们不希望这些反馈只是作为一个摆设,而希望用户的反馈能够达到内容提供方,帮助其提升内容质量,了解用户的心理。 喜欢就点个赞吧 😃 有任何疑问,欢迎联系作者:rhinoc@outlook.com
2019-06-28