View Hierarchy Optimization and Ergonomics

仕事のコードでレイアウトが遅くて困っているため View 構造の改善をやっている。

この作業は、少なくとも最初のステップは割と定形的だと自分は思っている。つまり、表示しない View の visibility を GONE にする。一部の機能でしか必要のない View subtree を ViewStub に押し込む。

この後が悩ましい。まず GONE とはいえ hierarchy に参加している View には一定程度のコストがある。だから可能なら hierarchy から外したほうが良い。このアプローチを dynamic mutation とでも読んでおこう。

もうひとつのアプローチは View の入れ子で実現しているものを一つの View に押し込む。そして入れ子の親だった何らかの layout view を消す。これは view  flattening と呼ばれている。

Dynamic mutation を使うと XML で宣言的に View を作ることができない。だから保守性が下がる。保守性を下げずに dynamic mutation を実現する良い方法がない。View flattening も conventional に書く良い方法がない。まあ ConstraintLayout で入れ子になったレイアウとを減らすのは conventional と言えるかな。でも flattening できるケースってそれだけじゃないよね。

Platform の convention に従うと遅いこの現状は Android にとって良い物ではないよなあ。

なぜこんなに遅いのか。View というオブジェクトが heavyweight で, かつライフタイムのフックというユーザのコードが View と一体化しているせいでツリートラバースでチートができない二点が原因だと自分は思っている。ウェブブラウザだと個々の Element は小さいしライフタイムのフックはそれなりに isolate されているのでたくさん Element を作ったりトラバースでチートしたりすることができた。

まあだからといってウェブアプリは convention に書けば速いかというと、そうは信じられていない。だから React みたいなものが幅を利かせることになった。

Android における React 的存在はなにか。ひとつは React Native で、もうひとつは Litho だろうな。

HTML にしろ View にしろ、プラットホームの convention はやがて React や Litho のような第三者に蹂躙される運命なのだろうか。そんなことはないと思うけれど、自分の身近な platform が二回続けてやられてしまうと platform というものへの faith を保てないのも事実だね。