Initialisation: make the progress bar update more smoothly#423
Initialisation: make the progress bar update more smoothly#423agarny merged 9 commits intoopencor:mainfrom
Conversation
The `void` doesn't seem to be needed anymore?
At the end of the day, it's not downloading libOpenCOR that takes time, but import it and then instantiate it. Yet, right now, our progress bar updates as a result of loading our external dependencies which means that when we have loaded libOpenCOR, we still need to wait a bit for it to be imported and then instantiated. This is clearly not great, so instead we should use one unit per external dependency (except for VueTippy where we should be using two since we have to import the module itself and then its CSS) and three units for libOpenCOR (one for loading its WASM, another for importing, and a final one for instantiating it).
There was a problem hiding this comment.
Pull request overview
Refactors renderer initialisation to centralise external dependency loading and drive the “Initialising OpenCOR…” progress bar from a shared initialisation module (intended to improve perceived smoothness during startup).
Changes:
- Introduces
common/initialisation.tsandcommon/dependencies.tsto initialise libOpenCOR and CDN-loaded libraries, and to expose them via a shared dependency registry. - Updates consumers to use the new dependency registry (e.g., jsonschema/JSZip/Math.js/Plotly/VueTippy) and adjusts OpenCOR’s initialisation UI logic accordingly.
- Misc UI/cleanup tweaks (z-index adjustments, BlockUI binding changes, minor code style edits).
Reviewed changes
Copilot reviewed 15 out of 15 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/renderer/src/main.ts | Comment formatting / semicolons. |
| src/renderer/src/libopencor/locUiJsonApi.ts | Switches jsonschema access to dependencies._jsonSchema. |
| src/renderer/src/libopencor/locApi.ts | Removes initialiseLocApi() and replaces with setters for C++/WASM APIs. |
| src/renderer/src/components/widgets/InputWidget.vue | Minor nextTick call style change. |
| src/renderer/src/components/widgets/GraphPanelWidget.vue | Switches Plotly access to dependencies._plotlyJs. |
| src/renderer/src/components/views/SimulationExperimentView.vue | Switches JSZip/Math.js access to dependencies registry. |
| src/renderer/src/components/dialogs/BaseDialog.vue | Minor nextTick call style change. |
| src/renderer/src/components/OpenCOR.vue | Integrates new initialisation module + progress wiring; updates UI blocking/background/issue aggregation. |
| src/renderer/src/components/MainMenu.vue | Raises submenu z-index. |
| src/renderer/src/components/BackgroundComponent.vue | Adjusts logo z-index class. |
| src/renderer/src/common/settings.ts | Minor promise call style change when loading settings. |
| src/renderer/src/common/locCommon.ts | Switches JSZip access to dependencies._jsZip. |
| src/renderer/src/common/initialisation.ts | New: orchestrates libOpenCOR + external dependency initialisation and progress tracking. |
| src/renderer/src/common/dependencies.ts | New: shared registry for dynamically loaded dependencies + xxhash init. |
| src/renderer/src/common/common.ts | Removes previous lazy-initialiser helpers; routes xxhash usage via dependencies._xxhash. |
Comments suppressed due to low confidence (4)
src/renderer/src/common/initialisation.ts:67
- When
window.locApiis available (C++ OpenCOR),crtNbOfStepsis never incremented. If you keep counting libOpenCOR init as steps (or iftotalNbOfStepsis adjusted away from 0 for Electron), progress may never reach 100%. Either increment steps for the C++ path or computetotalNbOfStepsbased on whether the C++ or WASM path is taken.
export const initialiseLocApi = async (): Promise<void> => {
// @ts-expect-error (window.locApi may or may not be defined which is why we test it)
if (window.locApi) {
// We are running OpenCOR, so libOpenCOR can be accessed using window.locApi.
// @ts-expect-error (window.locApi is defined)
locApi.setCppLocApi(window.locApi);
} else {
src/renderer/src/common/initialisation.ts:76
- The PR/issue description mentions switching libOpenCOR WASM to UNPKG and downloading it in chunks to provide smooth progress updates, but this still performs a single dynamic
import()fromopencor.wsand only advances progress in 2 coarse steps. If the goal is smoother progress, consider switching the URL to UNPKG and/or replacing the dynamic import with a streamedfetch()(usingContent-Length+ReadableStream) soprogresscan update during the download.
try {
const libOpenCOR = (
await import(
/* @vite-ignore */ common.corsProxyUrl(
'https://opencor.ws/libopencor/downloads/wasm/libopencor-0.20260211.0.js'
)
)
src/renderer/src/common/dependencies.ts:12
_xxhashis initialised using top-levelawaitat module load time. If this async init fails (or is slow), it will block importing any module that depends ondependencies.tsand bypasses the initialisation error reporting/progress tracking. Consider initialising xxhash inside the initialisation pipeline (with proper error handling) or exporting a Promise and awaiting it where needed.
export let _plotlyJs: Module = null;
export let _vueTippy: Module = null;
export const _xxhash = await xxhash();
src/renderer/src/common/initialisation.ts:106
- Typo in comment: “exteral” should be “external”.
try {
// Import the exteral dependency and set it.
const module = await import(/* @vite-ignore */ url);
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…cies. Well... this was disappointing since we are pretty much back to what we originally had. Indeed, to load and even cache libOpenCOR's WASM is not worth it. To actually import and instantiate is really what takes time.
Indeed, this doesn't go well with Electron since it uses CommonJS which... yeah, doesn't support top-level await.
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 18 out of 20 changed files in this pull request and generated 1 comment.
Comments suppressed due to low confidence (2)
src/renderer/src/common/initialisation.ts:106
- Typo in comment: "exteral" should be "external".
// Import the exteral dependency and set it.
src/renderer/src/common/settings.ts:50
- In the Electron path, a rejection from
electronApi.loadSettings()will currently be unhandled andemitInitialised()will never be called, leaving anyonInitialised()listeners waiting indefinitely. Consider adding a.catch(...)that logs the error, keeps defaults, and still callsemitInitialised()(optionally resetting to defaults).
if (electronApi) {
electronApi.loadSettings().then((settings: ISettings) => {
this._settings = settings;
this.emitInitialised();
});
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Fixes #419.