本文并非入门向介绍文章,适合有一定前端基础的开发者阅读。
经过年前若干天的开发、测试、审核,我司的小程序上线了,这是一个专注与打通线下体验、线上购买流程的小应用,感兴趣的可以微信内搜索 “身边寻宝” 进行体验。
开发整体体验
首先我们回忆下最开始公测时官方开发工具是个什么样子:
-
每次编辑完需要点击编译,偶尔还需要再刷新,因为刷新完总回到首页,所以调试特定页面需要每次重新导航
-
编译出错或者运行出错看不到提示,开发者只能对着白屏进行各种尝试性修复
-
经常性崩溃,高 CPU 高内存占用问题频发
前两个问题开发工具已经很好解决了,最后的问题在正式版发布后我也没再碰到过了,可以说已经比较稳定了。
一些开发建议
-
使用 es6 , 让你的代码更少更可靠,有一点要注意的是 object spread 并不属于 es6 规范
// 以下的用法是不行的
this.setData{obj, ...data}
// 参数 spread 是可以的
function f(x, ...y) {
// y is an Array
return x * y.length;
}
-
使用 polyfill, 微信尽管最大程序统一了 webview, 但是部分旧的 webview 依然是缺少部分常用方法的,例如:Array.find, Array.findIndex. 给出一份我使用的 polyfill.jshttps://gist.github.com/chemzqm/3653bdc576d7110acee4b9413d254ef6, 代码多数来自 MDN,仅供参考
-
使用 Promise,让你的异步并发和串行代码更容易编写和维护。因为微信旧版是没有原生 Promise 的,所以官方屏蔽了 Promise,你需要自己做一个 Promise 实现,网上有兼容标注 Promise 规范的实现,只需去掉相关 window 的判定即可:https://gist.github.com/chemzqm/8e50e23c35cc14992831027a40b8d871
-
分离 UI 代码和请求逻辑,这样你的请求可以在不同页面重用,将来维护相对容易些。我们有一个 service.js 文件,里面包含了所有请求后台的函数,返回均为 Promise, 这样方便做统一的控制管理
-
合理使用 wxml 中的 import 和 include,import 对应需要填充数据的模板,而 include 则用于引入静态的内容
-
避免把一个页面设计的太复杂,否则一个页面对象上过多的 data 数据和方法会变得很难管理
-
避免使用你不熟悉的第三方框架,例如使用 redux 来管理数据状态,因为小程序本身就有通过 data 属性实现了统一的数据管理,另外还提供了 devtools 工具方便调试,引入 redux 却不能在开发工具使用 redux 插件,结果可能只是增加了数据管理的难度
-
使用官方 UI 简化设计开发流程,weui/weui-wxss: A UI library by WeChat official design team, includes the most useful widgets/modules. 如果你的项目对 UI 定制要求不是很高的话
-
微信官方的 animation API 只是封装相关 css 属性的生成,其实质还是使用 css 的 transtion 样式,你也可以自己写相关样式后添加到元素 style 属性或者使用 animation 实现动画。出于性能考虑,不建议使用 tween 之类的库动态生成样式传递给 setData 函数
-
使用 svg data-uri 来做 icon, 小程序的 background 里只能使用完整的 image 路径,对于针对项目的 icon 来说,使用 svg 会更为方便一些,而且svg 是矢量图,具备完美的可伸缩性,使用 utf8 格式将来也可以很容易进行调整(主要是颜色),参考 Probably Don't Base64 SVG | CSS-Tricks 。Material icons - Material Design 提供了大量常用 icon 的多种格式,推荐使用。
-
尽可能利用 flex 进行布局,因为 flex 适应性最好,而且非常灵活,
-
合理使用 rpx 单位,rpx 是一个相当于屏幕宽度百分比的相对单位,我们在实现上对于部分padding 和 margin 样式使用了 rpx 来使得大屏上的布局获得更佳的展示效果,对于 font-size,border-width 等样式,不建议使用 rpx
-
不考虑性能问题可以使用 css 反锯齿,让字体渲染更精细一些,只需要 app.wxss 中加入:
page {
text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased;
}
-
使用有质量的开发辅助工具,例如:
-
chemzqm/wept: 微信小程序 web 端实时运行工具
-
chemzqm/wxapp.vim: 提供微信小程序开发全方位支持的 vim 插件
-
chemzqm/mockapi: Create a mock api service in minutes (有待完善)
遇到的一些问题及解决办法
-
html 无法使用,使用正则去掉 html 标签就是了,我们使用的代码如下:
export function formatHTML(html) {
html = html.replace(/<style([\s\S]*?)<\/style>/gi, '');
html = html.replace(/<script([\s\S]*?)<\/script>/gi, '');
html = html.replace(/<\/div>/ig, '\n');
html = html.replace(/<\/li>/ig, '\n');
html = html.replace(/<li>/ig, ' * ');
html = html.replace(/<\/ul>/ig, '\n');
html = html.replace(/<\/p>/ig, '\n');
html = html.replace(/<br\s*[\/]?>/gi, "\n");
html = html.replace(/<[^>]+>/ig, '');
html = html.replace(/\n{2,}/g, '\n\n')
html = html.replace(/\n+$/g, '')
html = html.replace(/ /g, ' ')
return html
}
性能不是很高,但是现代浏览器性能还是不错的,完全感受不到。
-
页面深度限制,小程序出于性能角度考虑做了 5 层跳转层次的限制,解决办法就是尽可能避免深层次的交互
-
合并多个页面,例如将搜索页面和搜索结果页面放到同一个页面上
-
使用弹层而不是跳转,例如我们支付页面的添加收货地址使用了弹出层,而不是跳转添加页面
-
使用 switchTab API,该接口会清理之前的页面栈
-
使用 redirectTo 接口重定向而不是使用 navigateTo
-
原生组件总是显示在最上层,小程序中 canvas、textarea、video 等组件使用原生渲染,如果需要弹层交互的话它们会挡住弹层。解决办法就是在弹层后将这些组件 hidden 属性设置为 true,弹出消失时重置为 false 即可。另一个问题是如果这些组件在弹层内,它们不会限制在弹层中,而是会随着页面整体进行滚动。
-
并发请求限制,小程序限制了最多 5 个并发的 request 请求。我们遇到的一个情况是需要图片自适应高度,而小程序不支持图片高度自适应,需要显示用 wx.getImageInfo 接口获取图片尺寸信息,如果图片多于 5 个且同时请求就会触发这个限制。解决办法是使用一个 promise 队列函数,实现如下:
-
export function queue (fns, count) {
return new Promise(function(resolve, reject) {
let a = fns.slice(0, count)
let b = fns.slice(count)
let l = fns.length
let runs = 0
if (fns.length == 0 ) return resolve()
for (let fn of a) {
fn().then(() => {
runs += 1
if (runs == l) return resolve()
let next = function () {
let fn = b.shift()
if (!fn) return
return fn().then(() => {
runs += 1
if (runs == l) return resolve()
return next()
}, reject)
}
return next()
}, reject)
}
})
}
第一个参数为返回 promise 的函数列表,第二个参数为并发个数,函数返回 Promise 对象。
-
小程序 url 生成限制。如果你想设置多个参数到二维码的 url 上,以下的调用是不行的:
-
response = RestClient.post("https://api.weixin.qq.com/cgi-bin/wxaapp/createwxaqrcode?access_token=#{token}", {
path: "pages/affiliate/index?id=#{id}&#{code}",
width: 430
}.to_json)
扫码后的 url 中 & 符号会变为 %2C\u0026 (感觉是微信的 bug),解决办法是使用其它自定义分割符号,例如下划线 _, 然后在小程序代码里对其进行单独解析。
最后,开发本身对于小程序而言只能算是刚开始的一小步,由于微信的流量控制,后续的铺码之路任重道远。
以上,不希望对您有所帮助,因为小程序的开发实在不是一件可以让人愉悦的事:)
|