最近在做一个微信小程序,小程序首页是一个列出信息并附带图片的列表。
这种小图理所应当地应该使用缩略图,主要是为了节省流量。但是微信似乎并没有提供缩略图的功能,于是就只好加载全图。
后来就出了问题,起因是其中一个头像换了个体积很大的图片,但是还是在加载原图,结果导致整个页面卡顿异常,乃至出现黑块。这个问题本来也存在,就是在下拉加载的时候会出现撕裂,但没有这么严重。
一番分析之后认为是加载的图片过大导致的(怀疑微信小程序的性能,这才到哪儿就这样了),于是决定换成缩略图。
图片是存放在微信云服务的存储里面,微信小程序内部直接用的cloud://
链接加载图片,也没有找到小程序对缩略图的支持方法。如此一来,似乎只有自己生成缩略图这一条路。
正好在编写后台时,用到了batchDownloadFile
的接口,这个接口可以返回图片的外链,留意一下外链的格式:https://数字-云环境id-数字.tcb.qcloud.la/文件名
的格式,如果在控制台将权限设置为所有人可读,就可以直接拼接出外链。
再看一下404的返回内容:
<Error>
<Code>NoSuchKey</Code>
<Message>The specified key does not exist.</Message>
<Resource>xxxx-xxxxx-xxxxx.cos.ap-shanghai.myqcloud.com/2133</Resource>
<RequestId>NWY0YzcwMWJfNTQyZjIyMDlfNmMxZl82OTAxNzM5</RequestId>
<TraceId>OGVmYzZ************kMTBiOWVmMDAxODc0OWRkZjk0ZDM1NmI1M2E2MTRlY2Mreg*****************************4Njk***************************c=</TraceId>
</Error>
微信云服务的存储功能不过是用的腾讯云的COS对象存储,对象存储一般是提供图像处理功能的,于是找到COS的文档中的图片处理部分 https://cloud.tencent.com/document/product/436/44880 。测试一下,可以使用。
https://xxxxxxxx.tcb.qcloud.la/example.jpg?imageMogr2/thumbnail/162x162"
在微信小程序里加一步将cloud://
转换为外链的步骤就行了,这个可以使用wx.cloud.getTempFileURL
(Cloud.getTempFileURL
文档),也可以如前文所述自己拼接出来(需要所有人可读)。
示例:
查询操作blabla.....
.then(({list})=>{
return list.map((item)=>{
/**
* 因为之前直接加载完整图片,影响页面性能,浪费流量
* cloud:// 格式的链接不能生成缩略图,将其转换成COS(腾讯的对象存储服务)的链接之后,
* 加上参数得到缩略图
*/
let filename = item.icon
item.icon = 'https://数字-云环境id-数字.tcb.qcloud.la/' + filename + `?imageMogr2/thumbnail/125x125`
return item
})
})
关于数字-云环境id-数字
,在微信开发者工具-云开发控制台-存储,随便找一个文件右键详情,在“下载地址”中就可以看到。
缩略图的大小如何选择呢?一般设个128x128这样差不多的数字就行了。最好的办法是根据不同屏幕进行适配。微信中常用的单位是rpx,图片的大小是px,需要先进行转换,可以用wx.getSystemInfo
(wx.getSystemInfo
文档)来获得屏幕分辨率信息,然后根据信息进行转换:
rpx是将所有设备得宽度都视为750,用windowWidth除以750得到px,再乘以像素比,得到物理像素。
/**
* 返回rpx和px的对应关系
* 这里的px是设备物理像素
*/
function getRpx2px(){
return new Promise((resolve, reject)=>{
wx.getSystemInfo({
success: (result) => {
// 物理像素 = 窗口宽度/750 * 像素比
resolve(result.windowWidth/750*result.pixelRatio)
},
fail: (msg)=>{
reject(msg)
}
})
})
}
这样我们就能得到rpx和物理像素的比例,将这个比例乘以小程序中图片的rpx尺寸,就可以得到物理尺寸
let rpx2px = await getRpx2px()
let px = Math.ceil(108 * rpx2px) // 图片设置为108rpx
// 拼接url
item.icon = 'https://xxxxxxx.tcb.qcloud.la/' + filename + `?imageMogr2/thumbnail/${px}x${px}`
如此,列表加载流畅。