wailsapp / wails

Create beautiful applications using Go
https://wails.io
MIT License
25.24k stars 1.21k forks source link

[V2, Linux] `OnDomReady` timing is not constant #2990

Open RyoTagami opened 1 year ago

RyoTagami commented 1 year ago

Description

On Linux, the timing when OnDomReady is not constant.

I created a sample that sends a message to the frontend with EventsEmit when OnDomReady is called. However, there are times when the frontend can receive messages and times when it cannot.

Looking at the logs, you can see that the timing of OnDomReady is different each time. (DOM Ready! is printed when OnDomReady is called.)

Log when message is not received ``` Wails CLI v2.6.0 Executing: go mod tidy • Generating bindings: Done. • Installing frontend dependencies: Done. • Compiling frontend: Done. > frontend@0.0.0 dev > vite VITE v3.2.7 ready in 138 ms Vite Server URL: http://localhost:5173/ ➜ Local: http://localhost:5173/ ➜ Network: use --host to expose Running frontend DevWatcher command: 'npm run dev' Building application for development... • Generating bindings: Done. • Compiling application: Done. • Packaging application: Done. Using DevServer URL: http://localhost:34115 Using Frontend DevServer URL: http://localhost:5173/ Using reload debounce setting of 100 milliseconds Watching (sub)/directory: /home/ryo-tagami/projects/sample INF | Serving assets from frontend DevServer URL: http://localhost:5173/ Overriding existing handler for signal 10. Set JSC_SIGNAL_FOR_GC if you want WebKit to use a different signal DEB | [DevWebServer] Serving DevServer at http://localhost:34115 DEB | [AssetHandler] Handling request '/' (file='.') DEB | [AssetHandler] File '.' not found, serving '/' by AssetHandler DEB | [ExternalAssetHandler] Loading 'http://localhost:5173/' DEB | [AssetHandler] Handling request '/@vite/client' (file='@vite/client') DEB | [AssetHandler] File '@vite/client' not found, serving '/@vite/client' by AssetHandler DEB | [AssetHandler] Handling request '/src/main.js' (file='src/main.js') DEB | [AssetHandler] File 'src/main.js' not found, serving '/src/main.js' by AssetHandler DEB | [ExternalAssetHandler] Loading 'http://localhost:5173/src/main.js' DEB | [ExternalAssetHandler] Loading 'http://localhost:5173/@vite/client' DOM Ready! DEB | [AssetHandler] Handling request '/src/style.css' (file='src/style.css') DEB | [AssetHandler] File 'src/style.css' not found, serving '/src/style.css' by AssetHandler DEB | [ExternalAssetHandler] Loading 'http://localhost:5173/src/style.css' DEB | [AssetHandler] Handling request '/src/app.css' (file='src/app.css') DEB | [AssetHandler] File 'src/app.css' not found, serving '/src/app.css' by AssetHandler DEB | [ExternalAssetHandler] Loading 'http://localhost:5173/src/app.css' DEB | [AssetHandler] Handling request '/wailsjs/runtime/runtime.js' (file='wailsjs/runtime/runtime.js') DEB | [AssetHandler] Handling request '/src/assets/images/logo-universal.png' (file='src/assets/images/logo-universal.png') DEB | [AssetHandler] File 'wailsjs/runtime/runtime.js' not found, serving '/wailsjs/runtime/runtime.js' by AssetHandler DEB | [AssetHandler] File 'src/assets/images/logo-universal.png' not found, serving '/src/assets/images/logo-universal.png' by AssetHandler DEB | [ExternalAssetHandler] Loading 'http://localhost:5173/wailsjs/runtime/runtime.js' DEB | [ExternalAssetHandler] Loading 'http://localhost:5173/src/assets/images/logo-universal.png?import' DEB | [AssetHandler] Handling request '/node_modules/vite/dist/client/env.mjs' (file='node_modules/vite/dist/client/env.mjs') DEB | [AssetHandler] File 'node_modules/vite/dist/client/env.mjs' not found, serving '/node_modules/vite/dist/client/env.mjs' by AssetHandler DEB | [ExternalAssetHandler] Loading 'http://localhost:5173/node_modules/vite/dist/client/env.mjs' DEB | [AssetHandler] Handling request '/src/assets/images/logo-universal.png' (file='src/assets/images/logo-universal.png') DEB | [AssetHandler] File 'src/assets/images/logo-universal.png' not found, serving '/src/assets/images/logo-universal.png' by AssetHandler DEB | [ExternalAssetHandler] Loading 'http://localhost:5173/src/assets/images/logo-universal.png' To develop in the browser and call your bound Go methods from Javascript, navigate to: http://localhost:34115 ```
Log when message is received ``` Wails CLI v2.6.0 Executing: go mod tidy • Generating bindings: Done. • Installing frontend dependencies: Done. • Compiling frontend: Done. > frontend@0.0.0 dev > vite VITE v3.2.7 ready in 99 ms Vite Server URL: http://localhost:5173/ ➜ Local: http://localhost:5173/ ➜ Network: use --host to expose Running frontend DevWatcher command: 'npm run dev' Building application for development... • Generating bindings: Done. • Compiling application: Done. • Packaging application: Done. Using DevServer URL: http://localhost:34115 Using Frontend DevServer URL: http://localhost:5173/ Using reload debounce setting of 100 milliseconds Watching (sub)/directory: /home/ryo-tagami/projects/sample INF | Serving assets from frontend DevServer URL: http://localhost:5173/ Overriding existing handler for signal 10. Set JSC_SIGNAL_FOR_GC if you want WebKit to use a different signal DEB | [DevWebServer] Serving DevServer at http://localhost:34115 DEB | [AssetHandler] Handling request '/' (file='.') DEB | [AssetHandler] File '.' not found, serving '/' by AssetHandler DEB | [ExternalAssetHandler] Loading 'http://localhost:5173/' DEB | [AssetHandler] Handling request '/@vite/client' (file='@vite/client') DEB | [AssetHandler] File '@vite/client' not found, serving '/@vite/client' by AssetHandler DEB | [ExternalAssetHandler] Loading 'http://localhost:5173/@vite/client' DEB | [AssetHandler] Handling request '/src/main.js' (file='src/main.js') DEB | [AssetHandler] File 'src/main.js' not found, serving '/src/main.js' by AssetHandler DEB | [ExternalAssetHandler] Loading 'http://localhost:5173/src/main.js' DEB | [AssetHandler] Handling request '/src/style.css' (file='src/style.css') DEB | [AssetHandler] File 'src/style.css' not found, serving '/src/style.css' by AssetHandler DEB | [AssetHandler] Handling request '/src/app.css' (file='src/app.css') DEB | [AssetHandler] File 'src/app.css' not found, serving '/src/app.css' by AssetHandler DEB | [ExternalAssetHandler] Loading 'http://localhost:5173/src/style.css' DEB | [ExternalAssetHandler] Loading 'http://localhost:5173/src/app.css' DEB | [AssetHandler] Handling request '/src/assets/images/logo-universal.png' (file='src/assets/images/logo-universal.png') DEB | [AssetHandler] File 'src/assets/images/logo-universal.png' not found, serving '/src/assets/images/logo-universal.png' by AssetHandler DEB | [ExternalAssetHandler] Loading 'http://localhost:5173/src/assets/images/logo-universal.png?import' DEB | [AssetHandler] Handling request '/wailsjs/runtime/runtime.js' (file='wailsjs/runtime/runtime.js') DEB | [AssetHandler] File 'wailsjs/runtime/runtime.js' not found, serving '/wailsjs/runtime/runtime.js' by AssetHandler DEB | [ExternalAssetHandler] Loading 'http://localhost:5173/wailsjs/runtime/runtime.js' DEB | [AssetHandler] Handling request '/node_modules/vite/dist/client/env.mjs' (file='node_modules/vite/dist/client/env.mjs') DEB | [AssetHandler] File 'node_modules/vite/dist/client/env.mjs' not found, serving '/node_modules/vite/dist/client/env.mjs' by AssetHandler DEB | [ExternalAssetHandler] Loading 'http://localhost:5173/node_modules/vite/dist/client/env.mjs' DOM Ready! DEB | [AssetHandler] Handling request '/src/assets/images/logo-universal.png' (file='src/assets/images/logo-universal.png') DEB | [AssetHandler] File 'src/assets/images/logo-universal.png' not found, serving '/src/assets/images/logo-universal.png' by AssetHandler DEB | [ExternalAssetHandler] Loading 'http://localhost:5173/src/assets/images/logo-universal.png' To develop in the browser and call your bound Go methods from Javascript, navigate to: http://localhost:34115 ```

To Reproduce

  1. Create project. wails init -n sample -t vanilla
  2. Rewrite the following files.
app.go ```go package main import ( "context" "fmt" "github.com/wailsapp/wails/v2/pkg/runtime" ) type App struct { ctx context.Context } func NewApp() *App { return &App{} } func (a *App) startup(ctx context.Context) { a.ctx = ctx } // 👇👇👇 Add func (a *App) domReady(ctx context.Context) { fmt.Println("DOM Ready!") a.EmitSampleEvent() } // 👇👇👇 Add func (a *App) EmitSampleEvent() { runtime.EventsEmit(a.ctx, "SampleEvent", "Hello! This is Event Message.") } ```
main.go ```go package main import ( "embed" "github.com/wailsapp/wails/v2" "github.com/wailsapp/wails/v2/pkg/options" "github.com/wailsapp/wails/v2/pkg/options/assetserver" ) //go:embed all:frontend/dist var assets embed.FS func main() { app := NewApp() err := wails.Run(&options.App{ Title: "sample", Width: 1024, Height: 768, AssetServer: &assetserver.Options{ Assets: assets, }, BackgroundColour: &options.RGBA{R: 27, G: 38, B: 54, A: 1}, OnStartup: app.startup, OnDomReady: app.domReady, // 👈👈👈 Add Bind: []interface{}{ app, }, }) if err != nil { println("Error:", err.Error()) } } ```
frontend/src/main.js ```js import './style.css'; import './app.css'; import logo from './assets/images/logo-universal.png'; // 👇👇👇 Add import { EventsOn } from '../wailsjs/runtime/runtime'; document.querySelector('#app').innerHTML = `
No events received.
`; document.getElementById('logo').src = logo; let resultElement = document.getElementById("result"); // 👇👇👇 Add EventsOn("SampleEvent", (message) => { resultElement.innerText = message; }); ```
  1. Run wails dev.
  2. Repeat reload several times. Reload
  3. Check that the message changes depending on the case. No events received Event message

Expected behaviour

OnDomReady is called after all assets have been loaded.

On Windows, OnDomReady is always called after all assets have been loaded (exclude favicon).

Logs on Windows ``` DEB | Using go webview2loader Wails CLI v2.6.0 Updating go.mod to use Wails 'v2.6.0' Executing: go mod tidy • Generating bindings: Done. • Installing frontend dependencies: Done. • Compiling frontend: Done. > frontend@0.0.0 dev > vite VITE v3.2.7 ready in 165 ms Vite Server URL: http://localhost:5173/ ➜ Local: http://localhost:5173/ Running frontend DevWatcher command: 'npm run dev' ➜ Network: use --host to expose Building application for development... • Generating bindings: Done. • Generating application assets: Done. • Compiling application: Done. INFO Wails is now using the new Go WebView2Loader. If you encounter any issues with it, please report them to https://github.com/wailsapp/wails/issues/2004. You could also use the old legacy loader with `-tags native_webview2loader`, but keep in mind this will be deprecated in the near future. Using DevServer URL: http://localhost:34115 Using Frontend DevServer URL: http://localhost:5173/ Using reload debounce setting of 100 milliseconds Watching (sub)/directory: D:\Projects\sample DEB | Using go webview2loader INF | Serving assets from frontend DevServer URL: http://localhost:5173/ DEB | WebView2 Runtime Version '117.0.2045.60' installed. Minimum version required: 94.0.992.31. DEB | [DevWebServer] Serving DevServer at http://localhost:34115 DEB | [AssetHandler] Handling request '/' (file='.') DEB | [AssetHandler] File '.' not found, serving '/' by AssetHandler DEB | [ExternalAssetHandler] Loading 'http://localhost:5173/' DEB | [AssetHandler] Handling request '/@vite/client' (file='@vite/client') DEB | [AssetHandler] File '@vite/client' not found, serving '/@vite/client' by AssetHandler DEB | [ExternalAssetHandler] Loading 'http://localhost:5173/@vite/client' DEB | [AssetHandler] Handling request '/src/main.js' (file='src/main.js') DEB | [AssetHandler] File 'src/main.js' not found, serving '/src/main.js' by AssetHandler DEB | [ExternalAssetHandler] Loading 'http://localhost:5173/src/main.js' DEB | [AssetHandler] Handling request '/src/style.css' (file='src/style.css') DEB | [AssetHandler] File 'src/style.css' not found, serving '/src/style.css' by AssetHandler DEB | [ExternalAssetHandler] Loading 'http://localhost:5173/src/style.css' DEB | [AssetHandler] Handling request '/src/app.css' (file='src/app.css') DEB | [AssetHandler] File 'src/app.css' not found, serving '/src/app.css' by AssetHandler DEB | [ExternalAssetHandler] Loading 'http://localhost:5173/src/app.css' DEB | [AssetHandler] Handling request '/src/assets/images/logo-universal.png' (file='src/assets/images/logo-universal.png') DEB | [AssetHandler] File 'src/assets/images/logo-universal.png' not found, serving '/src/assets/images/logo-universal.png' by AssetHandler DEB | [ExternalAssetHandler] Loading 'http://localhost:5173/src/assets/images/logo-universal.png?import' DEB | [AssetHandler] Handling request '/wailsjs/runtime/runtime.js' (file='wailsjs/runtime/runtime.js') DEB | [AssetHandler] File 'wailsjs/runtime/runtime.js' not found, serving '/wailsjs/runtime/runtime.js' by AssetHandler DEB | [ExternalAssetHandler] Loading 'http://localhost:5173/wailsjs/runtime/runtime.js' DEB | [AssetHandler] Handling request '/node_modules/vite/dist/client/env.mjs' (file='node_modules/vite/dist/client/env.mjs') DEB | [AssetHandler] File 'node_modules/vite/dist/client/env.mjs' not found, serving '/node_modules/vite/dist/client/env.mjs' by AssetHandler DEB | [ExternalAssetHandler] Loading 'http://localhost:5173/node_modules/vite/dist/client/env.mjs' DEB | [AssetHandler] Handling request '/src/assets/images/logo-universal.png' (file='src/assets/images/logo-universal.png') DEB | [AssetHandler] File 'src/assets/images/logo-universal.png' not found, serving '/src/assets/images/logo-universal.png' by AssetHandler DEB | [ExternalAssetHandler] Loading 'http://localhost:5173/src/assets/images/logo-universal.png' DEB | [AssetHandler] Handling request '/src/assets/fonts/nunito-v16-latin-regular.woff2' (file='src/assets/fonts/nunito-v16-latin-regular.woff2') DEB | [AssetHandler] File 'src/assets/fonts/nunito-v16-latin-regular.woff2' not found, serving '/src/assets/fonts/nunito-v16-latin-regular.woff2' by AssetHandler DEB | [ExternalAssetHandler] Loading 'http://localhost:5173/src/assets/fonts/nunito-v16-latin-regular.woff2' DOM Ready! DEB | [AssetHandler] Handling request '/favicon.ico' (file='favicon.ico') DEB | [AssetHandler] File 'favicon.ico' not found, serving '/favicon.ico' by AssetHandler DEB | [ExternalAssetHandler] Loading 'http://localhost:5173/favicon.ico' To develop in the browser and call your bound Go methods from Javascript, navigate to: http://localhost:34115 ```

Screenshots

No response

Attempted Fixes

No response

System Details

# Wails
Version         | v2.6.0
Package Manager | apt   

# System
┌─────────────────────────┐
| OS           | Ubuntu   |
| Version      | 22.04    |
| ID           | ubuntu   |
| Go Version   | go1.21.3 |
| Platform     | linux    |
| Architecture | amd64    |
└─────────────────────────┘

# Dependencies
┌──────────────────────────────────────────────────────────────────────────┐
| Dependency | Package Name          | Status    | Version                 |
| *docker    | docker.io             | Available | 24.0.5-0ubuntu1~22.04.1 |
| gcc        | build-essential       | Installed | 11.4.0                  |
| libgtk-3   | libgtk-3-dev          | Installed | 3.24.33-1ubuntu2        |
| libwebkit  | libwebkit2gtk-4.0-dev | Installed | 2.42.1-0ubuntu0.22.04.1 |
| npm        | npm                   | Installed | 9.8.1                   |
| *nsis      | nsis                  | Available | 3.08-2                  |
| pkg-config | pkg-config            | Installed | 0.29.2                  |
└──────────────────────── * - Optional Dependency ─────────────────────────┘

# Diagnosis
Optional package(s) installation details: 
  - docker: sudo apt install docker.io
  - nsis: sudo apt install nsis

Additional context

No response

leaanthony commented 1 year ago

Sounds like it needs more debugging to track down the bug,

lyimmi commented 1 year ago

I have ran into this before and this is a timing issue.

The domready event is triggered in the C code of the window handler by the gtkwebview process via WEBKIT_LOAD_FINISHED - Load completed. All resources are done loading or there was an error during the load operation.. Unfortunately this does not mean that all js code is done, or the javascript side event listeners are registered.

After the WEBKIT_LOAD_FINISHED event the domready go code is called. This can be faster then the javascript side of things.

My two workaround for this is:

  1. emmit your own domready event, this depends on what do you think when your frontend is ready, but this can be at an exact state in your frontend.
  2. wait a few milliseconds in func (a *App) domReady(ctx context.Context) but this can be still out of sync if the user uses a potato PC. (or a raspberry)

I use the first method in production.