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

Markdown Widget Lagging when Opening Large Files #4586

Closed
VexiaOnline opened this issue Jun 2, 2024 · 2 comments · Fixed by #4589
Closed

Markdown Widget Lagging when Opening Large Files #4586

VexiaOnline opened this issue Jun 2, 2024 · 2 comments · Fixed by #4589

Comments

@VexiaOnline
Copy link

Description:

I've encountered an issue where the Markdown Widget in Textual takes an excessively long time to load "large" markdown files, causing the application to freeze and become unresponsive. I put large in quotations because I'm not sure what the lower end of such a filesize is, I know it does it with a few hundred KB file, and davep has tested it with a much larger 7MB+ file.

Steps to Reproduce:

Run a large markdown file through the Markdown Widget, I put a LoadingIndicator on the Markdown widget where I would expect it to show the loading indicator while the file is being read and parsed.

Observe the app freeze completely while the markdown file is parsed, then LoadingIndicator is displaying briefly before the markdown is displayed within the widget.

Expected Behavior:
I expect the LoadingIndicator to display for a reasonable amount of time while parsing and rendering the markdown content.

davep helped test what was going on and the following are his observations and comments if they help:

Code Used:

from dataclasses import dataclass
from pathlib import Path

from textual import on, work
from textual.app import App, ComposeResult
from textual.message import Message
from textual.widgets import Button, Markdown

class LoadMarkdownApp(App[None]):

    CSS = """
    Markdown {
        border: solid red;
        height: 1fr;
    }
    """

    def compose(self) -> ComposeResult:
        yield Button()
        yield Markdown()

    @on(Button.Pressed)
    def start_load(self) -> None:
        self.query_one(Markdown).loading = True
        self.load_markdown()

    @dataclass
    class NewDocument(Message):
        markdown: str

    @work(thread=True)
    def load_markdown(self) -> None:
        self.post_message(
            self.NewDocument(Path("test.md").read_text())
        )

    @on(NewDocument)
    async def display_deocument(self, event: NewDocument) -> None:
        await self.query_one(Markdown).update(event.markdown)
        self.query_one(Markdown).loading = False

if __name__ == "__main__":
    LoadMarkdownApp().run()

davep:

When I run the above, the LoadingIndicator shows fine but then freezes, the app itself can't actually be stopped with ctrl+c either. Taking out the update in the NewDocument event handler has the loading indicator appear and disappear so fast I never see it.

This, for me, would indicate that the loading of the markdown file from storage happens pretty much instantly (no surprise on my setup here, M2Pro Mac Mini, SSD, etc...).

It looks like the issue is with Markdown.update; a large document is going to take some work to parse, I would suspect, so I imagine Markdown.update is bogged down in the main parsing loop. Off the top of my head I can't think of an easy workaround for handling that without that particular method being modified such that parsing isn't a blocking operation.

Indeed, unless I'm missing something obvious (not unlikely, one coffee into the work day and attention mostly on work things, not Textual), support for loading huge Markdown documents into the Markdown widget would seem to be something that is best baked into the Markdown widget itself (much like how DirectoryTree got an overhaul with similar motivations a year back).

Textual Diagnostics

Versions

Name Value
Textual 0.63.6
Rich 13.7.1

Python

Name Value
Version 3.10.12
Implementation CPython
Compiler GCC 11.4.0
Executable /usr/bin/python3

Operating System

Name Value
System Linux
Release 5.15.146.1-microsoft-standard-WSL2
Version #1 SMP Thu Jan 11 04:09:03 UTC 2024

Terminal

Name Value
Terminal Application Windows Terminal
TERM xterm-256color
COLORTERM Not set
FORCE_COLOR Not set
NO_COLOR Not set

Rich Console options

Name Value
size width=188, height=49
legacy_windows False
min_width 1
max_width 188
is_terminal True
encoding utf-8
max_height 49
justify None
overflow None
no_wrap False
highlight None
markup None
height None
Copy link

github-actions bot commented Jun 2, 2024

Thank you for your issue. Give us a little time to review it.

PS. You might want to check the FAQ if you haven't done so already.

This is an automated reply, generated by FAQtory

Copy link

github-actions bot commented Jun 3, 2024

Don't forget to star the repository!

Follow @textualizeio for Textual updates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant