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

High CPU and sluggishness running a simple wasm app #5073

Closed
2 tasks done
bogen85 opened this issue Aug 15, 2024 · 8 comments
Closed
2 tasks done

High CPU and sluggishness running a simple wasm app #5073

bogen85 opened this issue Aug 15, 2024 · 8 comments
Labels
unverified A bug that has been reported but not verified

Comments

@bogen85
Copy link

bogen85 commented Aug 15, 2024

Checklist

  • I have searched the issue tracker for open issues that relate to the same problem, before opening a new one.
  • This issue only relates to a single bug. I will open new issues for any other problems.

Describe the bug

Example app when idling uses a lot of CPU.
When entering in text it feels sluggish.

With chromium running nothing, it is at very low CPU usage. See screenshots.
Just running https://get.webgl.org/?ref=colonist-blog around 14% and 8% (2 cores)
Just running the provided example code fyne serve --sourceDir client around 16 and 18% (2 cores)

Firefox shows similar results.
GPU acceleration is being used. See screenshots.

How to reproduce

fyne serve --sourceDir client with the provided example code in the directory client

Wait for app to load then look at CPU usage.

Type in text into the entry box and press enter (or press the button).

Screenshots

chromium idle
image

chromium just running https://get.webgl.org/?ref=colonist-blog
image

chromium just running the provided example fyne wasm app
image

GPU is being used
image

Chromium version 127
image

Example code

// client/main.go
package main

import (
        "fmt"
        "fyne.io/fyne/v2/app"
        "fyne.io/fyne/v2/container"
        "fyne.io/fyne/v2/widget"
)

func main() {
        a := app.NewWithID("go-fyne-wasm-app")
        w := a.NewWindow("Sample app")

        entry := widget.NewEntry()
        addButton := widget.NewButton("Add", func() {
                text := entry.Text
                if text != "" {
                        entry.SetText("")
                        fmt.Printf("Text: %s\n", text)
                }
        })

        entry.OnSubmitted = func(s string) {
                addButton.OnTapped()
        }

        w.SetContent(container.NewVBox(
                entry,
                addButton,
        ))

        w.ShowAndRun()
}

Fyne version

fyne version v2.5.0

Go compiler version

go version go1.23.0 linux/amd64

Operating system and version

AlmaLinux 9.4 x86_64

Additional Information

This might be related to #2803 but this is with an idling app.

chrome:://gpu shows:

*   WebGL: Hardware accelerated
*   WebGL2: Hardware accelerated
@bogen85 bogen85 added the unverified A bug that has been reported but not verified label Aug 15, 2024
@bogen85
Copy link
Author

bogen85 commented Aug 15, 2024

I'm aware of #4641 as well, but as I said already, this issue is with an idling app.

@bogen85
Copy link
Author

bogen85 commented Aug 15, 2024

This uses very little CPU, when run as a wasm app, but it has no text input:

package main

import (
        "fmt"

        "fyne.io/fyne/v2"
        "fyne.io/fyne/v2/app"
        "fyne.io/fyne/v2/container"
        "fyne.io/fyne/v2/widget"
)

type customLayout struct {
        split *container.Split
}

func (c *customLayout) Layout(objects []fyne.CanvasObject, size fyne.Size) {
        c.split.Resize(size)
}

func (c *customLayout) MinSize(objects []fyne.CanvasObject) fyne.Size {
        return c.split.MinSize()
}

func main() {
        myApp := app.New()
        myWindow := myApp.NewWindow("Four Regions App")

        // Top region
        topRegion := widget.NewLabel("Top Region")
        topRegion.Alignment = fyne.TextAlignCenter

        // Middle resizable regions
        middleRegion1 := widget.NewLabel("Middle Region 1 (Resizable)")
        middleRegion1.Alignment = fyne.TextAlignCenter

        middleRegion2 := widget.NewLabel("Middle Region 2 (Resizable)")
        middleRegion2.Alignment = fyne.TextAlignCenter

        // Bottom region
        bottomRegion := widget.NewLabel("Bottom Region")
        bottomRegion.Alignment = fyne.TextAlignCenter

        // Create a split container for the middle resizable regions
        split := container.NewVSplit(
                container.NewVBox(middleRegion1),
                container.NewVBox(middleRegion2),
        )

        // Create a custom layout to wrap the split container
        customSplit := container.New(&customLayout{split: split}, split)

        // Set up the main container with all regions
        content := container.NewBorder(
                container.NewVBox(topRegion),
                container.NewVBox(bottomRegion),
                nil,
                nil,
                customSplit,
        )

        // Set minimum window size
        myWindow.Resize(fyne.NewSize(400, 300))

        myWindow.SetContent(content)

        // Common callback function to print dimensions
        printDimensions := func() {
                fmt.Printf("Window size: %v\n", myWindow.Canvas().Size())
                fmt.Printf("Top region size: %v\n", topRegion.Size())
                fmt.Printf("Middle region 1 size: %v\n", middleRegion1.Size())
                fmt.Printf("Middle region 2 size: %v\n", middleRegion2.Size())
                fmt.Printf("Bottom region size: %v\n", bottomRegion.Size())
                fmt.Println("------------------------")
        }

        // Callback for window resize
        myWindow.Canvas().SetOnTypedKey(func(ke *fyne.KeyEvent) {
                if ke.Name == fyne.KeyF11 {
                        fmt.Println("Window resized")
                        printDimensions()
                }
        })

        myWindow.ShowAndRun()
}

@bogen85
Copy link
Author

bogen85 commented Aug 15, 2024

Alright, this might be related to #4641 and therefore possibly a duplicate.
The text inputs on that demo feel like they may be sluggish as well.

@andydotxyz
Copy link
Member

I'm guessing this is with the entry focused? There is a cursor animation that you could turn off to see if it's related (by disabling animations in the build).

@bogen85
Copy link
Author

bogen85 commented Aug 15, 2024

Yeah, that makes sense. Yes, that is with the entry focused. That explains why the app with no blinking cursor does not have the CPU usage at idle. I'll try disabling the cursor animation.

@bogen85
Copy link
Author

bogen85 commented Aug 15, 2024

Disabling the animations also made the cursor invisible for me (local x11, not in the browser). Offhand I don't see a way in fyne serve to apply the no_animations tag.

Removed the wasm directory, rebuilt it with fyne package --target web --tags no_animations --src client/.

Served it with

package main

import (
        "fmt"
        "net/http"
)

func main() {
        fs := http.FileServer(http.Dir("./wasm")) // Serve from the 'web' directory
        http.Handle("/", fs)

        fmt.Println("Server started at http://localhost:8080")
        http.ListenAndServe(":8080", nil)
}

The cursor in the web page is now no longer animated, but it is now not visible as well. Also, the cpu usage is very low, so it is the blinking cursor that was consuming the CPU.

@andydotxyz
Copy link
Member

andydotxyz commented Aug 15, 2024

Offhand I don't see a way in fyne serve to apply the no_animations tag.

There is a PR open to fix this already :).

The cursor in the web page is now no longer animated, but it is now not visible as well.

That is fixed on the release branch in preparation for v2.5.1 coming soon.

@bogen85
Copy link
Author

bogen85 commented Aug 27, 2024

Alight, since I know what is going on, I'll close this. Especially with the mitigations you mentioned.

@bogen85 bogen85 closed this as completed Aug 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
unverified A bug that has been reported but not verified
Projects
None yet
Development

No branches or pull requests

2 participants