From 9dec3118fa253ec5bac609b3f7ffb909aefb49a0 Mon Sep 17 00:00:00 2001 From: Benedikt Bartscher Date: Mon, 9 Feb 2026 11:09:28 +0100 Subject: [PATCH] wip - testing compile cache --- reflex/components/base/bare.py | 22 ++++++++++++++++++++-- reflex/components/component.py | 28 ++++++++++++++++++++++++++-- reflex/components/core/cond.py | 6 +++++- reflex/components/core/foreach.py | 6 +++++- reflex/components/core/match.py | 6 +++++- 5 files changed, 61 insertions(+), 7 deletions(-) diff --git a/reflex/components/base/bare.py b/reflex/components/base/bare.py index 4182d0666ba..c36d7e7f19d 100644 --- a/reflex/components/base/bare.py +++ b/reflex/components/base/bare.py @@ -95,10 +95,13 @@ def _get_all_hooks(self) -> dict[str, VarData | None]: Returns: The hooks for the component. """ + if (cached := self.__dict__.get("_cached_all_hooks")) is not None: + return cached hooks = super()._get_all_hooks() if isinstance(self.contents, Var): for component in _components_from_var(self.contents): hooks |= component._get_all_hooks() + self.__dict__["_cached_all_hooks"] = hooks return hooks def _get_all_imports(self, collapse: bool = False) -> ParsedImportDict: @@ -110,11 +113,18 @@ def _get_all_imports(self, collapse: bool = False) -> ParsedImportDict: Returns: The imports for the component. """ + if ( + not collapse + and (cached := self.__dict__.get("_cached_all_imports")) is not None + ): + return cached imports = super()._get_all_imports(collapse=collapse) if isinstance(self.contents, Var): var_data = self.contents._get_all_var_data() if var_data: imports |= {k: list(v) for k, v in var_data.imports} + if not collapse: + self.__dict__["_cached_all_imports"] = imports return imports def _get_all_dynamic_imports(self) -> set[str]: @@ -135,10 +145,13 @@ def _get_all_custom_code(self) -> dict[str, None]: Returns: The custom code. """ + if (cached := self.__dict__.get("_cached_all_custom_code")) is not None: + return cached custom_code = super()._get_all_custom_code() if isinstance(self.contents, Var): for component in _components_from_var(self.contents): custom_code |= component._get_all_custom_code() + self.__dict__["_cached_all_custom_code"] = custom_code return custom_code def _get_all_app_wrap_components( @@ -196,14 +209,19 @@ def render(self) -> dict: Returns: The rendered component. """ + if (cached := self.__dict__.get("_cached_render")) is not None: + return cached contents = ( Var.create(self.contents) if not isinstance(self.contents, Var) else self.contents ) if isinstance(contents, (BooleanVar, ObjectVar)): - return {"contents": f"{contents.to_string()!s}"} - return {"contents": f"{contents!s}"} + result = {"contents": f"{contents.to_string()!s}"} + else: + result = {"contents": f"{contents!s}"} + self.__dict__["_cached_render"] = result + return result def _add_style_recursive( self, style: ComponentStyle, theme: Component | None = None diff --git a/reflex/components/component.py b/reflex/components/component.py index 02773061b47..f8710b41ea3 100644 --- a/reflex/components/component.py +++ b/reflex/components/component.py @@ -1223,6 +1223,8 @@ def render(self) -> dict: Returns: The dictionary for template of component. """ + if (cached := self.__dict__.get("_cached_render")) is not None: + return cached tag = self._render() rendered_dict = dict( tag.set( @@ -1230,6 +1232,7 @@ def render(self) -> dict: ) ) self._replace_prop_names(rendered_dict) + self.__dict__["_cached_render"] = rendered_dict return rendered_dict def _replace_prop_names(self, rendered_dict: dict) -> None: @@ -1496,6 +1499,8 @@ def _get_all_custom_code(self) -> dict[str, None]: Returns: The custom code. """ + if (cached := self.__dict__.get("_cached_all_custom_code")) is not None: + return cached # Store the code in a set to avoid duplicates. code: dict[str, None] = {} @@ -1517,6 +1522,7 @@ def _get_all_custom_code(self) -> dict[str, None]: code |= child._get_all_custom_code() # Return the code. + self.__dict__["_cached_all_custom_code"] = code return code def _get_dynamic_imports(self) -> str | None: @@ -1648,10 +1654,18 @@ def _get_all_imports(self, collapse: bool = False) -> ParsedImportDict: Returns: The import dict with the required imports. """ + if ( + not collapse + and (cached := self.__dict__.get("_cached_all_imports")) is not None + ): + return cached imports_ = imports.merge_parsed_imports( self._get_imports(), *[child._get_all_imports() for child in self.children] ) - return imports.collapse_imports(imports_) if collapse else imports_ + result = imports.collapse_imports(imports_) if collapse else imports_ + if not collapse: + self.__dict__["_cached_all_imports"] = result + return result def _get_mount_lifecycle_hook(self) -> str | None: """Generate the component lifecycle hook. @@ -1805,6 +1819,8 @@ def _get_all_hooks(self) -> dict[str, VarData | None]: Returns: The code that should appear just before returning the rendered component. """ + if (cached := self.__dict__.get("_cached_all_hooks")) is not None: + return cached code = {} # Add the internal hooks for this component. @@ -1821,6 +1837,7 @@ def _get_all_hooks(self) -> dict[str, VarData | None]: for child in self.children: code.update(child._get_all_hooks()) + self.__dict__["_cached_all_hooks"] = code return code def get_ref(self) -> str | None: @@ -2439,13 +2456,20 @@ def _render_stateful_code( ) -> str: if not self.tag: return "" + cache_key = ( + "_cached_stateful_code_export" if export else "_cached_stateful_code" + ) + if (cached := self.__dict__.get(cache_key)) is not None: + return cached # Render the code for this component and hooks. - return stateful_component_template( + result = stateful_component_template( tag_name=self.tag, memo_trigger_hooks=self.memo_trigger_hooks, component=self.component, export=export, ) + self.__dict__[cache_key] = result + return result @classmethod def _fix_event_triggers( diff --git a/reflex/components/core/cond.py b/reflex/components/core/cond.py index e5a85b00622..dcacf53d5b0 100644 --- a/reflex/components/core/cond.py +++ b/reflex/components/core/cond.py @@ -72,11 +72,15 @@ def render(self) -> dict: Returns: The dictionary for template of component. """ - return { + if (cached := self.__dict__.get("_cached_render")) is not None: + return cached + result = { "cond_state": str(self.cond), "true_value": self.children[0].render(), "false_value": self.children[1].render(), } + self.__dict__["_cached_render"] = result + return result def add_imports(self) -> ImportDict: """Add imports for the Cond component. diff --git a/reflex/components/core/foreach.py b/reflex/components/core/foreach.py index 67dd3d83bbf..f86975d1d5f 100644 --- a/reflex/components/core/foreach.py +++ b/reflex/components/core/foreach.py @@ -163,14 +163,18 @@ def render(self): Returns: The dictionary for template of component. """ + if (cached := self.__dict__.get("_cached_render")) is not None: + return cached tag = self._render() - return dict( + result = dict( tag, iterable_state=str(tag.iterable), arg_name=tag.arg_var_name, arg_index=tag.index_var_name, ) + self.__dict__["_cached_render"] = result + return result foreach = Foreach.create diff --git a/reflex/components/core/match.py b/reflex/components/core/match.py index b6ecf02fbea..6c78794806c 100644 --- a/reflex/components/core/match.py +++ b/reflex/components/core/match.py @@ -279,7 +279,11 @@ def render(self) -> dict: Returns: The dictionary for template of component. """ - return dict(self._render()) + if (cached := self.__dict__.get("_cached_render")) is not None: + return cached + result = dict(self._render()) + self.__dict__["_cached_render"] = result + return result def add_imports(self) -> ImportDict: """Add imports for the Match component.