You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@myfaces.apache.org by ta...@apache.org on 2026/06/03 07:30:30 UTC
(myfaces) 01/02: [perf] cache parent UINamingContainer
This is an automated email from the ASF dual-hosted git repository.
tandraschko pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/myfaces.git
commit b151ff00654c0151091e6100980019f004b0240c
Author: tandraschko <ta...@apache.org>
AuthorDate: Tue Jun 2 17:27:53 2026 +0200
[perf] cache parent UINamingContainer
---
.../jakarta/faces/component/UIComponentBase.java | 30 ++++++++++++++++++++--
1 file changed, 28 insertions(+), 2 deletions(-)
diff --git a/api/src/main/java/jakarta/faces/component/UIComponentBase.java b/api/src/main/java/jakarta/faces/component/UIComponentBase.java
index 0d989515e..e73fcb2ab 100755
--- a/api/src/main/java/jakarta/faces/component/UIComponentBase.java
+++ b/api/src/main/java/jakarta/faces/component/UIComponentBase.java
@@ -99,6 +99,8 @@ public abstract class UIComponentBase extends UIComponent
private UIComponent _parent = null;
private boolean _transient = false;
+ private transient UIComponent _closestNamingContainer;
+
private String _rendererType;
private String _markCreated;
private String _facetName;
@@ -170,6 +172,11 @@ public void setId(String id)
@Override
public void setParent(UIComponent parent)
{
+ // The parent chain is changing — the cached NamingContainer ancestor is no longer valid.
+ // setId must NOT clear it: UIData/UIRepeat call setId(getId()) per row on every descendant,
+ // and the ancestor depends only on the parent chain which setId never changes.
+ _closestNamingContainer = null;
+
// removing kids OR this is UIViewRoot
if (parent == null)
{
@@ -906,7 +913,7 @@ public String getClientId(FacesContext context)
setId(id);
}
- UIComponent namingContainer = ComponentUtils.findClosestNamingContainer(this, false);
+ UIComponent namingContainer = getClosestNamingContainer();
if (namingContainer != null)
{
String containerClientId = namingContainer.getContainerClientId(context);
@@ -947,7 +954,26 @@ public String getClientId(FacesContext context)
return _clientId;
}
-
+
+ /**
+ * Returns the closest NamingContainer ancestor, caching the result so that repeated calls
+ * (e.g. once per UIRepeat/UIData row after setId clears _clientId) skip the parent-chain walk.
+ * Invalidated in setParent only — setId must NOT clear it.
+ */
+ private UIComponent getClosestNamingContainer()
+ {
+ if (_closestNamingContainer != null)
+ {
+ return _closestNamingContainer;
+ }
+ UIComponent closestNamingContainer = ComponentUtils.findClosestNamingContainer(this, false);
+ if (closestNamingContainer != null)
+ {
+ _closestNamingContainer = closestNamingContainer;
+ }
+ return closestNamingContainer;
+ }
+
/**
*
* @return