LoginSignup
5
2

View.GONEとView.INVISIBLEの再描画パフォーマンスを比較してみた

Last updated at Posted at 2023-08-05

この記事は

AndroidViewでViewを非表示にする場合、Viewに対してView.GONEView.INVISIBLEを適用させると思います。(それぞれ違いについては他の記事に詳しく書いてあるのでそちらを参照してください)
しかし、APIの結果や時間の経過によってViewを表示・非表示させたい時がある場合はどちらを適用させたらいいか分からない場合があると思うのでPerfettoを使用してそれぞれの再描画パフォーマンスについて比較していきます

結論

Viewの表示・非表示が繰り返されそうな場合はView.INVISIBLEを使用しましょう

検証

使用したツール

Perfetto
ADBを介してAndroidデバイスからパフォーマンス情報を収集するためのツールです。GUI上で簡単に可視化出来るためこちらを使用しました

測定方法

TextViewを表示させてから2秒後に非表示にします、それから2秒後に再描画させたタイミングで測定しています

MainActivity.kt
class MainActivity : AppCompatActivity() {

  private lateinit var binding: ActivityMainBinding

  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    binding = ActivityMainBinding.inflate(layoutInflater)
    setContentView(binding.root)

    CoroutineScope(Dispatchers.Main).launch {
      delay(2000)
      binding.textView.visibility = View.INVISIBLE or View.GONE
      delay(2000)
      binding.textView.visibility = View.VISIBLE // ← このタイミングで測定
    }
  }
}

activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
  xmlns:app="http://schemas.android.com/apk/res-auto"
  xmlns:tools="http://schemas.android.com/tools"
  android:layout_width="match_parent"
  android:layout_height="match_parent"
  tools:context=".MainActivity"
  >
  <TextView
    android:id="@+id/textView"
    android:layout_width="wrap_content"
    android:layout_height="wrap_content"
    android:text="Hello World!"
    app:layout_constraintBottom_toBottomOf="parent"
    app:layout_constraintEnd_toEndOf="parent"
    app:layout_constraintStart_toStartOf="parent"
    app:layout_constraintTop_toTopOf="parent"
    />

</androidx.constraintlayout.widget.ConstraintLayout>

結果

View.INVISIBLEの場合であれば即座に描画が開始されますが、一方のView.GONEの場合であれば描画が開始されるまでにmeasureとlayoutの処理が走っており、描画までに多少時間がかかってしまいます。描画開始から描画終了までの時間(Wall duration)も二倍以上の差が出ています。
おそらくですが、View.GONEの場合レイアウト自体が変更になるため、再描画の際にレイアウトの再構築も行わないといけないためなのかな〜と思われます

View.GONE

スクリーンショット 2023-08-06 午前12.17.21.png

Name Wall duration (ms) Avg Wall duration (ms)
Total 35.199789
Choreographer#doFrame 533822 6.979583 6.979583
traversal 6.932708 6.932708
draw 5.298625 5.298625
postAndWait 4.433833 4.433833
DrawFrames 533822 4.400208 4.400208
Drawing 0.00 0.00 1080.00 2220.00 4.281625 4.281625
measure 1.093 1.093
Record View#draw() 0.779208 0.779208
flush commands 0.360333 0.360333
layout 0.275416 0.275416

View.INVISIBLE

スクリーンショット 2023-08-06 午前12.17.57.png

Name Wall duration (ms) Avg Wall duration (ms)
Total 14.539373
DrawFrames 521826 2.568709 2.568709
Drawing 0.00 0.00 1080.00 2220.00 2.533916 2.533916
Choreographer#doFrame 521826 2.370708 2.370708
traversal 2.343959 2.343959
draw 2.263 2.263
postAndWait 2.149042 2.149042
flush commands 0.099833 0.099833
Record View#draw() 0.076166 0.076166

補足

念の為測定にあたっては、前後の影響を受けさせないために複数回測定しましたがどれも同じような結果でした

Wall duration (Total)

View.INVISIBLEの場合(14.5ms)→View.INVISIBLEの場合(15.4ms)→View.GONEの場合(20.9ms)→View.GONEの場合(35.9ms)→View.INVISIBLEの場合(14.6ms)→View.INVISIBLEの場合(17.4ms)→View.GONEの場合(23.7ms)→View.GONEの場合(35.2ms)

リリースビルドとの比較

念のためリリースビルドでも比較してみましたが、目立った変化はありませんでした

View.GONE

Name Wall duration (ms) Avg Wall duration (ms)
Total 46.361167
Choreographer#doFrame 710656 7.863083 7.863083
traversal 7.828792 7.828792
DrawFrames 710656 7.810667 7.810667
Drawing 0.00 0.00 1080.00 2220.00 7.647542 7.647542
... ... ...

View.INVISIBLE

Name Wall duration (ms) Avg Wall duration (ms)
Total 12.10375
DrawFrames 707407 3.132167 3.132167
Drawing 0.00 0.00 1080.00 2220.00 3.07225 3.07225
Choreographer#doFrame 707407 1.400542 1.400542
traversal 1.386583 1.386583
... ... ...
5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2