react / react/react-native

TextInput becomes slow after lots of typing

オープン
#20,119 コメント 108 件 リアクション 69 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

Bug Component: TextInput Impact: Regression Platform: Android Ran Commands
主要言語
C++
スター
127k
フォーク
25.3k
平均マージ
1日 23時間
マージ済み PR(30日)
4

説明

Environment

$ react-native info
Environment:
  OS: Linux 4.9
  Node: 8.11.3
  Yarn: 1.7.0
  npm: 5.6.0
  Watchman: Not Found
  Xcode: N/A
  Android Studio: Not Found

Packages: (wanted => installed)
  react: 16.3.1 => 16.3.1
  react-native: 0.56.0 => 0.56.0 (*)

(*) In my test app, actually v0.55.4 plus the patch from #19645 . Others on #19126 report the same symptoms using v0.56.

Description

After typing a lot of text into a controlled TextInput, like ~500 char on a recent fast phone, we start dropping frames. It gets worse the more you type; at ~1000 char, we very frequently drop frames and the app looks noticeably laggy.

Reproducible Demo

The original repro is by @s-nel: https://github.com/s-nel/rn19126

Originally reported at https://github.com/facebook/react-native/issues/19126#issuecomment-402904164; more discussion in subsequent comments in that thread.

In particular, here's the video from that repro:
video

Here's a video by @s-nel on my test app, with this description:

Yes I can reproduce from [that repo] after typing for a couple minutes straight. I don't have to clear anything as the original bug description [in #19126] indicates. Here you can see my JS framerate drop to single digits from adding a few characters

image

Here's my description of replicating that repro, again in my test app:

I just tried again with my test app, on RN 0.55.4 + patch. If I type continuously for about 60 seconds -- maybe 400-500 characters, at a rough estimate (just gibberish, both thumbs constantly typing letters) -- then the perf overlay gets to about "10 dropped so far", and zero stutters. If I continue and get up to about 90 seconds, the "dropped" figure climbs faster, and the framerate (in "JS: __ fps") noticeably drops. At about 150 seconds (~1000 characters?), the "dropped" figure rapidly climbs past 200, and the framerate hangs out around 30.

Even at that point, it's still "0 stutters". And if I ignore the perf overlay and try typing normal text and watching it like I were using an app for real: it's a bit laggy, but doesn't make things feel unusable or outright broken, and I think most of the time I wouldn't even notice.

That was on a Pixel 2 XL; the numbers will probably vary with hardware.

Background from previous bug

This bug seems closely related to #19126; the repro steps and symptoms seem to be exactly the same, except quantitatively much less severe. (The original reports of #19126 describe clearing the input as part of the repro; I now think that was probably a red herring.)

The extreme symptoms of #19126 were absent in v0.54, introduced in v0.55, and fixed in v0.56 by #19645 . As I wrote when I figured out the cause of that (leading to the one-line fix in #19645):

[This buggy NaN comparison] means every text shadow node will create a CustomLetterSpacingSpan around its contents, even when the letterSpacing prop was never set. It must be that we're somehow ending up with large numbers of these shadow nodes -- that sounds like a bug in itself, but I guess it's normally low-impact -- and this condition is failing to prune them from causing a bunch of work here.

I think we're now looking at exactly that underlying bug. It may well have been present in v0.54 and earlier releases; I don't think we have any data on that. [EDIT: @piotrpazola finds below that the bug is present in v0.50, and absent in v0.49.]

I don't know anything more about what causes it; even the hypothesis that we're ending up with large numbers of text shadow nodes is just an inference from how it interacts with the line fixed in #19645. So, more debugging is required.

I don't expect to do that debugging myself, because these remaining symptoms are no longer one of the top issues in our own app. But I hope somebody else will!

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

リンクされている rn19126 と rn-textinput-test の再現手順から始め、パフォーマンスオーバーレイを監視しながら、制御された TextInput の低速化を再現してください。テキストシャドウノードの蓄積が疑われる問題と、#19645 の修正との相互作用を調査してください。根本原因が特定され、継続的な入力パフォーマンスの問題が対処され、報告された再現手順に対して検証されれば完了です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
react-native
領域
mobile-dev, performance
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
静か
明瞭さ
説明が足りない
初心者へのやさしさ
35/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。