-
Notifications
You must be signed in to change notification settings - Fork 25k
Open
Labels
Needs: AttentionIssues where the author has responded to feedback.Issues where the author has responded to feedback.Needs: Version InfoNever gets stalePrevent those issues and PRs from getting stalePrevent those issues and PRs from getting stalePlatform: AndroidAndroid applications.Android applications.
Description
Description
Updating any property of a Nested Text, triggers a full update of all the properties.
The consequence is that multiple spans are added to the TextView to display the same duplicate property, on every re-render. The redundant update process can lead to performance issues or unexpected behavior due to the unnecessary creation of spans.
- I opened this issue to ask opinion from the React Native Team.
- I would publish a series of Pull Request to improve React Native Nested Text.
I found out about this issue while testing feature flags Enable prop diffing for View #45551 and Calculate Android mounting instructions based on updates accumulated in rawProps #48303.
Steps to reproduce
I reproduced the issue in latests react-native main branch (fabOnReact@e57bcd3).
- Open the file
packages/rn-tester/js/RNTesterAppShared.js - Copy paste the example below
- Run the RNTester App on Android
- Quickly type a lot of text in the TextInput and the TextInput typing will become slow
CLICK TO OPEN TESTS EXAMPLE
import React, {useState, useEffect} from 'react';
import {View, TextInput, Text, StyleSheet} from 'react-native';
export default function PartialSpanInput() {
const [prevText, setPrevText] = useState('');
const [newText, setNewText] = useState('');
const onChangeText = nativeText => {
const newTextWithRandomStyle = (
<Text>
{prevText}
<Text style={getRandomStyle()}>
{nativeText[nativeText.length - 1]}
</Text>
</Text>
);
setNewText(newTextWithRandomStyle);
};
useEffect(() => {
setPrevText(newText);
}, [newText]);
const RANDOM_COLORS = ['red', 'green', 'blue', 'orange', 'purple'];
const getRandomColor = () => {
return RANDOM_COLORS[Math.floor(Math.random() * RANDOM_COLORS.length)];
};
const getRandomStyle = () => {
return {
color: getRandomColor(),
fontSize: Math.floor(Math.random() * 20) + 10,
fontWeight: Math.random() > 0.5 ? 'bold' : 'normal',
};
};
return (
<View style={styles.container}>
<TextInput style={styles.input} multiline onChangeText={onChangeText}>
{prevText}
{newText}
</TextInput>
</View>
);
}
const styles = StyleSheet.create({
container: {flex: 1, padding: 20, backgroundColor: '#f0f0f0'},
input: {
flex: 1,
borderColor: '#ccc',
borderWidth: 1,
padding: 10,
},
});React Native Version
latest
Affected Platforms
Runtime - Android
Output of npx @react-native-community/cli info
info Fetching system and libraries information...
System:
OS: macOS 15.3.2
CPU: (10) arm64 Apple M1 Pro
Memory: 156.53 MB / 16.00 GB
Shell:
version: "5.9"
path: /bin/zsh
Binaries:
Node:
version: 22.14.0
path: /nix/store/2yk2lr8y92mmkr4kcwwdlnr4hscvnps2-nodejs-22.14.0/bin/node
Yarn:
version: 1.22.19
path: ~/.nix-profile/bin/yarn
npm:
version: 10.9.2
path: /nix/store/2yk2lr8y92mmkr4kcwwdlnr4hscvnps2-nodejs-22.14.0/bin/npm
Watchman:
version: 2024.03.11.00
path: /Users/fabriziobertoglio/.nix-profile/bin/watchman
Managers:
CocoaPods:
version: 1.15.2
path: /Users/fabriziobertoglio/.nix-profile/bin/pod
SDKs:
iOS SDK:
Platforms:
- DriverKit 24.2
- iOS 18.2
- macOS 15.2
- tvOS 18.2
- visionOS 2.2
- watchOS 11.2
Android SDK:
API Levels:
- "28"
- "30"
- "31"
- "32"
- "33"
- "34"
- "35"
Build Tools:
- 28.0.2
- 28.0.3
- 29.0.0
- 30.0.2
- 30.0.3
- 31.0.0
- 32.0.0
- 32.1.0
- 33.0.0
- 33.0.1
- 34.0.0
- 35.0.0
System Images:
- android-22 | ARM 64 v8a
- android-28 | Google ARM64-V8a Play ARM 64 v8a
- android-30 | China version of Wear OS 3 ARM 64 v8a
- android-30 | Wear OS 3 ARM 64 v8a
- android-31 | ARM 64 v8a
- android-31 | Google APIs ARM 64 v8a
- android-31 | Google Play ARM 64 v8a
- android-33 | Wear OS 4 ARM 64 v8a
- android-33 | Google APIs ARM 64 v8a
- android-33 | Google Play ARM 64 v8a
- android-35 | Google Play ARM 64 v8a
- android-Tiramisu | Google TV ARM 64 v8a
- android-Tiramisu | Google Play ARM 64 v8a
Android NDK: Not Found
IDEs:
Android Studio: 2024.2 AI-242.23339.11.2421.12700392
Xcode:
version: 16.2/16C5032a
path: /usr/bin/xcodebuild
Languages:
Java:
version: 17.0.14
path: /usr/bin/javac
Ruby:
version: 2.6.10
path: /Users/fabriziobertoglio/.rbenv/shims/ruby
npmPackages:
"@react-native-community/cli": Not Found
react:
installed: 19.0.0
wanted: 19.0.0
react-native: Not Found
react-native-macos: Not Found
npmGlobalPackages:
"*react-native*": Not Found
Android:
hermesEnabled: Not found
newArchEnabled: Not found
iOS:
hermesEnabled: Not found
newArchEnabled: Not found
Stacktrace or Logs
04-15 20:53:52.387 13424 13424 W unknown:SetSpanOperation: Text tree size exceeded the limit, styling may become unpredictable
04-15 20:53:52.387 13424 13424 W unknown:SetSpanOperation: Text tree size exceeded the limit, styling may become unpredictable
04-15 20:53:52.387 13424 13424 W unknown:SetSpanOperation: Text tree size exceeded the limit, styling may become unpredictable
04-15 20:53:52.388 13424 13424 W unknown:SetSpanOperation: Text tree size exceeded the limit, styling may become unpredictable
04-15 20:53:52.388 13424 13424 W unknown:SetSpanOperation: Text tree size exceeded the limit, styling may become unpredictable
04-15 20:53:52.388 13424 13424 W unknown:TESTING : ReactTextInputManager updateExtraData com.facebook.react.views.text.ReactTextUpdate@52640cf
04-15 20:53:52.393 589 681 I InputDispatcher: Dropped event because it is stale.
04-15 20:53:52.393 589 681 I InputDispatcher: Dropped event because it is stale.
04-15 20:53:52.394 589 681 I InputDispatcher: Dropped event because it is stale.
04-15 20:53:52.394 589 681 I InputDispatcher: Dropped event because it is stale.
04-15 20:53:52.394 589 681 I InputDispatcher: Dropped event because it is stale.
04-15 20:53:52.394 589 681 I InputDispatcher: Dropped event because it is stale.
04-15 20:53:52.394 589 681 I InputDispatcher: Dropped event because it is stale.
04-15 20:53:52.394 589 681 I InputDispatcher: Dropped event because it is stale.
04-15 20:53:52.398 13424 13452 D EGL_emulation: app_time_stats: avg=1042.04ms min=811.05ms max=1273.02ms count=2
04-15 20:53:52.401 13424 13424 E unknown:TextLayoutManager: Set cached spannable for tag[4]: sdfsdfsd fsdafsdasadfdfsadfsdfsadfdfsdafasdfffffffffsdfsadffffffffffffffffffffffffffffffffffffffffffffffsdfsdfsd sdfsadfasdf
04-15 20:53:52.408 13424 13424 E unknown:TextLayoutManager: Set cached spannable for tag[4]: sdfsdfsd fsdafsdasadfdfsadfsdfsadfdfsdafasdfffffffffsdfsadffffffffffffffffffffffffffffffffffffffffffffffsdfsdfsd sdfsadfasdf
04-15 20:53:52.410 13424 13435 I OpenGLRenderer: Davey! duration=1266ms; Flags=0, FrameTimelineVsyncId=2754480, IntendedVsync=8044640266836, Vsync=8045706933460, InputEventId=56290598, HandleInputStart=8045723091835, AnimationStart=8045723092585, PerformTraversalsStart=8045892193794, DrawStart=8045893104710, FrameDeadline=8044673600168, FrameInterval=8045723030669, FrameStartTime=16666666, SyncQueued=8045894010877, SyncStart=8045894073794, IssueDrawCommandsStart=8045894113294, SwapBuffers=8045896157669, FrameCompleted=8045907210294, DequeueBufferDuration=2708, QueueBufferDuration=301209, GpuCompleted=8045907210294, SwapBuffersCompleted=8045898767544, DisplayPresentTime=8018659472906, CommandSubmissionCompleted=8045896157669,
04-15 20:53:52.634 589 681 I InputDispatcher: Dropped event because it is stale.
04-15 20:53:52.634 589 681 I InputDispatcher: Dropped event because it is stale.
04-15 20:53:52.634 589 681 I InputDispatcher: Dropped event because it is stale.
04-15 20:53:52.635 589 681 I InputDispatcher: Dropped event because it is stale.
04-15 20:53:52.636 589 681 I InputDispatcher: Dropped event because it is stale.
04-15 20:53:52.636 589 681 I InputDispatcher: Dropped event because it is stale.
04-15 20:53:52.636 589 681 W InputDispatcher: Dispatching key to 861e36b com.facebook.react.uiapp/com.facebook.react.uiapp.RNTesterActivity even though there are other unprocessed events
Reproducer
Screenshots and Videos
The video was re-encoded with ffmpeg to decrease the size.
output.mp4
Metadata
Metadata
Assignees
Labels
Needs: AttentionIssues where the author has responded to feedback.Issues where the author has responded to feedback.Needs: Version InfoNever gets stalePrevent those issues and PRs from getting stalePrevent those issues and PRs from getting stalePlatform: AndroidAndroid applications.Android applications.