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

Most of the Frontend Compile Time is Occupied by rx.icon #4627

Open
ruhz3 opened this issue Jan 13, 2025 · 4 comments
Open

Most of the Frontend Compile Time is Occupied by rx.icon #4627

ruhz3 opened this issue Jan 13, 2025 · 4 comments
Assignees
Labels
enhancement Anything you want improved

Comments

@ruhz3
Copy link
Contributor

ruhz3 commented Jan 13, 2025

I am using rx.icon to conditionally render icons in components, as shown below:

def dynamic_icon(icon_name: str, **props) -> rx.Component:
    return rx.match(
        icon_name,
        ("wand", rx.icon("wand", **props)),
        ("wand-sparkles", rx.icon("wand-sparkles", **props)),
        ("search", rx.icon("search", **props)),
        ("message-circle-question", rx.icon("message-circle-question", **props)),
        ("paperclip", rx.icon("paperclip", **props)),
        ...
    )

However, as the number of icons increased, the frontend compilation time started exceeding 2 minutes. To mitigate this during development, I switched to using the default value in rx.match as shown below:

def dynamic_icon(icon_name: str, **props) -> rx.Component:
    return rx.match(
        icon_name,
        # ("wand", rx.icon("wand", **props)),
        # ("wand-sparkles", rx.icon("wand-sparkles", **props)),
        # ("search", rx.icon("search", **props)),
        # ("message-circle-question", rx.icon("message-circle-question", **props)),
        # ("paperclip", rx.icon("paperclip", **props)),
        ...
        rx.icon("paperclip", **props)
    )

With this change, the compilation time was reduced to about 10 seconds.

Is there a better approach to handle this efficiently?

@ruhz3 ruhz3 added the enhancement Anything you want improved label Jan 13, 2025
Copy link

linear bot commented Jan 13, 2025

@Lendemor
Copy link
Collaborator

We've recently merged this PR : #4636 which used the newly define DynamicIcon from Lucide.
If you have a lot of icons, you might be able to substitute the rx.matchs with a variable tag.

Caveat is that actual live performance might be worse while in prod mode.

@ruhz3
Copy link
Contributor Author

ruhz3 commented Jan 21, 2025

@Lendemor
I really like the new feature. In that case, which is better in terms of performance: using "rx.match" as we currently do, or the new "dynamic icon" feature?

Currently, due to compile speed, we unify all project icons into one during development and only switch to individual icons when a build is required (as mentioned in the issue details).

Does the dynamic icon feature address this issue?

@Lendemor
Copy link
Collaborator

According to lucide docs, DynamicIcon usage should be preferred mostly when you want to accept any/ large amount of different icons, like if the tag was stored in DB or such.

Regarding compilation performance for dev, I would recommend setting up a whitelist system like we did in reflex-web.
This allow us to only compile the page(s) we are working on now in reflex run, but still compile all of them when doing export/deploy.

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

No branches or pull requests

2 participants