uni-app canvas组件在H5环境下效率非常低
uni-app canvas组件在H5环境下效率非常低
项目信息 | 详情 |
---|---|
产品分类 | uniapp/H5 |
PC开发环境操作系统 | Mac |
PC开发环境操作系统版本号 | 11.2.1 |
HBuilderX类型 | 正式 |
HBuilderX版本号 | 3.1.4 |
浏览器平台 | Chrome |
浏览器版本 | 88.0.4324.192 |
项目创建方式 | HBuilderX |
示例代码:
示例代码:
drawImageQueue(images, obj, done) {
//
console.log('打印图片', images);
let queue = [];
let self = this;
let ctx = this.getCanvasContext(obj);
let isClear = false;
if (typeof (images) === 'string') {
images = [images];
}
for (let img of images) {
if (img.length > 0) {
queue.push(img);
}
}
let doQueue = function () {
let src = null;
if (queue.length > 0) {
src = queue[0];
queue.splice(0, 1);
uni.getImageInfo({
src: src,
success(res) {
if (!isClear) {
isClear = true;
ctx.clearRect(0, 0, self.size.width, self.size.height);
}
ctx.drawImage(res.path, 0, 0, self.size.width, self.size.height)
if (queue.length > 0) {
doQueue();
} else {
ctx.draw(true,() => {
typeof (done) === 'function' && done.call();
});
}
},
fail(res) {
console.error('img fail', src,res);
if (queue.length > 0) {
doQueue();
} else {
ctx.draw(true,() => {
typeof (done) === 'function' && done.call();
});
}
}
});
}
}
doQueue();
},
使用console.time
+console.timeEnd
平均执行时间在200ms以上
function drawImage(images,done) {
console.log('打印图片', images);
var queue = [];
var isClear = false;
if (typeof (images) === 'string') {
images = [images];
}
for (var i = 0;i<images.length;i++) {
var img = images[i];
if (img.length > 0) {
queue.push(img);
}
}
var doQueue = function () {
var src = null;
if (queue.length > 0) {
src = queue[0];
queue.splice(0, 1);
getImage({
src: src,
success:function(res) {
console.log('res',res)
if (!isClear) {
isClear = true;
ctx.clearRect(0, 0, size.width, size.height);
}
ctx.drawImage(res.path[0], 0, 0, size.width, size.height)
if (queue.length > 0) {
doQueue();
} else {
typeof (done) === 'function' && done.call();
}
},
fail:function(res) {
console.error('img fail', src,res);
if (queue.length > 0) {
doQueue();
} else {
typeof (done) === 'function' && done.call();
}
}
});
}
}
doQueue();
}
function getImage(opt) {
var img = new Image(1920,1080);
img.src = opt.src;
img.onload = opt.success;
img.oncompvare = opt.success;
}
使用console.time
+console.timeEnd
平均执行时间在60ms以内
图片使用同样的地址。使用的本机图片,加载耗时不超过5ms
### 操作步骤:
#### 操作步骤:
```javascript
drawImageQueue(images, obj, done) {
//
console.log('打印图片', images);
let queue = [];
let self = this;
let ctx = this.getCanvasContext(obj);
let isClear = false;
if (typeof (images) === 'string') {
images = [images];
}
for (let img of images) {
if (img.length > 0) {
queue.push(img);
}
}
let doQueue = function () {
let src = null;
if (queue.length > 0) {
src = queue[0];
queue.splice(0, 1);
uni.getImageInfo({
src: src,
success(res) {
if (!isClear) {
isClear = true;
ctx.clearRect(0, 0, self.size.width, self.size.height);
}
ctx.drawImage(res.path, 0, 0, self.size.width, self.size.height)
if (queue.length > 0) {
doQueue();
} else {
ctx.draw(true,() => {
typeof (done) === 'function' && done.call();
});
}
},
fail(res) {
console.error('img fail', src,res);
if (queue.length > 0) {
doQueue();
} else {
ctx.draw(true,() => {
typeof (done) === 'function' && done.call();
});
}
}
});
}
}
doQueue();
},
### 预期结果:
#### 预期结果:
无
### 实际结果:
#### 实际结果:
无
### bug描述:
#### bug描述:
绘制多张图片到画布上的过程中,
使用uni-app的 `drawImage+draw` 相比原生H5中使用`drawImage`的方式,
执行效率相差非常大
这个版本还存在图片base64后如果里面有rpx 或upx 时,会导致base64的值错误。
更多关于uni-app canvas组件在H5环境下效率非常低的实战教程也可以访问 https://www.itying.com/category-93-b0.html
你是说drawImage使用 base64 的时候包含 rpx 会报错吗?
更多关于uni-app canvas组件在H5环境下效率非常低的实战教程也可以访问 https://www.itying.com/category-93-b0.html
我现在使用的 3.1.4.20210305 还是有这个问题。 是在从canvas里获取图片转为base64 到外面的image中使用时,如果内容里含有 rpx 还是会导致图片无法显示, 只能使用img标签来处理。 image组件 中的img标签是可以显示图片的, 但是同级的div中背景图片无法显示,导致空白
在H5环境下,uni-app的Canvas性能问题主要源于其API封装机制。uni.getImageInfo()和ctx.draw()涉及跨层通信和额外的数据序列化开销,这显著增加了执行时间。
原生H5的Image对象直接加载图片并绘制到Canvas上,整个过程在浏览器渲染线程内完成,效率更高。而uni-app的API需要经过框架桥接,每次调用都涉及JavaScript与原生层的交互,特别是在连续绘制多张图片时,这种开销会被放大。
建议在H5场景下,如果对性能要求较高,可以直接使用原生Canvas API。uni-app支持条件编译,可以在H5平台使用原生代码,其他平台继续使用uni-app API:
// #ifdef H5
// 使用原生Canvas API
// #endif
// #ifndef H5
// 使用uni-app API
// #endif