Some optimizations I've done in display.js I would like to share

41 views
Skip to first unread message

Peter Hebels

unread,
Mar 21, 2024, 3:01:54 PMMar 21
to noVNC
I'm use noVNC for a long time now and it performs great in my opinion. I only had some slowdowns on high resolutions; using 1920x1080 for example would cause noticeable hickups when displaying complex graphics, moving images or video's.

I found out that the use of base64 encoded data in an img src attrib was causing this and made some changes so that the whole encoding and transfering to an img is gone.

I added this in the constructor:

        this._img_bitmap = null;
        this._bitmap_ready = true;

I changed these lines in the imageRect function:

        const img = new Image();
        img.src = "data: " + mime + ";base64," + Base64.encode(arr);

        this._renderQPush({
            'type': 'img',
            'img': img,
            'x': x,
            'y': y,
            'width': width,
            'height': height
        });

To:

        let img_blob = new Blob([arr], { type: mime });

        this._renderQPush({
            'type': 'img',
            'img': img_blob,
            'x': x,
            'y': y,
            'width': width,
            'height': height
        });

And changed this in _scanRenderQ:

                case 'img':
                    if (a.img.complete) {
                        if (a.img.width !== a.width || a.img.height !== a.height) {
                            Log.Error("Decoded image has incorrect dimensions. Got " +
                                      a.img.width + "x" + a.img.height + ". Expected " +
                                      a.width + "x" + a.height + ".");
                            return;
                        }
                        this.drawImage(a.img, a.x, a.y);
                    } else {
                        a.img._noVNCDisplay = this;
                        a.img.addEventListener('load', this._resumeRenderQ);
                        // We need to wait for this image to 'load'
                        // to keep things in-order
                        ready = false;
                    }
                    break;

To:

                case 'img':
                    if(this._img_bitmap !== null) {
                        this.drawImage(this._img_bitmap, a.x, a.y);
                        this._img_bitmap.close();
                        this._img_bitmap = null;
                        this._bitmap_ready = true;
                    }else{
                        if(this._bitmap_ready == true) {
                            this._bitmap_ready = false;
                            createImageBitmap(a.img).then(
                                imageBitmap => {
                                    this._img_bitmap = imageBitmap;
                                    this._scanRenderQ();
                                }
                            );
                        }
                        ready = false;
                    }
                    break;

I also added these hints to the visible and offscreen canvas:

        // the visible canvas viewport (i.e. what actually gets seen)
        this._targetCtx = this._target.getContext('2d', {
            alpha: false,
            antialias: false
        });


Curious what you think of it and if you got the same results. For me the most noticeable difference was in Firefox but also Edge and Chrome render graphics much smoother with these changes.

Pierre Ossman

unread,
Mar 22, 2024, 2:49:47 AMMar 22
to no...@googlegroups.com, Peter Hebels
On 21/03/2024 20:01, Peter Hebels wrote:
>
> Curious what you think of it and if you got the same results. For me the
> most noticeable difference was in Firefox but also Edge and Chrome render
> graphics much smoother with these changes.
>

We played around with this idea some time ago:

https://github.com/novnc/noVNC/pull/1131

At the time, Chrome had serious issues with this approach. We reported
the bug to them, but the bug is still open in their tracker.

But if you are seeing different results despite that, then it might be
worth revisiting the subject.

Regards,
--
Pierre Ossman Software Development
Cendio AB http://cendio.com
Teknikringen 8 http://twitter.com/ThinLinc
583 30 Linköping http://facebook.com/ThinLinc
Phone: +46-13-214600

A: Because it messes up the order in which people normally read text.
Q: Why is top-posting such a bad thing?

Peter Hebels

unread,
Mar 28, 2024, 8:47:26 AMMar 28
to noVNC
Thanks for your reply and the link to the pull, I was not aware of that and reinvented the wheel... Because I also did some other changes as will on display.js I've shared a gist via Github containing my changes. For example, I also changed the blit operation to use createImageBitmap.

Op vrijdag 22 maart 2024 om 06:49:47 UTC schreef oss...@cendio.com:
Reply all
Reply to author
Forward
0 new messages