- 微信小程序性能优化入门指南(转载)
原文地址:https://segmentfault.com/a/1190000016901634 小程序从发布到现在也已经有将近两年的时间,越来越来多的公司开始重视小程序生态带来的流量,今年也由于小程序平台对外能力的越来越多的开放以及小程序平台的自身优化,越来越多的开发者也自主的投入到小程序的开发当中,现在,作为前端如果会写小程序,绝对是一个不折不扣的面试加分项。 相信不少人刚接触小程序时的感觉大都是小程序很简单,开发只要是会写html、css、js就可以了,但是当自己的第一个小程序开发完成上线时,却发现小程序体验非常糟糕,接下来就让我们一窥小程序优化之道。 加载流程要想给小程序做优化,对小程序的加载流程一定要有一定的了解,小程序是怎么加载的,让我们先来看一个图片: [图片] 这三个图片大家一定都不陌生,当你打开一个小程序的时候就会经历这三个过程: 资源准备,这个过程就是小程序在下载你的代码包的过程业务代码注入和渲染,这个过程就是小程序将的业务代码分别注入视图层和逻辑层,并在视图层做视图的渲染异步数据的请求,显示加载中的时候,其实就是在到达首页时,如果首页有异步数据请求,这个时候小程序就会执行异步数据请求上述就是对小程序的启动过程的一个简单概述,让我们再来看一个更加具体一点的图片,可能会更好理解小程序启动过程: [图片] 从这个图片可以看到,小程序在启动加载的时候,其实分为两部分,一部分是逻辑层的启动启动,另一部分是视图层的启动,逻辑层的启动就是加载小程序的js代码,视图层的启动webview对页面进行加载和渲染,那预加载又是什么时候执行的呢?其实在微信动的时候,小程序平台就开始静默执行与加载的过程,包括JS引擎初始化和WebView的初始化,然后会注入小程序自带的公共库,例如自带api、组件等,后面的小程序启动,就是上面说过的打开一个小程序具体的启动加载过程了,下载代码包,分别注入逻辑层和视图层,然后共同完成首屏渲染。 启动性能优化讲完小程序的启动过程,就可以开始介绍具体的性能优化方案了,让我们一起看看影响小程序性能的因素以及具体的解决办法 代码包大小代码包大小会直接影响小程序的启动速度,代码包越大,小程序的启动时间就越长,在小程序启动时,下载代码包和代码注入的时间和小程序代码包大小是成正比的,一般小程序的平均启动时间是2s左右,可以看看你的小程序有没有拖后腿,那么如何控制包大小呢? 资源控制开启开发工具”上传代码时自动压缩”,小程序开发工具有一个上传代码时自动压缩的功能,当开启时,会在你上传代码时为你做代码压缩,除了这个,我们也可以通过使用第三方打包工具做代码压缩,如webpack、grunt、grulp。及时清理无用代码和资源文件,无用的代码和资源也会占用一定的包大小。减少代码包中的资源文件,将资源存放在cdn上,小程序开发工具对资源文件的压缩比率非常低,资源有条件的可以尽量放在CDN上,因为小程序开发工具对资源文件的压缩比率非常低,只有10%左右,或者也可以用第三编译工具对资源文件自己进行压缩处理分包加载[图片] 分包加载是小程序提高加载启动性能的一个重要方法,如果有人还不了解,可以点开链接看官方介绍,那么如何做好分包加载呢? 将小程序中不常用的代码放在分包中,主包内只保留用户最常访问的页面,但是由于官方规定tab页面只能放在主包中,因为小程序启动时只会加载主包,使用时按需下载分包,不会在加载时一次将整个代码包下载,这样就能有效减少启动加载的时间。 但是分包加载也有它的局限性,用户首次打开分包页面时,需要先进行分包代码的加载和注入,会造成页面切换时产生一定的延时,因此在此基础上,官方又推出了分包预加载和独立分包。 分包预加载先来看一下之前分包加载时的流程是怎样的: [图片] 那么分包预加载是怎么干的呢?分包预下载:提前配置可能会跳到哪些分包,框架在进入页面后根据配置进行预下载,分包预加载会在你进入主包页面后,为你静默开启分包代码的下载和注入,这个过程是无感的,来看一下分包预加载的流程是怎样的: [图片] 分包预加载需要注意的是:同一个分包中的页面享有共同的预下载大小限额2M,限额会在工具中打包时校验,因此不能把所有的分包页面都配置到分包预加载的配置中,只配置主包页面会跳转的页面即可。 独立分包独立分包又是什么呢?由于从分包页面启动是,必须要依赖于主包的下载和注入,启动速度会受到主包大小的制约,因此这就有了独立分包,独立分包在启动分包页面时,可以独立启动而不需要依赖主包,这样就可以减少主包下载和注入的时间,通常情况下我们会将活动、广告一类的具有独立逻辑的功能代码标记为一个独立分包,在分包页面启动时,可以不依赖于主包启动,只下载分包代码进行注入。让我们来看一下独立分包的加载流程是怎样的: [图片] 首屏加载性能优化首屏加载的体验对小程序来说十分重要,那么如何提升首屏加载性能呢? 提前请求:异步数据数据请求不需要等待页面渲染完成利用缓存:利用storage API对异步请求数据进行缓存,二次启动时先利用缓存数据渲染页面,再进行后台更新避免白屏:先展示页面骨架和基础内容及时反馈:及时地对需要用户等待的交互操作给出反馈,避免用户以为小程序没有响应渲染性能优化要想提高渲染性能,就需要知道小程序如何做页面渲染的,让我们先来看一个页面渲染的流程图: [图片] js引擎和native都可以过js的计算或者data修改来对Webview发起绘制操作,但是对开发者来说最重要的就是js引擎和Webview之间的通信,这通信过程是一个跨进程通信,是非常耗时的一个过程,我们要提高渲染的性能,也就是减少这个跨进程通信的时间,那么怎么去减少跨进程通信的时间呢? 避免不当使用setData使用data在方法间共享数据,会增加setData传输的数据量,同时会增加页面重绘的概率data仅包括与页面相关的数据使用setData传输大量数据,通讯耗时与数据量正相关,页面更新延迟可能造成更新开销增加仅传输页面中发生变化的数据,使用setData的特殊key实现局部更新后台页面进行setData抢占前台页面的资源页面切入后台后的setData调用,延迟到页面重新展示的时候执行总结来说就是在data中只定义与页面渲染相关的数据,其他与页面渲染无关的数据都定义成普通变量,在做setData操作时,尽量只传输页面渲染需要的数据,当页面切换时,将后台执行的setData操作销毁,等到页面重新展示的时候再执行。 避免不当使用onPageScroll只在必要的时候监听pageScroll事件避免在onPageScroll中执行复杂逻辑避免在onPageSroll中频繁调用setData避免频繁查询节点信息(SelectQuery),部分场景使用节点布局相交状态监听(IntersectionObserver)替代由于onPageSroll事件监听在处理js引擎和webview之间的通信时也是一个跨进程通信,因此在使用onPageScroll事件时,要注意以上的几点内容,来进行相关的优化 使用自定义事件在需要频繁更新的场景下,自定组件的更新只在组件内部更新,不受页面其他部分内容复杂性影响,这样也可以在一定程度优化渲染性能 总结这篇文章简单的介绍了微信小程序性能优化的一些方法,还有很多我没有介绍到方法就需要大家自己去探索总结了。希望大家看完这篇文章能对小程序性能优化有一定的认识,如果有错误或不严谨的地方,欢迎批评指正,如果喜欢,欢迎点赞收藏。
2021-09-23 - 不定时出现css过渡动画失效或卡顿掉帧
ios微信浏览h5页面执行一段时间后,css3的动画,有时会出现transition过渡效果丢失或明显卡顿掉帧的问题。 比如3秒的css动画,没有过渡效果直接跳到结束动画,或者动画非常卡顿掉帧。 后台关闭微信进程后,重新打开微信浏览页面,动画恢复正常,但是过一阵可能又会出现。
2021-05-18 - 云开发实战:小程序导出Ecxcl表格功能
需求 作为信息收集者需要把用户填写的内容,用Ecxcl表格的方式导出。可以支持在线查看或者复制文件下载链接。 [图片] 查看 excle 表格可以直接在手机上查看表格 复制下载地址可以通过链接在电脑上下载 实现 以收集姓名信息为例: 云函数代码 [代码]// 云函数入口文件 const cloud = require('wx-server-sdk') cloud.init() //操作excel用的类库 const xlsx = require('node-xlsx'); // 云函数入口函数 exports.main = async (event, context) => { try { let { dataList, excelName } = event // 1. 定义excel表格名 let dataCVS = 'test.xlsx' // 2. 定义存储数据的 let alldata = []; // 3. 定义表头 let row = ['姓名']; alldata.push(row); // 4. 循环取出姓名数据 for (let key in dataList) { let arr = []; arr.push(applyList[key].name); alldata.push(arr) } //5. 把数据保存到excel里 var buffer = await xlsx.build([{ name: "mySheetName", data: alldata }]); //6. 把excel文件保存到云存储里 return await cloud.uploadFile({ cloudPath: excelName + ".xlsx", fileContent: buffer, }) } catch (e) { console.error(e) return e } } [代码] 注意上传部署云函数的时候需要先安装[代码]node-xlsx[代码] 安装步骤: 打开命令行 [图片] 输入安装命令:[代码]npm install node-xlsx --save[代码] 小程序调用代码 通用调用云函数生成表格代码部分 [代码]createExcel(type) { // 提示加载中 wx.showLoading({ title: '正在加载中...', }) console.log('请求获取') let data = { dataList: 姓名数据集合, excelName: 文件名 } // 生成excel并存储 wx.cloud.callFunction({ name: 'excel', data: data }).then(res => { // 获取存储文件ID this.getFileUrl(res.result.fileID,type) }) } [代码] 根据不同的type来实现不同的功能 2.1 type为0时查看excel 2.2 type为1时复制地址 [代码] getFileUrl(fileID, type) { let that = this; wx.cloud.getTempFileURL({ fileList: [fileID], success: res => { // get temp file URL that.setData({ fileUrl: res.fileList[0].tempFileURL }) // 下载文件并且打开文档 if (type == 0) { wx.downloadFile({ url: res.fileList[0].tempFileURL, success: function (res) { const filePath = res.tempFilePath wx.openDocument({ filePath: filePath }) } }) } else if (type == 1) { // 复制地址 wx.setClipboardData({ data: res.fileList[0].tempFileURL }) } } }) }, [代码] 扩展阅读 以上涉及到的API文档地址: node-xlsx wx.setClipboardData wx.uploadFile wx.downloadFile wx.openDocument
2021-02-25 - 群名称,已经获取到openGid但是前端页面,有部分群名称不显示?
组件名称:open-data(type="groupName"); 微信版本:8.0.6; 基础库:2.17.0; 手机型号:iOS14.5.1; 问题描述:群名称,已经获取到openGid但是前端页面,有部分群名称不显示? [图片]
2021-05-18 - 小程序中图片二维码、小程序码,长按识别支持的情况
因为看到最近还有人刷到这篇文章还有收藏的,所以特别说明一下: 以下是2021年5月31日时候测试的结果,并不一定与现在的情况相符。现在啥情况,我也不知道,已经不咋做小程序了。所以大家实际使用时候,请大家还是再测测。 上面这段话更新于2021年10月11日 下面是原文 ==================================================================================================================== 最近小程序中的图片支持长按识别了,总结一下几种情况下: 测试时间:2021-5-31 微信版本:8.0.6 当前时间最新 image标签 + show long press menu <image src="https://img.qr.com/qr.jpg" style="width: 100%;" mode="widthFix" show-menu-by-longpress="{{true}}"></image> ✅ 识别小程序码 - ✅ 跳转小程序 ✅ 识别群二维码 - ❌ 跳转到加群页面 ✅ 识别名片二维码 - ❌ 跳转到加好友页面 ❌ 识别小程序二维码 wx.previewImage ✅ 识别小程序码 - ✅ 跳转小程序 ✅ 识别群二维码 - ✅ 跳转到加群页面 ✅ 识别名片二维码 - ✅ 跳转到加好友页面 ❌ 识别小程序二维码 web-view ✅ 识别小程序码 - ✅ 跳转小程序 ✅ 识别群二维码 - ✅ 跳转到加群页面 ✅ 识别名片二维码 - ✅ 跳转到加好友页面 ❌ 识别小程序二维码 总结,目前微信已经开放了在小程序中长按识别。但是似乎还有一些bug,image标签可以识别到,但是点了没反应。
2021-10-11 - 云开发控制台已显示绑定了当前环境,但仍提示需要开通小程序云开发,并且也无法开通成功
云开发控制台已显示绑定了当前环境,但仍提示需要开通小程序云开发,并且也无法开通成功 [图片] [图片] 另一方面,在腾讯云的控制台中,似乎云环境已经准备就绪 [图片] [图片] 小程序相关联的公众平台也是同一个 [图片] [图片] 腾讯云关联的微信账号与登录微信公众平台的微信账号也是同一个。 今天该公众平台曾经从以下账号中解绑 [图片] [图片] 不知是什么问题导致无法在 微信开发者工具 中连接云环境并且使用?
2021-03-31 - 如何使用cloudbase-cli来管理(未开通腾讯云账号的)小程序云函数?
如果开通了腾讯云账户的话是可以在腾讯云的cloudbase中看见小程序的云环境,也可以方便的使用cloudbase-cli来自动化构建推送git修改后的云函数。 但是现在客户的小程序,只开通了小程序账户,而没有腾讯云账户。这种情况下不知道怎么使用cloudbase-cli工具来实现自动化构建。 是不是没有腾讯云账户的话只能在小程序开发者工具中管理云函数?
2020-11-09 - 非常简单的长列表(无限上拉触底加载 onReachBottom)实现方案
我们知道小程序针对长列表有两个硬杠杠,一旦越界直接给白屏: 1、setData的数组数据不能超过1M。 2、DOM数不能太多,具体数据未知。 官方这样处理也不无道理,太长了本身性能确实也有问题。所以长列表一定要人为干预处理,不处理一直上拉加载肯定是不行的。 目前主流的处理方法有三种: 1、二维数组,就是把数据改为二维的,每一个分页数据作为一个一维数组的元素。这样处理,只解决了setData的问题,DOM的问题并未解决。并且把本来是一维的数据强行二维化,在很多逻辑处理上变得复杂。 2、官方提供了一个扩展组件recycle-view,但它要求item等高,存在局限性。https://developers.weixin.qq.com/miniprogram/dev/extended/component-plus/recycle-view.html 3、自行搭建骨架屏,类似于方案2的自研版本,根据自己的实际需要编写代码。实现成本非常高。 实现方案如下(太简单了,不提供代码示例): 1、思路:只保留最新的n页数据进行setData,每新加载一页数据,就舍弃最前面一页的数据。同时把第1页的数据保存起来,监听onPageScroll,如果发现用户拉回到了页面顶部,则舍弃所有数据,把第1页的数据setData回来。 2、举个例子:假设n=5,那么当加载了第6页数据时,第6页数据合并到数组尾部,把数组头部的第1页数据去掉,让setData的数据始终保持5页。这里有个细节要处理好,就是去除数据的时候先setData一次,新数据加载合并后,再setData一次,这样可以保证用户的scrollTop不会走位,停留在最新一条数据那个位置。 3、这个方案也存在一些弊端,看你实际项目中能否接受,主要有两个问题:a、用户如果倒着往回逐条浏览,体验是不连续的,因为中间一段我们已经舍弃掉了,如果拉到页面顶部时,将会出现直接回到第一条数据。b、去除数据的setData操作时,存在一定程度的闪屏现象。(针对问题a,应该可以解决,无非就是把数据再逐页塞回来,而不是像我的方案简单粗暴的回到第一页数据,如果项目有需要可以自行尝试。) 4、适用范围:比较适合信息处理类应用,比如后台管理系统。这类应用,往往头几屏内容就能找到信息,或者借助搜索,比较少会拉很多屏。而且往往处理完毕时是直接回到顶部的,不会逐条翻回去。所以这类应用只要保证不出白屏,一些小概率场景下存在一些几乎可以忽略的体验小瑕疵可以接受。信息浏览类应用,比如新闻应用,往往都是长列表浏览,小瑕疵就不一定能接受。
2020-10-28 - 教你怎么监听小程序的返回键
更新:2020年7月28日08:51:11 基础库2.12.0起,可以调用wx.enableAlertBeforeUnload监听原生右上角返回、物理返回以及wx.navigateBack时弹框提示 AIP详情请看: https://developers.weixin.qq.com/miniprogram/dev/api/ui/interaction/wx.enableAlertBeforeUnload.html //======================================== 怎么监听小程序的返回键? 应该有很多人想要监听用户的这个动作吧,但是很遗憾,小程序不会给你这个API的,那是不是就没辙了? 幸好我们还可以自定义导航栏,这样一来我们就可以监听用户的这一动作了。 什么?这你已经知道啦? 那好咱们就不说自定义导航栏的返回监听了,说一下物理返回和左滑?右滑?(不管了,反正是滑)返回上一页怎么监听。 监听物理返回 首先说一下这个监听方法的缺点,虽说是监听,但是还是无法真正意义上的监听并拦截来阻止页面跳转,页面还是会返回上一页,而后重新载入刚刚的页面,如果这不是你想要的,那可以不用往下看了 其次说一下用到什么东西: wx.onAppRoute、wx.showModal 最后是一些主要代码: 重写wx.showModal,主要是加个confirmStay参数和使wx.showModal Promise化 [代码]const { showModal } = wx; Object.defineProperty(wx, 'showModal', { configurable: false, // 是否可以配置 enumerable: false, // 是否可迭代 writable: false, // 是否可重写 value(...param) { return new Promise(function (rs, rj) { let { success, fail, complete, confirmStay } = param[0] param[0].success = (res) => { res.navBack = (res.confirm && !confirmStay) || (res.cancel && confirmStay) wx.setStorageSync('showBackModal', !res.navBack) success && success(res) rs(res) } param[0].fail = (res) => { fail && fail(res) rj(res) } param[0].complete = (res) => { complete && complete(res) (res.confirm || res.cancel) ? rs(res) : rj(res) } return showModal.apply(this, param); // 原样移交函数参数和this }.bind(this)) } }); [代码] 使用wx.onAppRoute实现返回原来的页面 [代码]wx.onAppRoute(function (res) { var a = getApp(), ps = getCurrentPages(), t = ps[ps.length - 1], b = a && a.globalData && a.globalData.pageBeforeBacks || {}, c = a && a.globalData && a.globalData.lastPage || {} if (res.openType == 'navigateBack') { var showBackModal = wx.getStorageSync('showBackModal') if (c.route && showBackModal && typeof b[c.route] == 'function') { wx.navigateTo({ url: '/' + c.route + '?useCache=1', }) b[c.route]().then(res => { if (res.navBack){ a.globalData.pageBeforeBacks = {} wx.navigateBack({ delta: 1 }) } }) } } else if (res.openType == 'navigateTo' || res.openType == 'redirectTo') { if (!a.hasOwnProperty('globalData')) a.globalData = {} if (!a.globalData.hasOwnProperty('lastPage')) a.globalData.lastPage = {} if (!a.globalData.hasOwnProperty('pageBeforeBacks')) a.globalData.pageBeforeBacks = {} if (ps.length >= 2 && t.onBeforeBack && typeof t.onBeforeBack == 'function') { let { onUnload } = t wx.setStorageSync('showBackModal', !0) t.onUnload = function () { a.globalData.lastPage = { route: t.route, data: t.data } onUnload() } } t.onBeforeBack && typeof t.onBeforeBack == 'function' && (a.globalData.pageBeforeBacks[t.route] = t.onBeforeBack) } }) [代码] 改造Page [代码]const myPage = Page Page = function(e){ let { onLoad, onShow, onUnload } = e e.onLoad = (() => { return function (res) { this.app = getApp() this.app.globalData = this.app.globalData || {} let reinit = () => { if (this.app.globalData.lastPage && this.app.globalData.lastPage.route == this.route) { this.app.globalData.lastPage.data && this.setData(this.app.globalData.lastPage.data) Object.assign(this, this.app.globalData.lastPage.syncProps || {}) } } this.useCache = res.useCache res.useCache ? reinit() : (onLoad && onLoad.call(this, res)) } })() e.onShow = (() => { return function (res) { !this.useCache && onShow && onShow.call(this, res) } })() e.onUnload = (() => { return function (res) { this.app.globalData = Object.assign(this.app.globalData || {}, { lastPage: this }) onUnload && onUnload.call(this, res) } })() return myPage.call(this, e) } [代码] 在需要监听的页面加个onBeforeBack方法,方法返回Promise化的wx.showModal [代码]onBeforeBack: function () { return wx.showModal({ title: '提示', content: '信息尚未保存,确定要返回吗?', confirmStay: !1 //结合content意思,点击确定按钮,是否留在原来页面,confirmStay默认false }) } [代码] 运行测试,Oj8K 是不是很简单,马上去试试水吧,效果图就不放了,静态图也看不出效果,动态图懒得弄,想看效果的自己运行代码片段吧 代码片段 https://developers.weixin.qq.com/s/hc2tyrmw79hg
2020-07-28 - 云开发之图片压缩裁剪(CloudBase图像处理扩展实战)
1、大约半年前在论坛里寻求云开发后端图片处理方案无果,无奈退而求其次使用小程序端canvas做图片处理: https://developers.weixin.qq.com/community/develop/doc/000c00a3d74758caca2a2b3ef5b400 (寻求方案发帖) 2、canvas做图片处理,代码量比较大,对手机性能要求比较高,而且如果一次处理图片多,还会偶现各种奇怪的不稳定问题。 3、最近iPhone微信更新到7.0.20更是直接不能使用了: https://developers.weixin.qq.com/community/develop/doc/000cc4b48a4378003b7b2f97d51400 (bug反馈发帖) 4、更换图片处理的方案刻不容缓,上次云开发峰会上陈宇明大佬分享案例中提到一嘴CloudBase的相关支持,于是翻到了相关文章,一步步跟着操作,在此感谢大佬指路: https://developers.weixin.qq.com/community/develop/article/doc/0004ec150708d0b57d5bd532a53413 (大佬文章) https://cloud.tencent.com/document/product/876/42103 (开发指南) 5、本人电商项目中有多处图片处理需求,比较典型的一个业务是上传商品主图,当用户任意上传一个图片后,自动居中裁剪生成一大一小两张正方形的图,大的用在详情页,小的用在列表页。CloudBase支持两种方式:获取图片时处理、持久化图像处理。本人业务采用后者。 6、代码示例: 小程序端选择图片,上传到云存储 wx.chooseImage({ count: 1, sizeType: ['compressed'], sourceType: ['album', 'camera'], success: res => { const tempFilePaths = res.tempFilePaths const tempFile = tempFilePaths[0] let pictureLarge = tempFile let fileName = pictureLarge.split('.') let format = fileName[fileName.length -1] let cloudPath = 'products/sellerId/original-' + (new Date()).valueOf() + (format.length < 5 ? '.' + format : '') wx.cloud.uploadFile({ cloudPath: cloudPath, filePath: pictureLarge, success: res => { const pictureOrignial = res.fileID wx.cloud.callFunction({ name: 'addProduct', data: { operation: 'addPicture', pictureOrignial, cloudPath } }).then(res => { if (res.result.errCode) { wx.showModal({ title: '主图处理失败', content: res.result.errMsg, showCancel: false, confirmColor: '#67ACEB' }) } else { //拿到云文件ID做后续处理 res.result.picture } }).catch(err => { console.error(err) wx.showModal({ title: '主图处理失败', content: '主图处理失败,请重试', showCancel: false, confirmColor: '#67ACEB' }) }) }, fail: err => { console.error(err) wx.showModal({ title: '主图上传失败', content: '主图上传失败,请重试', showCancel: false, confirmColor: '#67ACEB' }) } }) } }) 云函数端处理图片,先放大到最小边大于1125px,再分别裁剪出1125px和258px的两张图,存到同一目录下,返回云文件ID 先安装包: npm install --save @cloudbase/extension-ci@latest 云函数: // 云函数入口文件 const cloud = require('wx-server-sdk') const extCi = require("@cloudbase/extension-ci") const tcb = require("tcb-admin-node") cloud.init({ env: cloud.DYNAMIC_CURRENT_ENV }) tcb.init({ env: cloud.DYNAMIC_CURRENT_ENV }) tcb.registerExtension(extCi) // 云函数入口函数 exports.main = async (event) => { const wxContext = cloud.getWXContext() if (event.operation == 'addPicture') { return await addPicture(event.pictureOrignial, event.cloudPath) } else { } } async function addPicture(pictureOrignial, cloudPath) { //process picture const res = await process(cloudPath) if (res.errCode !== 0) { return { errCode: 100, errMsg: '商品主图处理失败' } } else { const pictureIDLarge = pictureOrignial.replace(/original/, 'large') const pictureID = pictureOrignial.replace(/original/, 'normal') return { errCode: 0, picture: { pictureIDLarge, pictureID } } } } async function process(cloudPath) { try { const opts = { //scale to 1125 rules: [ { fileid: '/' + cloudPath, // 处理结果的文件路径,如以’/’开头,则存入指定文件夹中,否则,存入原图文件存储的同目录 rule: "imageMogr2/thumbnail/!1125x1125r" // 处理样式参数,与下载时处理图像在url拼接的参数一致 } ] } await tcb.invokeExtension("CloudInfinite", { action: "ImageProcess", cloudPath: cloudPath, // 图像在云存储中的路径,与tcb.uploadFile中一致 operations: opts }) } catch (err) { return JSON.stringify(err, null, 4) } try { const opts = { rules: [ //crop large { fileid: '/' + cloudPath.replace(/original/, 'large'), rule: "imageView2/1/w/1125/h/1125/q/85" }, //crop normal { fileid: '/' + cloudPath.replace(/original/, 'normal'), rule: "imageView2/1/w/258/h/258/q/85" } ] } await tcb.invokeExtension("CloudInfinite", { action: "ImageProcess", cloudPath: cloudPath, // 图像在云存储中的路径,与tcb.uploadFile中一致 operations: opts }) } catch (err) { return JSON.stringify(err, null, 4) } return { "errCode": 0, "errMsg": "ok" } }
2022-04-26 - 微信小程序新能力:URL Scheme,可从短信跳转小程序
最近小程序上线了一个超级流量的新入口:URL Scheme。通过小程序页面的URL Scheme,可以在短信、邮件或微信外部的网页中打开小程序。 那么如何实现呢?官方文档已经写的很清楚啦,这里简单介绍一下。 首先,获取URL Scheme,通过服务端接口可以获取打开小程序任意页面的URL Scheme,支持生成到期失效和永久有效的URL Scheme。 [图片] 然后,通过短信群发平台将获取的URL Scheme + 营销文案发送到用户的手机上。 最后,用户收到短信后,直接点击URL Scheme唤起微信,跳转到对应小程序页面,就是这么简单。 除此之外,还可以通过邮件或外部浏览器打开跳转小程序。 由于部分操作系统仍不支持直接识别URL Scheme,因此直接将Scheme发送给用户可能存在无法打开小程序的情况。 为此,我们可以先准备一个H5页面,再从H5页面跳转到URL Scheme实现打开小程序。 [代码]location.href = 'weixin://dl/business/?ticket= *TICKET*' [代码] H5的示例代码我已经更新到Github,可以复用起来,基于官方的案例做了些改动,增加PC端打开时生成二维码方便手机扫码使用。 这次新能力的更新将使微信小程序不再局限于微信内部的流量,天花板被掀开啦。 而且短信和邮件营销的触达成本非常低,营销成本的压低也会催生出很多新的流量玩法,我们敬请期待吧。
2021-01-08