我正在研究图形前端,该前端通过将压缩图像发送到客户端(想想VNC)来呈现服务器端并将屏幕更新推送到浏览器。我已经决定对PNG进行编码的开销过高,因此目前我正在通过网络套接字(启用压缩)发送8位RGB像素值的原始Blob。这实际上非常快,我看到了很大的压缩增益(例如75K-> 2.7k)。
但是,在客户端上,我必须获取原始像素,然后将其绘制到画布上。这是我目前最好的代码性能:
// receive message from server
self.ws.onmessage = function (evt) {
// get image offset
var dv = new DataView(evt.data);
var dx = dv.getInt16(0);
var dy = dv.getInt16(2);
var ww = dv.getInt16(4);
var hh = dv.getInt16(6);
var offset = 8;
// get context to canvas and create image
var ctx = self.canvas.getContext("2d");
var img = ctx.createImageData(ww, hh);
// unpack image data
var start = performance.now();
var dst = 0, src = offset;
for (var ii=0; ii < ww*hh; ii++) {
img.data[dst++] = dv.getUint8(src++);
img.data[dst++] = dv.getUint8(src++);
img.data[dst++] = dv.getUint8(src++);
img.data[dst++] = 255;
}
// draw image
ctx.putImageData(img, dx, dy, 0, 0, ww, hh);
var end = performance.now();
console.log("draw took " + (end-start) + " milliseconds");
上述75K图像(1000x500像素)以这种方式渲染需要约53ms的时间,这是很长的时间。进行绘制操作的最快方法是什么?我可以输出RGBA像素,而不是那样,使生活更轻松。
编辑:似乎这可能更多是Firefox的问题,Chrome浏览器平均运行该解码循环的时间约为2.5ms。
编辑第二个:
切换到完整的RGBA输出(由于压缩,不会增加太多开销),并使用以下代码直接包装websocket缓冲区要快得多:
// receive message from server
self.ws.onmessage = function (evt) {
// get image offset
var dv = new DataView(evt.data);
var dx = dv.getInt16(0);
var dy = dv.getInt16(2);
var ww = dv.getInt16(4);
var hh = dv.getInt16(6);
// get context to canvas and create image
var ctx = self.canvas.getContext("2d");
// draw image data
var start = performance.now();
ctx.putImageData(
new ImageData(new Uint8ClampedArray(evt.data, 8), ww, hh),
dx, dy,
0, 0,
ww, hh
);
var end = performance.now();
console.log("draw took " + (end-start) + " milliseconds");
}
现在,在Firefox中渲染大图像需要大约1ms的时间,而在Chrome中则需要350us。足够好了。
答案 0 :(得分:1)
切换到完整的RGBA输出(由于压缩,不会增加太多开销),并使用以下代码直接包装websocket缓冲区要快得多:
describe('test', () => {
it('test', () => {
// page one. Register 1 beforeunload event, and prevent the unload event.
// -------------------------------------------------------------------------
cy.visit('/a');
cy.window().then( window => {
window.addEventListener('beforeunload', () => {
return 'one';
});
});
// redirect to page two. Assert a prevented unload event.
// Register another, but don't prevent unload.
// -------------------------------------------------------------------------
cy.visit('/b');
cy.assertBeforeUnload( ret => {
expect(ret).to.eq('one');
});
cy.window().then( window => {
// register, but don't prevent
window.onbeforeunload = () => {};
});
// page three. Assert a non-prevented unload event. Register none.
// -------------------------------------------------------------------------
cy.visit('/c');
cy.assertBeforeUnload( ret => {
// assert an event fired, but returned nothing (indicated by `null`)
expect(ret).to.eq(null);
});
// page four. Assert no beforeunload event was fired.
// -------------------------------------------------------------------------
cy.visit('/d');
cy.assertBeforeUnload( ret => {
expect(ret).to.eq(undefined);
});
});
});
现在,在Firefox中渲染大图像需要大约1ms的时间,而在Chrome中则需要350us。足够好了。