アートとサイエンスのはざまで
例えばパフォーマンスエンジニアリングは定式化されたアクティビティをどれだけ回していくかのサイエンスだと思う。けれども、一般には秘伝の最適化手法を感性で駆使したアートのように思われていることが多いのはなぜなのか。「〜すると速い」みたいな真偽不明のマントラが多いからそのように見えるのか。
僕からすると、ソフトウェアの設計やリファクタリングの方がよっぽどアートだと思う。問題構造をどのように認識して、どのような形であるべきかを解いて、具体的なコードとして落とし込んで行くアクティビティであって、それは思想や哲学の叙述という行為に近しいからだ。パターン言語とかもあるけれども、ある思想体系において理論立てられた説明と用語を用いているという感覚。
styled-componentsへの最近の感想
今の職場で既に組まれたシステムが既にstyled-componentsにべったり依存していて、別に積極的に入れ替える理由もないので普通に使っているけれども、やっぱりこれ微妙だなと思った話。
そもそもとして、ビルドシステムへの介入が多くて不必要にロックインになったり、提示されてる手法がだいたいイマイチで普通にCSSとかSCSSを書く以上の意義が見出せないので、僕は基本的に「JS中にCSSを書いたり、ES Moduleのimportを使ってCSSを読み込むタイプのアプローチ(以下CSS-in-JS)」がそんなに好きではない・大人しくCSS書く方が好きではあるんだけど。色々あった理由はこちら:
- https://saneyukis.hatenablog.com/entry/2019/02/28/022750
- https://saneyukis.hatenablog.com/entry/2019/03/14/023446
感想
上のリンク先にも色々書いてる微妙に感じる点を全部見なかった事にしても、やっぱり微妙だと思う。
- 何を作るにもstyled-componentsで包まれた(ファクトリ)コンポーネントを作る事になるので、ラムダ(匿名関数)を書いて済ませたい箇所で、古のJavaのCallbackクラスを書くのを強制される気持ちになる
- 具体的には調整用のdivやspanをぺろっと置きたいだけなのに、わざわざ書く事になる
- 結果、包まれた(ファクトリ)コンポーネントは変数定義順の問題があり、function宣言のhoistingなどに頼ることができないので、 BEMのelement定義してからBlock書く感じになる。なので、抽象化されたコンポーネントを定義したいのに、まず具象化された細部から書いていく必要があるし、既存のコードもそのように書かれる
- ここら辺、人によって書き方変わるし、lintなどのしばり方次第で如何様にも書けるだろうけど、temporal dead zoneを考えると宣言してない変数を使うのはありえないのは共通認識とする
- 末節・BEMでいうelement側の定義をファイルを分けてimportすれば解決する問題だが、繰り返すようにラムダ(匿名関数)を書いて済ませたい箇所でCallbackクラスを定義するような事になる
- そもそもテンプレートリテラルで文字列として記述しているのが、非常に中途半端に見える
- JSX記法がDSLとしてセマンティクスを持つ事による教訓が活かされていないのは釈然としない
イマイチだと思ったのはここら辺。他にも色々あるけれども。
かつてのCoffeeScriptを持て囃す論説への拒否感と似ているものの、そんなことをいうとCoffeeScriptに失礼だな。
それとstyled-componentsに限った話題ではないけれども、いわゆる「GUIのTheme実現が可能」みたいな売り文句は実際には十中八九使わないタイプの機能だと思っていて、なぜかというと
- 現実にはダークモード+alphaくらいしかテーマを作らない
- そもそもテーマ機能を真面目に用意してるプロダクトを見た数の方が少ない
- ダークモード対応なら
prefers-color-scheme
で解決する
- ダークモード対応なら
- そもそもテーマ機能を真面目に用意してるプロダクトを見た数の方が少ない
- 仮に実装するとしても、起こり得るテーマの変更はCSS custom propertiesで使って色やサイズや
background-image
などの変数定義で解決するのが大半なので、標準化された方法に依存した方が良い - もっと複雑なことをやりたい場合は、大抵はGUIの実装部分が別になるので「一つのファイル・コードで複数のテーマを実現可能」にお世話になることは(あんまり)ない
- ユーザー定義スタイルを許容する場合、尚更public interfaceとしてclass属性などは必須だし.
から。 ちなみに自分の好きなアプローチは上の方に貼ったリンク先に全部書いてあって、それを超えるものではなかったかな。
Facebookのリデザインに見る、CSS-in-JSの良さそうな方向
色々ぐだぐだ書いているけれども、 https://engineering.fb.com/web/facebook-redesign/ に載っているサンプルコードの方向性は、良さそうに見える。実際にこの通りに書かれてるかはわからないけどね。
なぜかというと、
Update my status
I'll begin my new job from this May after short leave from this industry. Thank you for worrying about me. See you again in the community!
My next job will be began from WFH. Its start may be a bit hard for me. Interesting.
BlinkとWebKitの違い(大雑把)
「〜がChromiumベースに!」なことが起こるたびに「Chromium/BlinkはWebKitを源流とするエンジンでしかじか」みたいな話が出てきて、「実質WebKitだから同じだね」という反応が出てくるのが恒例行事っぽくなってるけど、結構モニョモニョする。
先祖が同じなら子孫も同じ、ってそんな単純な話じゃない。
fork前、BlinkがChromium WebKitというかWebKit Chromium portと呼ばれていた頃でさえ、Chromium portとApple portの2つが同じエンジンと呼べる箇所って、layoutとかdomとかstyleとかブラウザエンジンのコア部分だけで、他はV8とJSCとか、SkiaとCore Graphicsとか、そもそもプロセス分けてる方法も違うし、呉越同舟というか寄り合い所帯感だった。composition周りだってApple portはCore Animationにべっとり依存するような実装じゃなかったけ。
それで、数少ない共有部なコアでさえ、fork後に色々変わっている。自分の知っている・思い出せる範囲で大きいやつだと
- layout
- style
- DOMのオブジェクト管理
とかとか。細かいあれこれを挙げだすとキリがない。
GeckoやEdgeHTMLと比較した場合、WebKitとBlinkは近縁種だと思うけど相対的なものでしかなくて、それぞれが呉越同舟していた時代に追加された仕様未定義な挙動に箇所に関するテストケースや、同祖であることに由来する箇所くらいしか、同じエンジンとは言えない。ましてや最近実装されたものは以下略。
リポジトリを境界としたコードベースとしては、WebKitは変わらずライブラリ指向だけど、Chromium/Blinkはプラットフォーム志向で、リポジトリの成長の方向性としてはFirefox/Geckoの方が近くなってきている
でも、そう変わるのも当然で、当代で世界トップクラスにお金を持っている二社が別々の方針で(数十人とか数百人のオーダーで)エンジニアを7年も張り付けていて、しかもそれぞれプロジェクトが実現したいWebに対するスタンスは結構違っているのに色々変わらない訳が無い。
でも、一方でWebGLの実装とかはWebKit(のApple port)もANGLE使おうとしてて、このままだとGecko/Blink/WebKitのどれもANGLEになろうとしているんだから、面白い。
JSConf 2019 Postmortem
JSConf 2019で Your benchmark may not guide real application performance という話をしてきました。 寒い中お越しいただいた皆様。ありがとうございました。
話さなかったこと
「そうは言ってもベンチマークを組み込むのつらいよね」な話
自分の体験談、身の回りの同僚知人各位の体験談も合わせていくとそれだけの一本のコンテンツにできますが、今回は単純にスコープ外かつ30分に収まらないので諦めました。私の力量の問題もあります
後からベンチマーク足そうと思うと本当に大変。まあ最初からやっても大変だとは思うけども、ゼロからやる方が"ちょっとだけ"簡単だと思う。
詰まるところカルチャーの問題なので、うまくチームや会社を巻き込まないといけない。「ソフトウェアパフォーマンスは究極的には組織文化である(要約)」というJoe Duffyの主張はとても正しい。「パフォーマンス専任担当者・チーム」が、どこからともなくやってきて、ベンチマーク足して帰って行ってもあんまりうまくいかない。文化として根付いていないからだ。
プロダクトを主に書いているチームの人間が自分たちで取り組まない限り、途中から現状維持でさえキツくなったり、ベンチマークスコアがどんどん遅くなるのを眺めて何もできないままとなっていくみたいな話。「遅い変更は強制revert」ルールとかも、ちゃんと(評価など含めて)カルチャー化してないと、ひたすら疲弊するだけですし。
再現性は手軽さも重要みたいな話
動かすだけで一苦労みたいな、手軽に再現できないベンチマークは誰も試さなくなる。「一回動かすのにセットアップで1人/週かかって、実行に5時間かかります」みたいなのは絶対に続かない。
わかりやすいボトルネックが本当に見当たらなくて「全体的に遅い」みたいなことになってる問題に対処する話
わかりやすいボトルネックを1~2つ潰したらこうなることが多い気がする。最初からそうなってることも、それなりにある(気がする)。
原因はクリティカルパスが隠れている以外にも、「どうしようもなく全体が遅い」「全体を速くしないと速くならない」みたいなこともあって、それはプログラミング慣習の問題だったり、ソフトウェアアーキテクチャだったり、そもそもの機能要求に起因したり、まあ色々。徹底して分析するしかないと思っている。
この手の話で好きなのはAndroidの豪傑Dianne HackbornがGoogle+で書いていた話なのだけど、もう消えちゃったんだよねえ.....(と思ったらアーカイブが残っていた)。これは少々極端だしOSやフレームワーク層の意見で、アプリケーション層とはまた少し違うと思うけれども、態度として敬意を払いたい。
「単純なボトルネックなんて早々に消え失せてしまった」系の話だとMozillaのQuantum Flowの時の話とかも個人的には好きです。
そもそもコアバリューってなんだよ・ちゃんと自分たちのコアバリュー考えて仕事してるんだっけ話
複数の友人から指摘されたけど、これ言い始めるともう少しメタな話になるので省きました。指摘をくれた友人各位には「俺よりもお前の方が適任だと思うぞ」と返信していたので、彼らがやってくれるかもしれません。
Q&A形式のまとめ
友人に勧められたのですが、(英語力の問題で)面白いやりとりが思い浮かばなかったor身も蓋もなさすぎるのでボツになりました。
よかったこと
話が刺さってくだすった観客が何人かいたこと。 その後、直接感想をくださった皆様、ありがとうございます。楽しんでもらえらた人がいるだけで何よりです。
やっちまったなと思うこと
動画が公開されるかもしれませんので、現時点で気づいたことを予め懺悔しておきます
- 観客の目を見て喋る機会が少なかった
- 「下ばっかり見て何だコイツ」と思われた方もいると思います。申し訳ありません。カンペ読んでました
- しゃべるの速すぎる
- すいません。練習が足りませんでした。
- 序盤、「自分たちでコントロールできない指標」のくだりでしどろもどろになってしまったこと
- うっかり口が滑ってしまった
- 多分意味不明なこと言ってます。本当に申し訳ない。
- ベンチマークは指標に過ぎないという話が弱かったかもしれない
- あくまでも実現したいコアバリュー・目標としての速度があって、ベンチマークはそこに向かって進むためのテストケースに過ぎないという話です
- Causal Profilingの話への理解が微妙に甘い。たぶん変なこと言ってる気がする
- 理解が甘いのに無理に言及してしまった
- 詳しく知りたい方は元論文を参照してください
謝辞
運営の皆様、二日間開催お疲れ様でした。来年はUDXカンファレンスや大田区産業プラザPioでの開催となれば駅近なので嬉しいです。途中で帰ってしまったため、もしアンケートフォームなどありましたら公式Twitterでシェアいただければ幸いです。
当日お越しいただいた皆様、ありがとうございました。楽しんでいただけたなら幸いです。
観客の皆さんは金と時間を使って観に来てくださっているわけで、やはり楽しんでもらえないことには自分が発表する意味はないわけです。無闇に客に媚びれば良いというものでもありませんが、ちゃんと一人でもいいから需要のある話を提供できないといけないわけです。そうした中で何かしら刺さってくれる人がいたのであれば、登壇者冥利に尽きます。
資料のレビューやアイデア出しに参加いただいた友人各位、本当にありがとうございました。無事形になりました。皆さんのおかげです。本当にありがとうございました。
Leave my work
I was fired 😫
Sorry, this is a bit clickbait phrase. My contract was ended due to various reasons. This primary reason is that I could not pass the interview by an industrial doctor and I ended over the period my employer allows me to rest.
Thank you for my colleagues.
By the way, I'm finding my next job. I don't have any concrete next plan. I consider all options about my next position since I can no longer to work for CyberAgent Inc. If you have an opportunity which I may suite for, I’ll appreciate to let me knows about it. Please contact me via my email address which I listed to GitHub.
I'd like to work to continue software engineer and I'm interested in to challenge to shape a platform service provides high availability, performance, and reliability.
However, this my hope might too long jump if you know my career. But I'd like to challenge it.
Finally, I appreciate my colleagues. I’m looking forward to see you again. Bye.
css-modulesを止めようとしている話(具体的な解決編)
BEMでいいじゃん話の続きその2にして, 具体的な解決編.
多分ここが気になる人が多いと思うのでなるべく箇条書きで済ませることにする.
背景
前回書いてた内容をまとめると以下のようになる.
無駄話が多いので前回は読まなくてもいいです.
追記: 前回読んでもらった方がいい気がしてきた. 時間が無い方はいったん飛ばしてくれて構わないのは変わらず.
状況
- サービスの初期からwebpackのcss-loader(を用いたcss-modules)を使用していた
- サービス開始時の鉄火場の中で, cascadingに基づく暗黙的なスタイルの継承を用いて, UI component treeにおいて祖先側が子孫側のスタイルを上書きしている箇所が多々あった
起きた問題
- リファクタリングの一環でディレクトリ構造を転置し, 併せてimportの順序も変更・整列した結果, css-loaderによるモジュール間依存グラフの構築順序が変わり,
最終成果物たるCSSのcascading順序が変わり, 先述の暗黙的な上書きと相まって, ES Module間の依存構造の先の先に位置するような,
ほぼ全く予期せぬ箇所のスタイルがいきなり崩れるような事故が発生し始めた
- この時点でreftest(visual regression test)は無い
- reftestがあったとしてもいきなり全く関係ない箇所のスタイルが壊れるコードはメンテがしんどい
- リファクタリングを妨げるような道具立ては長期運用するプロダクトにおいて選択する理由がない
- webpackの上にCSSのビルドまで依存させた結果, ビルドパイプラインが複雑化の一途を辿っていた.
解決方法
要求事項
- 最終的に生成されるCSSが予測可能(透過的)なアプローチであること
- 他のツール群(Lintなど)との相互運用性が取れていること
- できればwebpackに依存しないこと
- css-loaderベースの既存コードからのmigrationが容易であること
- css-loaderベースの既存コードのメリットである「UIコンポーネントのコードとそれに関連するCSSファイルの物理的距離が近い(siblingである)」ことが保たれること
具体的な解決法
importの方法
元々, 以下のようなファイル構成になっていた
/ ├ featA/ │ ├ ComponentA.css │ └ ComponentA.jsx └ featB/ ├ ComponentB.css └ ComponentB.jsx
ComponentA.jsx
のスタイル指定は原則的にはComponentA.css
に記述され,
css-loaderを用いることでwebpackでのbuild時にimport styles form './ComponentA.css';
のように解決される.
これを以下のようにする
/ root.css ├ featA/ │ ├ featA.css │ ├ ComponentA.css │ └ ComponentA.jsx └ featB/ ├ featB.css ├ ComponentB.css └ ComponentB.jsx
/root.css
は, featA.css
とfeatB.css
を任意の順序で@import
経由でimportし, featA.css
はComponentA.css
を同様にimportする. featB.css
も同じ.
これにより, 既存の記述方式からの緩やかな移行が可能になりつつ, ディレクトリ単位での順序関係の定義がCSS wayで明確に可能になった.
また, 現実的にはUIコンポーネントは粒度の細かいものから大きなものに沿って, 祖先方向(caller)なUIコンポーネントが子孫方向(callee)となり, 従属関係があるように設計されるため, セレクタ名さえユニークであればconflictすることはないし, ディレクトリ構造を少しいじった程度で規則が変わるという問題もない.
これは元々css-loaderを採用していた時から「理想的・本来的にはそうなっているはず」だったのだけど, 現実にはcascading順序が先述の理由から偶発的に変わることがあり, 厳密な保証を取りにくい状況にあった.
それをroot.css
でのimport順序に用いてシンプルなcascading順序解決にすることで最終的なコードにおける記述順序が透過的な形式で記述できるようにできた.
そのため, 万が一に順序の問題が起きたとしても(そしてそれはレガシーコードとの釣り合いの問題や, css-loaderからの移行, リファクタリングの中間過程においては頻繁に発生しうるが), 以前よりは順序問題として容易にコントロールが可能になる.
尚、コードはわかりやすくするとこんな感じになる.
/* desktop/mobileで切り替え可能になっている */ @import './variables.css'; @import './component/atom.css'; @import './component/mole.css'; @import './component/org.css'; /* template */ @import './featA/featA.css'; @import './featB/featB.css'; /* page */ @import './page1/page1.css'; @import './page2/page2.css';
これにより
はなんとかなった.
セレクタの命名規則
前項の前提を達成するためにセレクタをユニークにするにはBEMを下敷きに以下のように設定した.
.アプリケーションドメイン-コンポーネント名__コンポーネント内の要素--修飾子
アプリケーションドメイン の箇所は, 当該cssが配置されているディレクトリまでのパスが-
で繋がれる形式になることが多い.
一方で汎用コンポーネントは.com-a
や.com-m
のように簡略表記を許容していた.
同時に, あとでgrepで検索しやすくするため, アプリケーションドメイン-コンポーネント名
の部分をJSコードなどで動的に構築するのは(事実上)禁止することにした.
これは将来的にセレクタ名をrenameするのを容易にするための方針. そもそもcssファイルのsiblingに位置するjsファイルの中でしか使われないので必ずしも重要ではないのだけれども, 原理上, 上位(粒度の粗い側)のコンポーネントからセレクタ経由でdirty hackとして上書きされる可能性を許容してしまっているため, それを「やらざるを得なくなった」場合への対処の余地も含んでいる(現実にはコードレビューで弾かれることの方が多いので存在はしないだろうと思っているが).
結果(中間報告)
一番最初にも述べたけど最終的な移行完了を自分は見届けたわけではないので中間報告になるけれども.
- postcssベースで実現
- node-sassを使わなかったのは, Node.jsのmajor version upへのnode-sassの対応が他に比べて遅れやすく, Node.jsの更新の妨げになるケースが過去多々あったために避けた
- 要求事項は達成
- コード上の使用箇所とスタイル定義が紐づくため, 不要コードの削除も比較的容易なcss-loaderのメリットを引き継げたのは非常に大きい
- 何よりも生成コードの予測がつきやすくなった
- easyではないがsimpleは達成できた
ので結果は上々(と言えると思っている).
Performance Impacts
- minifyしないことで相対的なファイルサイズの増加は起こり得る
- SpeedCurveでの計測を見ていると移行による大規模なperf regressionは起きていない
- 長期的にはむしろ通常の機能追加に基づくコードの増加の影響の方が多い....
未解決または諦めた問題たち
- class属性のmangling
- critical rendering pathに必要なCSSだけの読み込み
- css-loaderべったりの時から, 最終成果物は独立したCSSファイルにしていたため, これ自体はregressionではない
- 将来的にこれが問題になった時に改めて検討する
- plainなCSSにした結果, 必要なスタイル定義だけを切り出してhtml中に埋め込むなどの最適化の余地が広がっているんじゃないかと思っているものの, その調査と最適化を必要とする段階には至っていないので未確認.
- 現代の多くのwebサイト・アプリケーションでは, この問題が現実の問題になるよりも先に, initialで読み込むJSのサイズの方がよっぽどperformance bugになると推測しているし, このとあるアプリケーションA(仮)では事実そうだった
- renameがめんどい
- 変更する箇所が多い
- これはある程度固まったプロダクトでは問題ない
- 立ち上げ期の試行錯誤の続くコードベースではめんどくさいかもしれない
- grep一発で解決可能ではあるが...
余談
- 元々CSS-in-JS嫌いな自分が面白半分で実験していたものを, regression鎮火のために, UIコード周りのオーナーと煮詰め直してworkaroundとして急遽投入したものだけど, 案外うまくいった(と思っている).
- easyではないがcascading style sheetの記述としてsimpleな所に落ち着いたと思うし, 自分としてはBEMで問題が解決していたという屁理屈が実証を伴ったという認識.
- いくつかのunresolved question含め、そのうち同僚の誰かがもう少し詳細に話してくれる....はず. 多分.
教訓・まとめ
- class属性を上書きしてどうにかするのは忙しくても止めた方が良い
- reftestは早期からあると良い
- 壊れたことを検知するには当然テストですよ
- CSSはcascading style sheetsでありES Moduleとは諸々の解決規則が違うので, 道具としては別物として考えるべき
追記: ちょっとした返答・反論とか
CSS Moduleを止めようとしている話(具体的な解決編) - saneyuki_s log“cascadingに基づく暗黙的なスタイルの継承を用いて, UI component treeにおいて祖先側が子孫側のスタイルを上書きしている” コレを食い止めなられなかったことが致命的であって、BEMかCSS Modulesか、という話はあんまり関係な
2019/03/15 03:32
根本的かつ理想的にはそうです. それで解決できていたならば何を採用しても苦労しません.
しかし残念ながら,
- レビューの際の見逃しやby designや時間的な制約による場当たり的な対応という意味の事故も含め, そのような問題が容易に発生しうるのがCSS Scopingのない(WebComponentsに頼れない)世界のCascading Style Sheetsの限界である
- そうした問題が発生していないのであれば, そもそもBEMだstyled-componentsだのという論争も存在しない.
- 現実にそれが当該アプリケーションのコードベースでは発生していた
- 今後の運用の過程で継承や上書きに頼る必要のある箇所が(偶発的であっても)現れるのが予見しうる状況にあったし, 仮にゼロから理想的な設計かつ負債の無いコードベースで構築したとしても, プロダクションにおけるコーナーケースも考慮すると, どこかの層で原理的に担保しない限り「発生しない」という前提に立つのは難しい.
- CSSの継承に頼らず, 関連するpropertyを個別に
unset
またはinitial
で埋めつつ作業をするのも解法としてあり得るが現実的ではない. - そして本文の繰り返しになりますが, リファクタリングなどに際してそこの依存が思わぬ箇所に出てくる結果となっていた. また, css-modulesの枠内で対処を試みると, 取り扱っている対象と記法のセマンティクスのミスマッチから却ってmonkey patchを増やすばかりであった
ため, それらの課題に対して
- そもそも暗黙的な上書きをしうるケースを減らす方向にコーディングスタイルやミクロなUIツリーの設計を変えるようにした
- 最終的に生成されるCSSコードを透過的に扱えるようにすることで, 以下の課題への対処を容易にする
- 1の結果発生しうるコーナーケースの緩和
- 1を志向してもどうしてもうっかり発生しうる将来の問題へのworkaround
- すでに負債と化していたコードベースで発生していた, css-module依存のcascadingに依存したコードからの移行
というのが, 当該アプリケーションで採用した解決案であり, 本エントリで主に言及していたのは2になります.
CSS Moduleを止めようとしている話(具体的な解決編) - saneyuki_s log無秩序なCSS Modulesの使用から、秩序あるBEMにしたら、秩序を得た。CSS Modulesはなにも問題ないのでは?
2019/03/15 20:27
改めて説明すると,
- css-module時代のコードはそれはそれで秩序はあった.
- 付け加えていうのであれば
- リファクタリングを妨げるような道具立ては長期運用するプロダクトにおいて選択する理由がない
- 最終的にcascading style sheetsのセマンティクスで表現されるものを, ESModule(ないしwebpackのloaderセマンティクス)で構築するような, 異なるセマンティクスを道具で構築するのはやり方が悪い
- 最終的に規約や秩序や運用でカバーといった言葉で解決するしかないのであれば, よりsimpleな運用で済む手段で良い
- とりあえずこちら と, 本エントリを改めて読んでいただければと思います
色々書いてなかったこと
Twitterでやりとりした中で、やっぱり書いたほうがいいなと思った話。
込み入りすぎててうまく説明できる気がしなかった初稿で説明していなかったが, className
地獄への門の一端として, 現状の課題たるコーナーケースも色々あった(全部覚えていない + 全部列挙する前にCSS Module路線を諦めた)。例えば「本来であれば:nth-child()
擬似クラスで解決するのが綺麗なはずだが、実際には適用したい対象がReact Componentかつ孫よりも下位に位置するため, 結局何かしらの上書きが必要になっている」など。この辺りについては「そもそものUI ComponentのAPI設計・粒度がおかしい」と断じてしまえばそれまでなのだが, 目の前にあるコードをmigrationしようとするには避けて通れない問題であった。
また、CSS custom propertiesなどはレガシー環境を考慮するとコンパイル時に解決するものになってしまう。つまり, 実行時制約を転化には処理系でのネイティブサポートが必須になるもののIE11などのサポートを含めている以上はそちらを前提にした設計に切り替えることは難しい(丸々IE11向けとそれ以外のコードベースを用意するか、そこも含めてサポートする互換レイヤーを何かしらで用意する必要があった)。
また、WebComponents一式が使えるようになったとしても, ShadowDOM境界を跨ぐ前提に立つと諸々の設計パターンは変わる可能性があり, WebComponents周りが未だ発展途上気味であるため(form control周りなどは最たる例だし, 残念ながら「今年はWebComponents元年」と年初に叫ぶはもはや年中行事になりつつある), より「モダン」なapproachへ将来的に移行したいことや最も強固なエコシステムであるWeb標準のなるべく近くに位置しておきたいことを考慮すると, メンテナブルかつ保守的(Web標準の近くに寄る)手段を採用するほうが長期的には払うコストが少ないだろうと予想し. ゆえに, シンプルに振ることになった.
ゼロから全てを描き直せるのであれば, おそらく強固な規約を浸透させるなどの運用戦術を取りつつ, 別の手段を考慮する可能性もあるだろう. しかし, 我々にそのような富豪的な選択肢はありえないし, 仮に書き直せるとしても真っ先にレガシー環境を切り捨てる方向に体力を注ぐだろうし, 一連の記事で述べている過程は「書き直しやすくする」ための前段階としての措置であった. そもそも頻繁に書き直しできるのであれば, 長期的にメンテナブルにすべきかなどといった問題はない. 困ったら書き直せばいいのだから.
それとstyled-components/CSS-in-JSに関する話については, 「最終的にCSSというシステムに落ちるのだから」自分は否定的にすぎない(あれで本当に多くのcascadingの課題を難なく解決できるのであればそちらで全く問題ない). ゆえに, React Nativeのように最終形がAndroidやiOSのスタイルシステムに落ちるフレームワークに関しては意見するつもりはない.そっちは今の所よく知らないし.