css-modulesを止めようとしている話(長々とした状況説明編)

BEMでいいじゃん話の続きその1にして, とあるアプリケーションが困っていた話.

書き味は最良ではないけれど, 設計思想を持った上で長期メンテを考えると結構いい感じだと思っているアプローチに至った. しかしながら, 放っておくと誰も試行錯誤の過程を書かないままになってしまいそうだし, それを書きそうな同僚も(多忙のあまり)書きそうな雰囲気はなさそうだし, もしかすると永遠に出てこない気さえするので書いてみる.

多分完遂の暁にはどこかで話として総括が出てくると思うけど, 中間報告ということで.

経緯

とあるアプリケーションは, 元々はCSS Moduleをcssのビルドシステムに用いてAtomic Designとして作っていた. CSS Moduleを選定した理由は自分はよく知らないが, ものの試しで使ってみようと思ったんだと思う. ここまでは別に間違ってはいない. (自分は選ばないが)styled-componentsに比べれば自分の好みではあるし, そこまでガミガミと言うつもりはない.

しかし, 肝心のコードがやらかしていた.

セレクタの黒魔術こそ殆どなかったものの, いたるところに存在するReact製のUI componentがclass属性の上書きを許容する形になっていた. この時点で開かれすぎたcomponent指向なので色々破綻しているのだが, おそらく汎用的なcomponentを作ろうとする麻疹の一種だったのだろうと推察している. そしてそれは同時に, initial release前の炎上の鉄火場のなかでダクトテープを貼り付けてデザインレイアウトとの不整合をどうにか鎮火しようとするプログラマーのメンタルモデルとハマってしまったのだろう(その時自分はその場にいないので、真相は藪の中だけど). 結果, アプリケーションサービスがリリースされて1年以上が経過した頃(自分が関わるようになった頃)には, いたることで上位のcomponentが思い思いにclass属性を上書きすることで帳尻を合わせるコードが散見されるようになっていた.

複雑なセレクタの黒魔術による上書きではなく, class属性の上書きで対処しようとした理由はわからない. だが、おそらくはCSS Moduleを使っている関係上, production buildでclass属性がmangleされてしまい, そのmangle結果もコードの成長に応じて必ずしも一定しないためにセレクタでの解決が不可能だったのではないかと推測する. とはいえセレクタを使っていても問題は後述の問題は回避できなかったと思うけど.

さて, そのような不安定なコードベースの現状に対して, アプリケーションの属するサービスは順調に成長を重ねていた. もし「実は伸びないのでcloseします」みたいなサービスであったら、ガタガタでも何の問題も無かっただろう. どうせ死ぬんだし. だが, それとは真逆でむしろ伸ばす方向にするにはどうするかを考える必要があった. そのような状況で, やばいなーと思いつつもガタガタになっているとはつゆも知らない自分(と同僚たち)はうっかりパンドラの箱を開けてしまうことになる.

発端はコードベース内のディレクトリ構造をリファクタリングしているときに起こった. そもそもディレクトリ構造をリファクタリングしていたのはコードやモジュールの責務境界を明瞭にするために実施したのだが, その過程でES Moduleのimport文の順序関係や格納されるパスのアルファベット順を変えてしまうケースがあった. 変えてもアプリケーションはちゃんと動いているし読み込む側の順序に依存するようなことはないだろうと思っていた.

読み込む側での順序を変えた結果, アプリケーション内で読み込まれる側のモジュールの依存関係に基づくDAG上でトラバースされ評価されるタイミングは変わることになる. しかもその変わった対象は変更したモジュールから遠く離れた箇所であったりもするため, changesetから読み取ることも難しい. これがJSの世界に閉じただけならば問題なかったのだが, 変更前後でグラフ構造の比較が必要になる上, 「変更箇所から10モジュールくらい跨いだ先のJSファイルが読み込んでいるCSSファイルの評価順序が変わった」のを上手く検知しながら他を壊さないように直す方法を探す必要がある. さらに悪いことに, その評価順序の変更の適用される対象が「最終的にはフラットな構造を上から下まで読み込んだ順序に評価する」cascading style sheetsなのであった.

結果を先に述べると, 上の方で述べた「上位のcomponentがclass属性を介して下位のcomponentのclass属性を上書きして微妙なレイアウトを調整する」ために必要なcascading順序が大きく破綻して, 「注意して確認すると壊れている」「大きく破綻するケースもあれば小さくずれているだけも両方ありうる」状況になってしまった.

それでもreftestがあれば早期に問題には気づけたであろうが, 当時の自分たちはreftestを持っておらず, しかも悪いことにリファクタリング作業が半分以上進んだ段階でその問題が発覚したために(それまで気づくことができなかった), 今更ディレクトリ構造の変更を中断して全てをrollbackするのも難しい状態になっていた.

では仮にreftestを持っていた場合は早期に問題が検知できて堅実に進めることができたのだろうか? その場合は先にも述べたようにモジュール間の依存グラフ構造を黒ひげ危機一発的におっかなびっくりと壊さないように変更を進めることになる. それが嫌であれば、コード行数10~15万行の中から, まず安易な上書きをしているところをすべて取り除く必要があり,それは縦横無尽に鎮火を前提として書かれたhackを全て取り除くだけのチームの体力が要求される. どちらにせよ, コードの責務分界点を分けるという目的に到達するまでに年単位の労力が必要になる. そして繰り返すが当時の自分たちにはreftestはない. 事実上, この路線のままでは軽微なcleanupにも等しいリファクタリングさえもロクにできない状況に追い込まれていた. リファクタリングできないコードベースとか敗北宣告にも等しかった.

解決に向けて

話を戻す, 今更rollbackして後にも引けない, かといって放っておくと前進すら難しい自分たちは以下の強行着陸を採用することになる..

  1. 可能な限りモジュール依存グラフの評価順序を変えないために, JSのimport文のsortを諦める
  2. CSS Module by css-loaderを使うのではなく, 素のcssをconcatすることでcascadingの評価順序を壊さないようにする

1は, 評価順序を変えなければ最終成果物が変わらないという保証が取れたので, 2で払うべきコストを先送りしてディレクトリ構造の変換を継続するための手段. 2は, すでに壊れてしまったものを制御可能な状態に戻すための処置. 手間は増えるしダルいものの, 明示的にcascadingの順序を制御できるために, もっともシンプルな解決方法となる.

この2つを, 最終的に2に持っていく合意のもとに壊れた箇所を修正しながら適用することになった. そもそもclass属性上書きしているのを直すべきなのだが, 影響範囲が大きすぎる + regressionの鎮火が優先であるため, 次のフェーズの課題とした.

結果的に多数のregressionは鎮火し, その後細々と変え続けた結果, 開始から数カ月(機能実装などで一時中断していたので実働としてはもっと短い)ののちにディレクトリ構造の変更は完了したのであった(CSS Module撤廃はside work的に現在も進行中)..

......同僚各位、その節は本当にご迷惑をおかけしました....

なんか話が長くなってきたので具体的にどうしたかは次のエントリで書くことにする.

「OSSのコードが綺麗」という先入観

先週、Twitterでまるっきり別のクラスタの知人が全く別個の「Open Source Softwareのコードは綺麗。業務のコードは汚いが動くコード」みたいな誰かのtweetをRTしていてちょっとそれ違うよなーと思った次第。

Open Source Softwareのコードが綺麗かどうかというのは非常に大雑把かつ間違った先入観で、 仮にそう思っているのであれば、それはその人がロクでもないコードや大雑把な単位のコミットを普段から見すぎているか、 運よくめちゃくちゃコードの出来がいいプロジェクトのコードを読んでいるだけだと思った方がいい。

Open Source Softwareのコードが綺麗になるとするならば、

  1. コードを公開する側にとっては綺麗なコードを公開したいという気持ちが生まれ、せめて見せかけだけでもと頑張っている(恥の概念)
  2. 綺麗なコードを書けるプログラマーが参加している・集まっている
  3. プロジェクトのcheck-in policyが(時には潔癖なまでに)しっかりしている

のどれかでしかない。

Open Sourceだろうがプロプラだろうが先ず重要なのは問題を解いていることであって、 コードが綺麗かどうかは重要じゃない(クソコード無罪と積極的に言っているわけではないので悪しからず)。

それに、パッと見は設計もスタイルも綺麗だけど全然問題に適してない設計だったり、 そもそもインデントが揃っててて綺麗なだけで全部グチャグチャとか、コミットログがロクでもないとか、 設計やAPI designが腐ってるとか、そういうコードはOpen Source Softwareを多数探せばいっぱいあるし、 逆にプロプラでもメチャクチャしっかりしたコードと出会うこともある。

Open Source Softwareに期待するべきなのは、コードが公開されているとか再利用可能とか困ったら自分で修正できるとかにすべきで、 コードの綺麗さを期待してはいけない。

仮にそういうことを褒めたいときは特定のプロジェクトを名指しで褒めるべき。OSS一般が綺麗というのは幻想もいいところ。

そもそも綺麗なコードって何だよっていう話ではある。

BEMで底に達した問題を探す問題のために生まれる問題

最近、社内のいろんなプロジェクトのリポジトリを眺めているとスタイルシートの記述にstyled-componentsとかwebpackのcss-loaderとかで頑張っているものを頻繁に目にする。

んで、Lintとかどうしてるの?みたいな話をすると「〜はこの『A(どこかのCSS-in-JS派閥の一つ)』は対応してないんだよねー」という返答が返ってくる。

そのたびに思う。「BEMで問題解決してたんだからBEMでいいじゃん」と。

このようなことを言うと「JVMJITコンパイラの仕組みを聞いた後に『アセンブラを生で書けばいいじゃん』と言い出す痛いおじさん」感がするので自分でもあんまり好きじゃない。ただ、CSSに関してはBEMで問題が底に達してしまっていて、そこから先の標準化されてないwebdevツール群は問題を再発明しているだけに過ぎないなと思う。

書き味をどう頑張ろうが結局我々はCascadingという宿命からは逃れられないのだし、それぞれのツールや処理系の最適化は依然として最終成果物がcascading style sheetsに落ちることを期待しているという事実を無視してもしょうがない。であるならば如何に素のCSSに近い状態で、エコシステム内の多くのサービスやツールとの相互運用性を諦めずに済むかの方がよほど現実的であったり長期的に残るんじゃないかな。「このサービスはハズレたらすぐ死ぬから大丈夫?」、だいたいそういうプロジェクトに限って、儲かってもいないが赤でもない、みたいな感じでうっかり長生きしちゃったりするんだぜ.......?

「文書構造と見た目を分離する」という目的でCSSがHTMLのツリー定義と分かれているというのが常に便利とは限らない、というのが現状であるものの、依然としてCSSというモデルは生きているのであり、それは好む好まざるに関わらない事実である。それを無視するのはクレバーじゃないなーと思う。業界全体的になんかおかしくない?

さて、かつての我らがCSSに困っていた問題は場当たり的なセレクタの複雑化と、それに伴う優先順位の破滅であった(今も困っている)。

BEMやその一門はclass名は複雑でもセレクタはシンプルに保つ方向でそれを解決しようとした。あの命名規則は問題を解決したと言っていいが、我々は慣れ親しんだセレクタの奥義を捨てるのはまだまだ惜しかった。

ただ、BEMが一定の知名度を得た頃には、あまりUI component指向みたいなものは(webデザイナー業界・Webフロントエンド業界)では一般的ではなかったような記憶があるし、体系を作るための設計語彙みたいなものもそんなに統一されていなかった。

それから時は流れて。Atomic Designを始めとする設計語彙は随分と人口に膾炙するようになり、UI component指向は大なり小なり考えるのが前提の時代になった。今や黒魔術的なセレクタをdirty hack以外で使う方が珍しい。そんな今だからこそ、やっぱりBEMでいいんじゃないか。いいというか、「あれでよくなったんじゃないか」。

それゆえに思う。「BEMで問題解決してたんだからBEMでいいじゃん」と。

EdgeHTMLを悼む

久々に色々書きたい気持ちになった + 矢倉さんの書かれたものを見て、彼とは微妙に考えることは違うかなあと思ったので書くだけ書いてみる。意見似てるなと思ってるところは書かないようにはした(標準化方面周りとか)。あと、Webブラウザ周りの現状に明るくない同僚や友人向けのテイストは含んでいる。

そもそもの大前提

まず、Webという文書・アプリケーションプラットフォームの価値は「標準仕様に基づく相互運用性」「インストールせずとも使える」の二点に集約されると自分は思っている。

最近はずいぶん聞かなくなった「Webは簡単に作りやすい」というメリットは、「Win32のデスクトップアプリに比べると」という但し書き付きで、90年代は事実だったと思うけど.NET Frameworkの進化とかモバイルOSアプリが出たりとか業界の成熟に伴って事実ではなくなって久しいと思う。

この「標準仕様に基づく相互運用性」というのは、標準仕様を実装しているソフトウェアがあればあるほど担保されやすくなっている。単一の実装と単一のテストケースだけでは、どうしても特定の実装に依存する標準仕様になっていることがあって、まず相互運用性なんてものは実現されないと思っていい。複数の実装があって、それぞれで相互に検証して、どれが実装のバグなのかどうかを試しかめるフェーズが非常に重要になってくる。

ここで問題になるのが、「今日の商用利用に耐えうるWebブラウザをゼロから新規に作り直すのは現実的には不可能である」ということ。理由は

  1. Webブラウザに求められる機能が非常に多いため、開発には多大なる人間や金や時間が必要であるため
  2. 歴史的経緯に基づく挙動や標準仕様、意図的に無視する必要のある仕様もいくつか存在するため、それらを含めて相互運用可能な状態にするには本当に大変な労力が必要となる
  3. 今日の商用利用に耐えうるWebブラウザは化石ではないため、日進月歩で進化を続けていく。仮に再実装する場合は、彼らに追いつく速度で進化させつつ足りない歴史的な機能を実装し続けていく必要がある
  4. そのような大事業を新規でやることに経済合理性がある会社は世界中のどこにも存在しない。
    • 2008年にGoogle ChromeをリリースしたGoogleでさえWebKitを利用することを選んだし、そのWebKitを生み出したSafariでさえ2001年の時点でKHTMLをforkすることを選んだ。どのエンジンも90年代のWeb黎明期に作られたエンジンを20年かけて改良し続けることで今日の日常的な商用利用に耐えうるソフトウェア足り得ている

などが挙げられる。

おもちゃ程度であれば一人でも十分に再実装は可能だし、00年代の中盤に求められた程度の機能であればエース級エンジニアを10人ほど集めて2~3年やれば近しいところまで実現できるというのはMozillaのServo Projectが2013~15年ごろに証明したけれども、アクセシビリティとかコーナーケースなどの対応を考えるともっと人数がいるし時間もいる。

そこまでやってもゼロからの新規開発では15年近く前の環境しか作れないので、何も経済合理性が存在せず、むしろ既存の実装を捨てることで影響力が消えたり、イニシアチブを取れなくなったり、相互運用性を損なう業界へのリスクを考慮して継続しているのがWebプラットフォームないしWebブラウザ開発の現場だったりする。

Opera (Presto)の思い出とwebでコードを書く話

そんな状況に陥ったWebブラウザの開発が中断されるのは別に今回が初めてじゃない。2013年には組み込み向けビジネスを当時のWebKitに破壊され、収益の柱を失ったOperaが自社製エンジンの開発を断念してChromiumに移っている。

自分はPrestoの死を悼むし、今回のEdgeHTMLの死も悼むけれども、それらが別にコードを書いていて楽しい相手だったかといえば必ずしもそうではない。

ソフトウェアなのでもちろんバグってることはあるし、「このブラウザ向けに対応しても喜ぶユーザーは滅茶苦茶少ないかもなあ」と思ってそれら専用のworkaroundを書くときは複雑な心境ではあった。だけどそれはPrestoやEdgeHTMLに限った話ではない。あらゆるソフトウェアにおいてバグが存在しているので、それに出会うかどうかの運の問題でしかないし、ユーザーが多いブラウザの方がバグが見つかりやすくて直されやすいというだけでしかない。Google ChromeだってSafariだってFirefoxだって、ブラウザの実装バグに悩まされなかったブラウザなんて一つもない。むしろインターネットの声の大きな人たちから好かれて絶賛されているメジャーなブラウザがバグっていて、普段は嫌われ者のあいつがちゃんと動いてるときは本当に複雑な気持ちだった。だけど、それが相互運用性のあるプラットフォームというものなのであるし、そうしたバグを踏んでしまった場合に誰が悪いかを決めるのが標準仕様なんだ。僕たちはそのメンドくささを飲み込んで、その上にあるメリットを掴み取ることにした。だからそこに愚痴は言えども、ちゃんとissue trackerにバグを報告して次のリリースで直ってくれればいい。それで終わりだ。

そんな心持ちでいたからこそOperaがPrestroを止めたときはショックだったし、その後にBlinkに移行した結果、Presto時代のOperaの開発者の多くがレイオフないしは自主的な退職でOperaを去り、Opera Software所属の社員の姿を標準化のメーリングリストや議事録から消えるのを見るのは複雑な心境だった。もちろんAnneみたいに他のベンダに転職して継続して活動している人もいるけど、全体としては標準化の要である「目」と実装の数が減ってしまったのは事実だ。

そうした過去や、MicrosoftIEで市場を一旦破壊・独占した結果として標準仕様の価値が無に帰した時代を知っているだけに、少なくともWebでコードを書いて銭を稼いでいた人間としてはこれ以上エンジンが消えることはWebの相互運用性に悪影響を及ぼす可能性というものは心配していた。

ましてやGoogle Chromeが、Googleの多大なる投資の結果、彼らのWebサービスとの強い結合とともにWebにおいて、かつてのIEの権勢を思い出すような強いシェアをモバイルとデスクトップの両面で持ち始めている。私企業の経済活動が「うっかりやり過ぎてしまって」、結果として全体としては不幸なことにになリかねないという懸念の矢先にEgdeHTMLの開発停止が発表されてしまった。

EdgeHTML

EdgeHTMLは、TridentをforkしてIE時代の互換コードをバッサリと落としたり、内部の文書構造がWebブラウザ向けではなかったのをDOMベースにするなどのリファクタリング話をある時期までよく発表していた。Chromium互換っぽく見せることに注力する傾向があったため、悪い意味でChromiumのダメな箇所を引きずったりもしているなと思ったし(Extension周りのAPIの作り方とか。あれは今やるならMozillaみたいにPromise使わないとダメだよ)、Windows 10のややこしすぎるサポートポリシーのために厳密な市場シェアの高いバージョンを調べるにはサービスごとのユーザー動向を見る必要はあったけれども、総体としてはずいぶんサクサクと動いてくれるし、IEと比べてwebdevとしてもすごくユーザーに勧めやすいブラウザの中身になっていたと思う。

動画系のAPIのように標準化の隙間が結構見え隠れするAPIの挙動は不安定だったりするし、Microsoft Connectに登録しても本当に直してくれるのか不安なところはあった。けれども、それは各OSに特化して作ったブラウザのあるあるなところで、Safariみたいなものだと思えば先述の通り問題なかった。少なくともEdgeHTMLについては、標準仕様に基づく相互運用性が高く、かつ時代や業界の要求してくるAPIについても大きなタイムラグなく実装してくれていたので、開発者としてもユーザーとしても期待が持てるブラウザだった。実家の父親がパソコンを買った時に「新しくGoogle Chromeをインストールして....」とヘルプしなくても済むし、サポートしがいのある(ナーバスな気持ちにならずに積極的にコードを書いていいと思える)ブラウザだと思っていた。

しかしながら、MicrosoftWindows Phoneを止め、Android向けに出したEdgeはBlinkベースになり、Microsoft自体はナデラがOpenを謳う一方でconsumer clientへの会社としてやる気の薄さとAzure/Officeの稼ぎぶりが目立つようになっていったあたりから次第にEdgeHTMLやChakraCoreも新機能開発してる話も細々とアナウンスされるようになったり、かつてはやる気に満ち溢れていたリファクタリングの話も聞こえなくなり、Chromiumが押しに押しているWeb Componentもなかなか実装されないなあと感じるようになった。

正直、FirefoxOSに全賭けして大敗北した間にAndrod版の投資をサボりにサボった結果の果てにモバイルにおける影響力をほぼ全て失ったMozillaよりも先にWebブラウザを諦めても不思議じゃないなと思うようになっていた。それでも、WebViewをGUI環境のAPIとしてWindowsのいろんなところで使っていたり、WebベースのOffice製品やVisual Studio関連製品を出しており、収益も株価も決して不調とは言えないMicrosoftが今更ブラウザエンジンを止めるとも思えず、杞憂に終わるのではないかと思っていた。そんなことを1年ほどぼんやりと心の片隅に置いていたところで、MicrosoftがEdgeHTMLが止めるかもしれないという噂が報道され、そして数日後にそれは現実のものとなった。

止める理由は漠然とわかる。Web標準への準拠ならびに市場最大シェアとなっていたChromiumとの互換性を強く押し出し、Windows 10のデフォルトブラウザとしての地位を使い、あの手この手でユーザーに使わせようとしていた割にはシェアが零細のまま伸び悩んでいたし、スマートフォンタブレットの普及の進展に伴い、モバイルで大敗北したWindowsはインターネット接続デバイスの総数における影響度は落ち始めていた。それにいくらスマートフォン市場で全く勝てなかったにしてもモバイルOSは時代の華でであり、Holo LensなどのXRの橋頭堡としての利用価値だってあったはずのWindows PhoneのGUIシェルのチームすらも解散させるような前科のある、今のMicrosoftがPersonal Computingをいつ諦めても不思議ではないという雰囲気は1ユーザーからも見てわかるように漂っていた。それ故に驚きはなく、ただただ切なさだけがこみ上げてくるだけだ。ましてや実装のdiversityの懸念がPrestoの脱落以後ずっと気にされていた中で、KHTML出身なWebKitやBlinkとは由来が全く違うTrident由来の、最も実装のdiversityにとって重要なエンジンの一つと目されていたものの脱落だけに、なおさらに切ない。今後、ORTCのようなcounter proposalが出る機会も失われるのだろうと思うと、単純に実装の一角が落ちたという以上の悲しみがある。

Mozillaの公式声明について

この件についてMozillaがChris Beard名義で以下のような内容を出している.

Goodbye, EdgeHTML - The Mozilla Blog

自分はこの声明の語調の強さには少々顔をしかめたくなるのだけれど、独立系ベンダーとしてのOperaも今は無く、WebKitも(胴元のAppleの方針も相まって)プロジェクトとして何か言うことは無いだろうし、Googleは当然何もいうはずがない。今や Google ChromeのVPであるGoogleのDarin Fisherは、彼には彼のポジショントークがあるにしても、こんな感じのことを言ってしまう状況だからね...... そのような状況を踏まえると、もはやMozillaしか言えないからMozillaが語調を荒げていうことに対しては一定の理解はできる。

だけど、この状況において(ある意味ではチャンスとも言える状況において)、FirefoxOSの失敗と同時にFirefox Androidに投資を殆どしていなかった結果、ことモバイルにおいてはMozillaは影響力が皆無に等しい状態にある。また、Web Engineのコアバリューの一つである速度の面で、総合的な結果として他二つに後塵を拝することになっているGeckoがユーザーに選んでもらえるかというと、短期的には厳しいんじゃないか。一番速い必要はなくとも、競合と比較した場合に遅いというのは選び続ける理由としては厳しいものがある。

そして、MicrosoftChromium Projectに(どの程度かは知らないけれども)参加する意向を示している以上は、少なくともWindows向けのIntegrationくらいはやるだろう。そうなるとMozillaは最後にして唯一のプロプラOSベンダーからの支援が名実ともに一切無いProjectになるわけで、モバイルやWeb全盛の中では開発チームを動態保存するだけでも精一杯とまで揶揄されるようなデスクトップOS向けアプリケーション開発としては長期的には競合比で不利になるのではないかと懸念する。

なので、頑張っては欲しい。自分はcontributorとしては退いてしまった身なのであんまり偉そうなことは言えないけども......

WebKitについて

Mozillaについて書いたので、一応こちらにも触れておく。

従来、WebKitについては結構心情としては複雑。彼らのsoftware engineeringにおけるuser first主義とそのためのperformance first主義、そして「Web BrowserはOSの1コンポーネントであるが、同時に1コンポーネントに過ぎない」と言わんばかりの姿勢には大変なる尊敬を自分は抱いている。だいたい2015年ぐらいからは標準化されている範囲に関しても、きっちりと作り込んで来ている印象もある。

一方で、specに書かれていないことの合間を縫っていると思しき最適化の結果や、モバイル環境向けにメモリリソースなどを削りこんでいると思しき最適化、彼らのprivacy重視の実装の結果として発生するバグについてはwebdevとしては本当に厄介。しかし標準化されていない・解釈次第ともいうべき箇所であったりするので強く文句も言えないし、標準化されていない範囲に関してはそれぞれの実装方針は自由であるというのがWebの多様性を支えている重要な点でもある。地道に「せめてデバッグしやすくしてくれ」「せめて動かない理由がわかるようにしてくれ」とbugzillaに要望を書いたりしていくとかするしかないんだろう。面倒だけど仕方ないね。

めんどくさい奴だけど、現状においてはそのシェアの問題とスタンスの違いから、WebUSB/WebBluetoothのように、WebのOS化の夢を諦めていないGoogle Chromeに対する非常に重要なカウンターパートなので、Webのdiversityの観点からは非常に重要なキーファクターであり、当面は応援したいところ。

まさか2012年にWebKitに市場が席巻されるのを心配していた頃に、6年後の2018年の今ではApple WebKitがWebの相互運用性のための一角を担うことになるとは誰が思っていただろうか。

Microsoftについて

あんまりWeb関係ない感想なんだけど。

2014~2015年ごろのMicrosoft Buildの様子とは大きく変わって、最近のMicrosoftは次々とconsumer client deviceについては少なくともWindowsとしては放置を決め込んでいるように見える。Windows Phoneはシェルの開発チームごと消えてしまったし、捨てるに捨てられない戦略物資だったはずのWeb Engineは今回の件で捨ててしまったし、相変わらずHolo Lensは生きているのか死んでいるのかわからないし...... CortanaもAlexaとコラボするみたいな話があったし、Windows 10 on ARMもやる気あるのかないのかわからないし、Surfaceはハードウェアの話でSotfwareとしてのWindowsそこまで関係ないし。AzureがあるからNTカーネル自体は維持するんだろうけれども、GUIシェルよりも上に関してはもうやる気がないのかな....と邪推してしまう。

ちょっと脱線した。

webdevとして

webdevとしては「Edgeを冠するWindowsのデフォルトブラウザのリリース間隔が短くなる(かも)」という点に関してのみは嬉しい。非常に惜しむらくはそれがEdgeHTMLによって為されなかった点。半年に一度のWindows 10のUpgradeに紐付く上に、そのUpgrade対象ポリシーが非常にややこしいために「だいたい最新のEdgeが使われていると信じる」ような推定からは脱出できるからだ。しかし、それがEdgeHTMLによって為されていないという点が悔やまれる。

率直に言って、現在のWebクライアントサイドの開発においてEdgeHTMLの対応に苦心するというのは例外を除いてそんなにない。彼らがChromium互換を狙っていたというのもあるけれども、後述する例外を除いて苦心するようなケースは、経験上、そもそもの問題として何かしらcross browserで動くことを一切想定していないような事例が多い。

故に、EdgeHTMLが消失したことに対してシャンパン祝賀会を開こうと主張している、どこぞのカメラアイコンの人は、少なくとも直近数年においてはEdgeHTMLのサポートを含むまともなWebクライアントサイドの開発をしていなかったか、そもそもまともなコードを書いたことがないか、後述する例外ケースばかり泥臭くやっていて心を病んでいたんじゃないかな?と思った。そういえばiOS黎明期に一発当てて以後の最近はもっぱらUI/UXコンサルタントでしたっけ? 私は彼を詳しく存じあげていないのでよくわかりませんが。Web周りは専門外なんじゃないかな? 間違ってたらごめんなさいね。

一応例外はある。それはWebRTCであったり動画配信のように、OSやベンダーとブラウザの組み合わせごとに、バックエンドの実装が変わってしまう場合。自分はWebRTCについては詳しくはないけれども、少なくとも動画周りに関してはDRMデコーダバックエンド、再生しているフォーマットやコンテンツファイルの相性というものがいまだに残っている。しかし、ライトに使っている限りは顕在化しないし、ヘビーに使っている場合はEdgeHTMLとWindowsの組み合わせに限った問題ではなく、どのWebブラウザでも大なり小なり抱えている問題で、それを踏み抜くかは運の問題でしかない。何度も繰り返すが、相互運用が価値のプラットフォームにおいてその問題は日常茶飯事であり、瞬間的には怒りこそすれども、そのようなプラットフォーム向けにコードを書いている以上は仕方ないのないことで、統合という方向性よりもそのようなバグが修正させる方向に向かった方が健全ではある。非常に面倒くさいけどね。。。。

EdgeブランドがChromiumに移行した結果であっても、おそらく類似の問題は発生するだろう。Microsoftが今後ChromiumベースのEdgeをリリースする時に、もしEdge向けのバックエンドがWindowsとの強固なintegrationを志向して、Google Chromeとは別の実装である場合、もしかするとEdgeHTMLの時以上にブラウザのバグ回避が困難な可能性だってありえる。故に、相互運用性だのWebの価値だのと言った問題をすべて外した上でも、一概にChromiumに移行することがwebdevにとって幸せだとは言えないと自分は思っているし、むしろGoogle Chromeに真の意味で一本化されていない以上、実装のモノカルチャーが中途半端に進展して中途半端な差異が生まれるだけで不幸でさえあるかもしれない。

長くなってきた

もう少し色々ダラダラ書きたかったんだけど、いったん切ることにする。

EdgeHTMLを諦めるというMicrosoftの判断は残念ではならない。非常に悲しい。

二要素認証進めるのに重要なのはメタファーだと思う

セキュリティ強化のために二要素認証を有効にする箇所が増えてきたけれども、サービスによってAuthenticatorとかSMSとか物理トークンとか色々な方法がある。

自分は色々あってSMS or 物理トークン派なのだけど、このうち、二要素認証を有効にするためにGoogle AuthenticatorやMicrosoft Authenticator入れろっていうのは自分はメタファーとして失敗してると思っている「セキュリティを向上させるためにアプリを入れましょう!」ってのは第一印象とストーリーがひたすら手間を増やしてるだけなので、むしろダメなんじゃねーのと思う。

SMSとかAppleハードウェアの二要素認証みたいに「何も入れずに済むけど、ログイン時に一回手間が増える」くらいがストーリーとして受け入れられる最低要件で、本来は物理トークンみたいに「セキュリティを担保するために鍵を指しましょう」みたいな人間にとって合理的なストーリーがないと二要素認証を有効にしたいって思う人はそんなに増えないんじゃないかな。

WebAuthnも標準化されて、Safariの実装状況を見るに来年か再来年には有効にしてきそうだし、「アプリを入れて二要素認証しよう!」ってのは多分そのうち自然消滅してくれそうな気はするけれども、なるべく早いうちにGoogle Authenticatorしか二要素認証対応しないサービスは考え直して欲しい次第。

チョッパヤ本を読んだ

超速! Webページ速度改善ガイドを読んだ。

超速!  Webページ速度改善ガイド ── 使いやすさは「速さ」から始まる (WEB+DB PRESS plus)

超速! Webページ速度改善ガイド ── 使いやすさは「速さ」から始まる (WEB+DB PRESS plus)

普段あまりこういう本は買わないのだけれども、友人達が書いていたので購入してみた。特に献本などもないのでどうでもいいかと思ってたんだけど、あとで印税貢献分としてコーヒー一杯奢れと著者両人にたかるネタとして良さそうなので買いました。

内容はGoogleの出しているWeb Fundamentalsのうち、パフォーマンスに関連するセクションを捕捉・再構成したような感じ。

巷では玄人向けという評価もあるけれど、それは本のターゲットの説明として大雑把にすぎると思う。 一読者たる私の感じたターゲットは、

  • Chromeのdeveloper toolsのperformance profilerの使い方がよくわからない
  • Webサイトの動作が遅くて困っている・困っていないが予防のための知識が欲しい
    • サーバー側の負荷には余裕があるのでクライアントサイドが原因だと思っている
    • どこが原因なのかわからないので、まずクライアント側から調べていきたい
  • 「Webフロントエンド」に関した(限った)パフォーマンス戦術の頻出パターンが知りたい
    • 余談ですが私は 「Webフロントエンド」という呼称が大嫌いです
  • Webサイト構築・運用におけるパフォーマンスについての考え方を知りたい

あたりの人向けの本だと思った。基本的にはWebクライアントサイド慣れしてない人向けの本だと思うし、ビギナー向けの本だとも思う。

逆にこの本に書かれていない内容としては

  • 2010年代のGUIアプリはなぜ60fpsを出さないといけないのか
  • システム全域に関わるパフォーマンスについての話
  • 「速いソフトウェア」の作り方と組織

とか。

ここら辺が知りたい人はAndroidを支える技術 part 1の第1章とか、Brendan Greggの"System Performance"とか、Joe Duffyの"Performance Cultue"あたりを読んどけばいいと思う。

具体的に感じたこと

第1章

  • Webサイトのパフォーマンスに関する概論的なお話。パフォーマンスやる意味とかを偉い人に説明するのに使うと便利とか、どういう技術的な指標を用いるかという話
  • npmとかNode.jsの使い方に関しては第1章に入れなくてもいいと思った。この本を読むような人種でnpmの使い方がわからない人種はあまりいないだろうし、想定するにしても「はじめに」の直後とかでよかったんじゃないかなあ。

第2章・第3章

  • ここら辺まではWebサイト構築に携わるエンジニアなら誰でも大雑把には知っておきたいところ。細かい設定の話とか覚えなくていいから。
  • ネットワーク処理周りの概論と具体的な調査方法、と言いつつもだいたいwebページがロードされるまでの話と、どういう指標があるのかについて
  • クリティカルレンダリングパス周りについては、ここら辺も読んでおくといいと思います

第4~5章

  • ここら辺から「Webフロントエンド」っぽくなってくる
  • ちなみにpainting時のrasterization周りはoff main threadになりつつあるので、メインスレッド(JSスレッド)の邪魔はしにくい処理系も出てきています(Display Listの構築処理は残っているので、そこのコストが消えているわけではない)
  • GPUの場合では、なぜテクスチャ転送のコストが発生するのかという原理的な話(コンピュータアーキテクチャ)については、個人的には解説があったほうがすんなりのみ込みやすくなると思うけれども、ターゲットを考えると省いて正解だとも思います。

第6~7章

  • 1本のメインスレッド(JSスレッド)のイベントループの中で、如何に不要な処理を間引きつつやるかという話。GUIプログラマーっぽい話。
  • 私見として、メモリリーク周りに関しては、ページ中のオブジェクトのライフサイクルを常に意識して適切にデストラクトして参照をnull埋めなどしてリークしにくい(GCにオブジェクトが回収されやすい)コードを普段から書いた上での、デバッグテクニックとして捉えるべきだと思う。

第8章

  • 画像などに関する取り扱い
  • これは実質ネットワークリソースの話だから、第4章の前とかに持ってきてもよかったんではないかなあ。

第9章

  • ServiceWorkerとResource Hint周りの話なので、特に感想はない

エモい書評書かないの?

特にエモい感情がわかなかったので.... 

終わりに

  • なんかダメ出し多くなってしまったけど、最近のWebサイトのパフォーマンスに関する話題をつまむのにちょうどいい本だと思います。
  • @著者両名 そのうちコーヒー一杯奢ってください