PromucFlow_constructor/app/client/src/ce/entities/DataTree/utils.ts
Vemparala Surya Vamsi 5232b3f89e
chore: cache theme value properties, since it is a frequent property (#41031)
## Description
Added caching of theme property value since it is a frequent expression,
it constitutes 20% of all binding expressions for a large customer app.
Expecting a 400ms reduction in LCP for a large customer app.

Fixes #`Issue Number`  
_or_  
Fixes `Issue URL`
> [!WARNING]  
> _If no issue exists, please create an issue first, and check with the
maintainers if the issue is valid._

## Automation

/ok-to-test tags="@tag.All"

### 🔍 Cypress test results
<!-- This is an auto-generated comment: Cypress test results  -->
> [!TIP]
> 🟢 🟢 🟢 All cypress tests have passed! 🎉 🎉 🎉
> Workflow run:
<https://github.com/appsmithorg/appsmith/actions/runs/15880337835>
> Commit: 11fab20fe285aa1b3b59c164179902628d35d97d
> <a
href="https://internal.appsmith.com/app/cypress-dashboard/rundetails-65890b3c81d7400d08fa9ee5?branch=master&workflowId=15880337835&attempt=2"
target="_blank">Cypress dashboard</a>.
> Tags: `@tag.All`
> Spec:
> <hr>Wed, 25 Jun 2025 17:45:37 UTC
<!-- end of auto-generated comment: Cypress test results  -->


## Communication
Should the DevRel and Marketing teams inform users about this change?
- [ ] Yes
- [ ] No


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Summary by CodeRabbit

- **New Features**
- Improved performance when evaluating theme-related properties by
introducing caching for repeated values.

- **Chores**
- Added a utility to identify specific theme-related unevaluated values.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
2025-06-26 11:03:13 +05:30

98 lines
2.9 KiB
TypeScript

import type {
PropertyOverrideDependency,
OverridingPropertyPaths,
WidgetEntity,
ActionEntity,
JSActionEntity,
} from "ee/entities/DataTree/types";
import type { DataTreeEntity } from "entities/DataTree/dataTreeTypes";
import { OverridingPropertyType } from "ee/entities/DataTree/types";
import {
isAction,
isJSAction,
isWidget,
} from "ee/workers/Evaluation/evaluationUtils";
import type { Module } from "ee/constants/ModuleConstants";
interface SetOverridingPropertyParams {
key: string;
value: string;
propertyOverrideDependency: PropertyOverrideDependency;
overridingPropertyPaths: OverridingPropertyPaths;
type: OverridingPropertyType;
}
export const setOverridingProperty = ({
key: propertyName,
overridingPropertyPaths,
propertyOverrideDependency,
type,
value: overridingPropertyKey,
}: SetOverridingPropertyParams) => {
if (!(propertyName in propertyOverrideDependency)) {
propertyOverrideDependency[propertyName] = {
[OverridingPropertyType.DEFAULT]: undefined,
[OverridingPropertyType.META]: undefined,
};
}
switch (type) {
case OverridingPropertyType.DEFAULT:
propertyOverrideDependency[propertyName][OverridingPropertyType.DEFAULT] =
overridingPropertyKey;
break;
case OverridingPropertyType.META:
propertyOverrideDependency[propertyName][OverridingPropertyType.META] =
overridingPropertyKey;
break;
default:
}
if (Array.isArray(overridingPropertyPaths[overridingPropertyKey])) {
const updatedOverridingProperty = new Set(
overridingPropertyPaths[overridingPropertyKey],
);
overridingPropertyPaths[overridingPropertyKey] = [
...updatedOverridingProperty.add(propertyName),
];
} else {
overridingPropertyPaths[overridingPropertyKey] = [propertyName];
}
// if property dependent on metaProperty also has defaultProperty then defaultProperty will also override metaProperty on eval.
const defaultPropertyName = propertyOverrideDependency[propertyName].DEFAULT;
if (type === OverridingPropertyType.META && defaultPropertyName) {
overridingPropertyPaths[defaultPropertyName].push(overridingPropertyKey);
}
};
export const generateDataTreeModuleInputs = (
// eslint-disable-next-line @typescript-eslint/no-unused-vars
moduleInputs: Module["inputsForm"],
) => {
return {
unEvalEntity: null,
configEntity: null,
};
};
export function isWidgetActionOrJsObject(
entity: DataTreeEntity,
): entity is ActionEntity | WidgetEntity | JSActionEntity {
return isWidget(entity) || isAction(entity) || isJSAction(entity);
}
const THEME_PROPERTIES = new Set([
"{{appsmith.theme.fontFamily.appFont}}",
"{{appsmith.theme.boxShadow.appBoxShadow}}",
"{{appsmith.theme.colors.primaryColor}}",
"{{appsmith.theme.borderRadius.appBorderRadius}}",
]);
export function isThemeUnevaluatedValue(value: string): boolean {
return THEME_PROPERTIES.has(value);
}