charmbracelet / bubbletea

A powerful little TUI framework 🏗
MIT License
26.74k stars 771 forks source link

Inconsistent and Notable Init Delay #1071

Open DaltonSW opened 1 month ago

DaltonSW commented 1 month ago

Describe the bug Inconsistent, notable delay when starting up BubbleTea

Setup Host: Windows 11 23H2 using WSL, info below

OS: Ubuntu jammy 22.04 x86_64 Host: Windows Subsystem for Linux - Ubuntu (2.2.4) Kernel: Linux 5.15.153.1-microsoft-standard-WSL2 Shell: zsh 5.8.1 WM: WSLg (Wayland) Terminal: WezTerm 20240203-110809-5046fc22

(My friend experienced the same thing when running my exported binary on his full Debian install using GNOME Terminal)

To Reproduce My program relies on having an Advent of Code session cookie saved, and I don't want to post mine. I can give more information, or try and get a test token to provide, if the provided info isn't enough.

Source Code Here's the repo, tagged at the time I'm writing the issue. BubbleTea specific stuff is in /internal/tui/tui.go The resource experiencing slowdown was PageData, and the one that didn't show any was Leaderboard

https://github.com/DaltonSW/aocgo/releases/tag/TUI-Slowdown

Expected behavior I expect the viewport to initialize quickly, as indicated by the example comments.

Example Below is my debug log between two executions of the program. comparison.log

Here is a GIF that shows displaying two different things in the same viewport setup. Both are website responses parsed and stylized with lipgloss/bubbletea Example.gif (The GIF isn't over or frozen, it just sometimes really does take that long)

Additional context Sometimes, it appears to initialize instantly when I scroll my mousewheel, but other times I'll scroll and nothing will happen.

anpez commented 1 month ago

Same here. For me, it happens when I open a huh form. No other visible delay happens when using just plain bubbletea models

DaltonSW commented 1 month ago

So a few different updates on my end:

For the present moment, I've solved this issue by doing the following:

anpez commented 1 month ago

Tried this and, in my case, it didn't work. Not sure if it's the same issue or a related one.

For the present moment, I've solved this issue by doing the following:

  • Using the golang.org/x/term module to get the terminal size myself
  • In my model's Init() function, I return a custom "initMsg" that will cause the viewport to do all of its proper initialization and content setting, but without having to wait on the WindowSizeMsg to come in eventually
anpez commented 1 month ago

Update on my investigation here. My problem seems to be on this function getting a timeout inside r.output.HasDarkBackground()

func (r *Renderer) HasDarkBackground() bool {
    r.mtx.RLock()
    defer r.mtx.RUnlock()

    if !r.explicitBackgroundColor {
        r.getBackgroundColor.Do(func() {
            // NOTE: we don't need to lock here because sync.Once provides its
            // own locking mechanism.
            r.hasDarkBackground = r.output.HasDarkBackground()
        })
    }

    return r.hasDarkBackground
}

Writing in my main a call to HasDarkBackground solves the issue. As term is not busy with tea program, and does not timeout. Is there a way to make this cleaner?

    lipgloss.DefaultRenderer().HasDarkBackground() // this line fixes the timeout
    p := tea.NewProgram(startup.InjectInitialModel())
    if _, err := p.Run(); err != nil {
        fmt.Fprintf(os.Stderr, "Error: %v", err)
        os.Exit(1)
    }
DaltonSW commented 1 month ago

Ooh that's really interesting. As far as your 2nd snippet goes, that's the kind of thing that I've been doing, so I don't see anything that could be cleaned up about it. Ideally this would be addressed (or documented at least). I really have no idea if the stuff I noticed is truly a root cause or if what I tried just happened to work. Glad you got something figured out, that's gonna be a good thing to keep in my back pocket. I dunno if there's someone that's part of the org we could tag to get input on this

meowgorithm commented 1 month ago

Hi all! Yeah, this is a known issue which we're solving for in what will probably be the v2 versions of Bubble Tea and Lip Gloss. @ANPez, you nailed the source of the issue: Bubble Tea and Lip Gloss are competing for use of stdout which Lip Gloss needs to query to determine the background color.

To solve this we need to make some internal changes to both libraries. In the meantime, it's pretty gross but you can work around the issue by simply performing the background query prior starting Bubble Tea:

_ = lipgloss.DefaultRenderer().HasDarkBackground() // ugh

if _, err := p.NewProgram(model{}).Run(); err != nil {
    fmt.Fprintf(os.Stderr, "Oof: %v", err)
}
DaltonSW commented 1 month ago

Thanks so much for the response! I really appreciate it, this has been driving me nutty for a few weeks now. Glad there's a workaround and a plan in place to fix it.

Do you mind if I leave this issue open for tracking purposes, or is there another/an existing one it should be documented on?

DaltonSW commented 1 month ago

@anpez For future reference, what did you do to discover where it was hanging? I'm admittedly fairly new to Go, but none of my profiling or breakpoints seemed to point to anything concrete. I'd like to have another investigation tool in my toolbelt :)

anpez commented 1 month ago

@DaltonSW nothing special, plain old breakpoints :)

DaltonSW commented 3 weeks ago

this is a known issue which we're solving for in what will probably be the v2 versions of Bubble Tea and Lip Gloss... Bubble Tea and Lip Gloss are competing for use of stdout which Lip Gloss needs to query to determine the background color.

@meowgorithm Just to confirm, you're expecting these to be solved in v2 when the current modules don't even appear to be in v1? Is there any sort of timeline for that? I'd frankly expect an issue like this in your modules that advertise being great to use with each other would be considered to be a higher priority.

meowgorithm commented 3 weeks ago

Actually, this should be fixed momentarily via a workaround: https://github.com/charmbracelet/bubbletea/pull/1107.

With regard to v2, there's no ETA, but it's in active development and top of mind for us. @DaltonSW, you're welcome to leave this open until we hit v2, or close this one after the next patch. Regardless, this is one of the drivers behind v2 and we're well aware of the issue.

DaltonSW commented 3 weeks ago

Awesome, thanks so much for the responses! Glad to hear :)

meowgorithm commented 3 weeks ago

We really appreciate you raising the issue! The workaround is now available in Bubble Tea v0.27.1.