Web view start up UI issue

After working on many projects using JUCE’s in-built UI support, I thought I’d give the WebBrowserComponent a go using a full(ish) web stack: Vite, React, Tailwind and shadcn/ui.

To test, I’ve implemented a few complex components including a non-trivial MSEG editor.

All good - and the performance is pretty impressive as it’s leaning into browser rendering tech that’s pretty fast these days. Its buttery smooth and the canvas rendering is lightening.

I’m almost at the point of declaring it as a decent way to develop plugin apps.

However…there’s one last thing that’s driving me nuts and thats when the plugin (or standalone) first loads. You get a white flash prior to the web-view being rendered. Presumably going from a blank web-view to the UI rendered view.

I’ve tried several things to try and get around it, but no luck. It’s annoying because for a commercial plugin it would really look scrappy - I’d have it down as a bug.

The ideal would be to only present the standalone or plugin window when you’ve got a full UI render done.

Anyone here had any experience with fixing this or implementing a useful workaround?

1 Like

My understanding is this is the time it takes for all the plumbing to happen. It makes the webview, delivers resources, etc. A way I’ve found around it is to setup the webview in the processor, parent it to an off screen hwnd, then when you open/close your editor you are reparenting the webview between your editor and the dummy hwnd. Super hacky, but it works in the ways I’ve tested it.

1 Like

Yeah, I imagine its doing a fair bit of heavy lifting to start with.

I’ll give your suggestion a go and see how that works out.

Have you tested in a Release build?

Another workaround could be to use paintOverChildren() from your plugin’s editor and draw a short splash screen that fades after half a second or so when the web UI has had a chance to render.

You can also do similar things from the web UI side where you load the UI in different stages rather than waiting for the whole UI to build at once. I.e. only render the background on the first pass, then asyncrounously load your different groups/panels, then load your controls as a final pass. Use calls to fetch() to load the different stages from your JUCE backend.

1 Like

My hacky fix to this was to addChildComponent the webview, paint the editor with a colour that matches the background colour of the web UI and then setVisible on the webview after a small delay.

2 Likes

Another hacky approach could be to take a screenshot of the UI once it’s loaded and then draw that in paint()

1 Like

Ok, best I managed to achieve was a set colour full screen rectangle, then shortly after the web view appears. No white flashes or flickering.

And it was a royal PITA to do.

Main problems: the web view is a native view that’s rendered above all JUCE components rather than being subject to Z order. And trying to render off-screen is problematic because at least on Mac it’s not guaranteed to do that - it knows it’s not visible (off-screen) and decides not to render yet.

As a side, I also implemented drag resize for the window, with the required effect of scaling the contents as you drag. Implemented ok, but as you drag the window you get small white right and bottom side borders appear as the web view catches up with the size of the window.

I’m a stickler for a solid feeling and polished product, so these glitches are really problematic for me at least.

The upsides are the rendering speed and maturity (full power of CSS, SVG etc) and lots of tooling available for web UI.

The downside seems to be these rough edges and the plumbing between c++ and web which may well negate any development speed-up gained through the upsides.

Back to native JUCE UI it is…

2 Likes