Repository: reflex-dev/reflex

Issue:
dynamic icons causes next to never halt
![Image](https://github.com/user-attachments/assets/74d61a44-970a-40ae-89cc-cd6d380719ce)

When using rx.match for example in gathering icon by dict/list using a foreach it rises the cpu to 50+%

When removing the rx component addition it "only" adds 20% on each tab

code example:

```python
import reflex as rx

class LandingState(rx.State):
    features: dict[str, dict] = {
        "fast": {
            "title": "test1",
            "description": "test2",
            "icon": "zap"
        },
        "secure": {
            "title": "test2",
            "description": "test2",
            "icon": "lock"
        },
        "global": {
            "title": "test3",
            "description": "test3",
            "icon": "globe"
        }
    }

def feature_card(feature: str) -> rx.Component:
    
    icon_name = rx.match(
        feature,
        ("fast", "zap"),
        ("secure", "lock"),
        ("global", "globe"),
        "zap"  # Default fallback
    )

    return rx.card(
        rx.vstack(
            rx.icon(
                icon_name,
                size=32,
            ),
        ),
    )

def features_section() -> rx.Component:
    return rx.vstack(
        rx.hstack(
            rx.foreach(
                LandingState.features.keys(),
                lambda feature: feature_card(feature)
            ),
            spacing="6",
            justify="center",
            wrap="wrap",
            width="100%",
            padding="2em",
        ),
    )

@rx.page(route="/test", title="Test")
def test() -> rx.Component:
    return rx.vstack(
        features_section(),
        spacing="0",
        width="100%",
        background="#151515",
    )
```


Discussion:
<p><a href="https://linear.app/reflex-dev/issue/ENG-5266/high-cpu-usage-when-using-rxmatch">ENG-5266 High CPU usage when using rx.match</a></p>
workaround would be using a rx.cond:

```python
            rx.cond(
                feature == "fast",
                rx.icon("zap", size=32),
                rx.cond(
                    feature == "secure", 
                    rx.icon("lock", size=32),
                    rx.icon("globe", size=32)
                )
            ),
```
nextjs downgrade is to blame for that 😔 



Patch:
diff --git a/reflex/config.py b/reflex/config.py
index f3c6417898..cc21bbb39f 100644
--- a/reflex/config.py
+++ b/reflex/config.py
@@ -703,7 +703,7 @@ class EnvironmentVariables:
     REFLEX_STATE_SIZE_LIMIT: EnvVar[int] = env_var(1000)
 
     # Whether to use the turbopack bundler.
-    REFLEX_USE_TURBOPACK: EnvVar[bool] = env_var(True)
+    REFLEX_USE_TURBOPACK: EnvVar[bool] = env_var(False)
 
     # Additional paths to include in the hot reload. Separated by a colon.
     REFLEX_HOT_RELOAD_INCLUDE_PATHS: EnvVar[list[Path]] = env_var([])
@@ -815,6 +815,9 @@ class Config:  # pyright: ignore [reportIncompatibleVariableOverride]
     # Whether to enable or disable nextJS gzip compression.
     next_compression: bool = True
 
+    # Whether to enable or disable NextJS dev indicator.
+    next_dev_indicators: bool = False
+
     # Whether to use React strict mode in nextJS
     react_strict_mode: bool = True
 
diff --git a/reflex/constants/installer.py b/reflex/constants/installer.py
index d234780d0f..eca97f8af7 100644
--- a/reflex/constants/installer.py
+++ b/reflex/constants/installer.py
@@ -2,6 +2,7 @@
 
 from __future__ import annotations
 
+import os
 from types import SimpleNamespace
 
 from .base import IS_WINDOWS
@@ -84,7 +85,7 @@ class Commands(SimpleNamespace):
         "@emotion/react": "11.14.0",
         "axios": "1.8.3",
         "json5": "2.2.3",
-        "next": "15.0.4",
+        "next": os.getenv("NEXTJS_VERSION", "15.2.4"),
         "next-sitemap": "4.2.3",
         "next-themes": "0.4.6",
         "react": "19.0.0",
diff --git a/reflex/utils/prerequisites.py b/reflex/utils/prerequisites.py
index 81aa97f05f..399b3201d7 100644
--- a/reflex/utils/prerequisites.py
+++ b/reflex/utils/prerequisites.py
@@ -1067,6 +1067,7 @@ def _update_next_config(
         "compress": config.next_compression,
         "trailingSlash": True,
         "staticPageGenerationTimeout": config.static_page_generation_timeout,
+        "devIndicators": config.next_dev_indicators,
     }
     if transpile_packages:
         next_config["transpilePackages"] = list(


Test patch:
diff --git a/tests/units/test_prerequisites.py b/tests/units/test_prerequisites.py
index 3df2337ea9..9abc227fee 100644
--- a/tests/units/test_prerequisites.py
+++ b/tests/units/test_prerequisites.py
@@ -32,7 +32,7 @@
                 app_name="test",
             ),
             False,
-            'module.exports = {basePath: "", compress: true, trailingSlash: true, staticPageGenerationTimeout: 60};',
+            'module.exports = {basePath: "", compress: true, trailingSlash: true, staticPageGenerationTimeout: 60, devIndicators: false};',
         ),
         (
             Config(
@@ -40,7 +40,7 @@
                 static_page_generation_timeout=30,
             ),
             False,
-            'module.exports = {basePath: "", compress: true, trailingSlash: true, staticPageGenerationTimeout: 30};',
+            'module.exports = {basePath: "", compress: true, trailingSlash: true, staticPageGenerationTimeout: 30, devIndicators: false};',
         ),
         (
             Config(
@@ -48,7 +48,7 @@
                 next_compression=False,
             ),
             False,
-            'module.exports = {basePath: "", compress: false, trailingSlash: true, staticPageGenerationTimeout: 60};',
+            'module.exports = {basePath: "", compress: false, trailingSlash: true, staticPageGenerationTimeout: 60, devIndicators: false};',
         ),
         (
             Config(
@@ -56,7 +56,7 @@
                 frontend_path="/test",
             ),
             False,
-            'module.exports = {basePath: "/test", compress: true, trailingSlash: true, staticPageGenerationTimeout: 60};',
+            'module.exports = {basePath: "/test", compress: true, trailingSlash: true, staticPageGenerationTimeout: 60, devIndicators: false};',
         ),
         (
             Config(
@@ -65,14 +65,22 @@
                 next_compression=False,
             ),
             False,
-            'module.exports = {basePath: "/test", compress: false, trailingSlash: true, staticPageGenerationTimeout: 60};',
+            'module.exports = {basePath: "/test", compress: false, trailingSlash: true, staticPageGenerationTimeout: 60, devIndicators: false};',
         ),
         (
             Config(
                 app_name="test",
             ),
             True,
-            'module.exports = {basePath: "", compress: true, trailingSlash: true, staticPageGenerationTimeout: 60, output: "export", distDir: "_static"};',
+            'module.exports = {basePath: "", compress: true, trailingSlash: true, staticPageGenerationTimeout: 60, devIndicators: false, output: "export", distDir: "_static"};',
+        ),
+        (
+            Config(
+                app_name="test",
+                next_dev_indicators=True,
+            ),
+            True,
+            'module.exports = {basePath: "", compress: true, trailingSlash: true, staticPageGenerationTimeout: 60, devIndicators: true, output: "export", distDir: "_static"};',
         ),
     ],
 )