Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve cache handling in blur filter #4792

Closed
wants to merge 2 commits into from

Conversation

danxuliu
Copy link
Member

@danxuliu danxuliu commented Dec 17, 2020

Fixes #4827
Follow up to #4678

Instead of using an array as the cache now a LRU cache is used, which should prevent overflowing the cache.

Pending:

  • Make the cache global so the backgrounds are reused when switching between speaker mode and grid view (as VideoBackground is recreated in that case)

@danxuliu
Copy link
Member Author

/backport to stable20.1

@danxuliu
Copy link
Member Author

/backport to stable20

The blurred background images were cached directly in an array, so the
cache could grow without limits. Although it should be a rare case, this
could lead to a high memory consumption if the user slowly resizes
during a long time the browser window. Therefore the cache now uses a
least recently used cache limited to just five elements (so it can store
the blurred backgrounds when the sidebars are open or closed, plus
having a bit of room).

"node-lru-cache" was selected as the library to use due to being small,
widely used and, apparently, matching the expected behaviour
("quick-lru", which is smaller and also widely used, although not so
much, unfortunately does not seem to honour the "maximum size"
parameter).

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
Before the cache for blurred video backgrounds was local to each
VideoBackground instance. During a call different VideoBackground
instances can be mounted and destroyed for the same participant (for
example, when switching between speaker mode and grid view, or when a
promoted speaker changes), so the cache was lost and the blurred
background had to be recalculated every time that happened.

Now the cache is global and shared between VideoBackground instances,
so previously cached backgrounds can be used by new VideoBackground
instances.

The global cache is lazily initialized when needed and cleared each time
a call ends.

Signed-off-by: Daniel Calviño Sánchez <danxuliu@gmail.com>
@danxuliu danxuliu force-pushed the improve-cache-handling-in-blur-filter branch from 4037327 to 208b820 Compare January 5, 2021 17:10
@danxuliu danxuliu marked this pull request as ready for review January 5, 2021 17:55
@danxuliu danxuliu requested a review from nickvergessen January 5, 2021 17:55
@@ -36,6 +36,7 @@
"escape-html": "^1.0.3",
"hark": "^1.2.3",
"lodash": "^4.17.20",
"lru-cache": "^6.0.0",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is reaching a level where i think it stops being useful/worth it

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is only ~16 KiB unpacked including its single dependency, so I do not think it is so bad :-) If I had written my own with just the needed features it would have been (I hope...) smaller, but this was faster and easier 🤷

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well its not about the bytes or whatever, its about the complexity off all this. 3rdparty lib, caching, loading images and blurring them with JS, …

return
}

Vue.set(state.blurredBackgroundImageCache, videoBackgroundId, new LRU({ max: 10 }))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so what happens in a call with 12 users and they speak all one sentence after another, it will have to calculate again and again?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, each participant has (or should :-P ) its own cache; 10 is the number of backgrounds for each participant (as the blurred backgrounds are different depending on the size of the video background).

@@ -26,6 +26,8 @@ import {
CONVERSATION,
} from '../constants'

const LRU = require('lru-cache')
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

normally we use import? not require?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The library does not support import, only require 🤷

@nickvergessen
Copy link
Member

I don't know, might be me or something. I set the LRU size to 2, joined with 3 people and when the 3rd one joins the avatar background of the first one changes.

I have to admit I don't care enough and as said before tend more and more to just have black backgrounds in chrome/chromium if the blurring sucks too much. but like storing blurred images in the vue cache, etc....
I leave the decision to Vincent and Marco

@PVince81
Copy link
Member

I'm also not thrilled about the added complexity.

Now I'm also wondering whether the performance issue is happening only on Linux or also on Windows and Mac ?
Because some browsers on Linux are lacking hardware acceleration. In my Firefox on openSUSE I had to turn on some obscure about:config option to enable acceleration and get smooth animations.

Depending the affected demographics it might justify the added complexity. But if it only affects browsers on Linux, browsers which will likely get improvements for hardware acceleration (usually those are experimental first), then maybe not worth the extras and in those cases we could go with black background (or use the avatar letters background color instead).

Thoughts ? @danxuliu @ma12-co

@marcoambrosini
Copy link
Member

marcoambrosini commented Jan 12, 2021

But if it only affects browsers on Linux

Does it? I thought that it affected chrome in general!
In that case yes, I think it'd be fine to go with the usernameToColor function for the backgrounds as an exception for linux chromium based browsers only.

@PVince81
Copy link
Member

I'm not sure if only Linux is affected. I think I now remember @danxuliu mentioning IE also being affected, but not sure if it was a guess.

@nickvergessen
Copy link
Member

IE cant do calls

@danxuliu
Copy link
Member Author

I think I now remember @danxuliu mentioning IE also being affected, but not sure if it was a guess.

Not IE, Edge based on Chromium.

For reference Chromium on MacOS seems to work fine. It does not on Windows (or, at least, on a virtual machine; maybe it does if graphic acceleration is available, I do not know).

Safari has the same performance issue as Chromium when using CSS blur filters, and it does not support the workaround used for Chromium (because it does not support CSS filters on canvases).

Anyway, as discussed this will be closed in favor of always using an average color instead of a blurred background (except on Firefox, as the CSS blur filter works fine).

@danxuliu danxuliu closed this Jan 20, 2021
@danxuliu danxuliu deleted the improve-cache-handling-in-blur-filter branch January 20, 2021 22:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Blur lag introduced in Talk 10.0.4 on Chromium
4 participants