WebView vs JUCE graphics

not that this hasn’t happened to me, but if an incremental debug rebuild takes 30 seconds, then maybe something is off with the compile structure… or your machine is a sloth ;).

1 Like

In that case you probably want to move most of the UI to separate .cpp files to speed it up. You probably don’t need to constantly recompile the entire project when modifying UI positions, colors, etc (which is the use case for hot reload), so those 30 seconds should only happen on the very first compile.

4 Likes

Point taken. This particular project has a bunch of mostly header file templated DSP code which is also used for rendering waveform previews…

I guess this is a good reminder that attending to your compilation structure and separating code out into .cpp files is a good and important practice that can save much time when working on UI updates!

Pros:

  • Improved SVG rendering
  • Improved font rendering for Windows (but this has been improved quite a bit with the new D2D renderer also)
  • Hot reload
  • Don’t have to code GUI in C++
  • Access to JS frontend frameworks
  • CSS

Cons:

  • Need to set up relays and generally communicate between C++ and webviews
  • JUCE frontend library seems decent but lacking typescript & packaging support
  • Potentially complicate installers if you want to ensure correct webview runtimes are installed
  • Setting up resource routes for your frontend assets (not so bad once you set up a wrapper around juce::WebBrowserComponent::Resource & have a good build step leveraging JUCE BinaryData)
  • Potential performance implications for heavier GUIs

Overall I’m pretty happy with the outcome. I would like to see better TypeScript support for the frontend library and also published to a package registry to make it easier to integrate in a node/bun/deno project.

2 Likes

Can this be done if the GUI code is part of a JUCE module? Currently, my understanding is you only actually have one cpp file per module, which you’re meant to then include everything else from. So it’s effectively a single unit with all the cpp copy-pasted.

If there’s a way around that, I’d love to do it.

Short answer: yes.

How you create TU division in your modules is up to you. A module can have multiple TU’s, and you can split your GUI into multiple modules, our complicated products have a few different modules just for UI.

In terms of compilation times, you want to divide it to where things make sense. For example adding 5 components to a module will probably make almost 0 difference on compilation speed.

But, adding your DSP or networking code to that module might be a huge bump in iteration time, so split that/have the call to them behind a forward declare type or PIMPL, etc.

How? JUCE just looks for module_name.cpp as far as I understood.

Including other cpp files from that cpp file does not count.

The module format allows you add file names like juce_core_time.cpp to create multiple TUs.

But I would say that you should only do that if those files should really compile in isolation, as the more splits you do you will lose on the big speedup of unity builds.

From the docs…

The names of these source files must begin with the name of the module, but they can have a number or other suffix if there is more than one.

In order to specify that a source file should only be compiled for a specific platform, then the filename can be suffixed with one of the following (case insensitive) strings:

_mac or _osx    <- compiled for macOS and OSX platforms only
_windows        <- compiled for Windows platforms only
_linux          <- compiled for Linux and FreeBSD platforms only
_andoid         <- compiled for Android platforms only
_ios            <- compiled for iOS platforms only

e.g.

juce_mymodule/juce_mymodule_1.cpp         <- compiled for all platforms
juce_mymodule/juce_mymodule_2.cpp         <- compiled for all platforms
juce_mymodule/juce_mymodule_mac.cpp       <- compiled for macOS and OSX >platforms only
juce_mymodule/juce_mymodule_windows.cpp   <- compiled for Windows platforms only
6 Likes

In case anyone is interested, I’ve open sourced a couple of Vue.js components that we’ve been crafting: https://acousti-kit.io/

For now, we’ve been focusing on getting a good Knob component going, with similar features as we could build in JUCE like multiple mouse tracking modes, pointer capture, customizable graphics and more. The pointer capture still doesn’t work in the JUCE webview yet, still seeing if there’s something to be done about that. Also working on value skewing features, step configuration and more for this component. After that, I’ll be starting on sliders, meters and possibly more. Please chime in with ideas or requests if you have them, would be cool to build some high quality components to speed up plugin UI building.

7 Likes

This looks really promising, especially if you manage to get other components like sliders, combo boxes and toggles working with the same degree of customizability that’s already in your knob component!

What would sell this for me immediately is some form of visualiser-like component, something akin to a spectrogram or a frequency analyzer with easy-to-change graphics (eg bg colours, glow, reactivity speeds, etc.)

Keep up the awesome work!

I guess big consideration for web vs juce graphics now is the product stage.

For existing projects, it might not be worth the effort. even if it’s a major update that does some UI updates. Unless there’s key benefit which again, depends on the project.

For new projects, things get interesting.
Many interesting points were raised here.

One thing I’ve really enjoyed fiddling with lately was WebGL based code.
Even not something I wrote myself, just integrating it was much faster than getting OpenGL working across multiple platforms. and all the headache of overlaying elements, blurring and fancy things are already available out of the box.

One thing I’ve already noticed that can be tricky is keyboard focus.
I wonder if anyone played with keyboard focus with web views and got some suggestions about that.

1 Like

There was some discussion about this in the choc channel on The Audio Programmer Discord: https://discord.com/channels/382895736356077570/1218213251553165393/1237422491266187445

On both macOS and Windows, WebGL uses ANGLE for translating GLSL shaders, to native. Which is a great way to get fast 2D and 3D graphics running. On both systems. iOS also uses ANGLE. So this makes Web views potentially very attractive indeed. If Juce had a Metal renderer it would be a very different story, of course…

Is it possible to unlock 60HZ → 120HZ on MacOS/iOS in the WebView?