Add feature flag for spannable cache

Summary:
sSpannableCache is a significant user of Java heap memory - up to 0.22MB is retained by sSpannableCache.

It turns out sSpannableCache was never hitting as hashCode is different for the same attributedString contents. attributedString.getInt("hash") provides the expected hash code.

This indicates removing spannableCache will not affect perf. Will gate just in case though.

Changelog: [Internal]

Reviewed By: mdvacca

Differential Revision: D34900414

fbshipit-source-id: 7563cde6ba9dc153072e7aebede99389ce3153e7
This commit is contained in:
Genki Kondo
2022-03-16 10:38:50 -07:00
committed by Facebook GitHub Bot
parent e5874d90e2
commit b2454f9e66
2 changed files with 20 additions and 10 deletions
@@ -109,4 +109,7 @@ public class ReactFeatureFlags {
* JNI.
*/
public static boolean enableLargeTextMeasureCache = true;
/** TODO: T113245006 Delete this flag. Enables caching of spannables for text */
public static boolean enableSpannableCache = false;
}
@@ -31,6 +31,7 @@ import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableNativeMap;
import com.facebook.react.bridge.WritableArray;
import com.facebook.react.common.build.ReactBuildConfig;
import com.facebook.react.config.ReactFeatureFlags;
import com.facebook.react.uimanager.PixelUtil;
import com.facebook.react.uimanager.ReactAccessibilityDelegate;
import com.facebook.react.uimanager.ReactStylesDiffMap;
@@ -197,19 +198,25 @@ public class TextLayoutManager {
Spannable preparedSpannableText;
synchronized (sSpannableCacheLock) {
preparedSpannableText = sSpannableCache.get((ReadableNativeMap) attributedString);
if (preparedSpannableText != null) {
return preparedSpannableText;
if (ReactFeatureFlags.enableSpannableCache) {
synchronized (sSpannableCacheLock) {
preparedSpannableText = sSpannableCache.get((ReadableNativeMap) attributedString);
if (preparedSpannableText != null) {
return preparedSpannableText;
}
}
}
preparedSpannableText =
createSpannableFromAttributedString(
context, attributedString, reactTextViewManagerCallback);
preparedSpannableText =
createSpannableFromAttributedString(
context, attributedString, reactTextViewManagerCallback);
synchronized (sSpannableCacheLock) {
sSpannableCache.put((ReadableNativeMap) attributedString, preparedSpannableText);
synchronized (sSpannableCacheLock) {
sSpannableCache.put((ReadableNativeMap) attributedString, preparedSpannableText);
}
} else {
preparedSpannableText =
createSpannableFromAttributedString(
context, attributedString, reactTextViewManagerCallback);
}
return preparedSpannableText;