読者です 読者をやめる 読者になる 読者になる

将来は標準のDOM APIを使うのがより身近になると思ってる

最近、標準のDOM APIは別に悪くない、と考えるようになった。 そう考えて劇的に何か変わるかというと、現時点ではライブラリを使うことに慎重になるという気分的なものかもしれない。

気分が変わった結果として、僕は直近のプロジェクトのごくふつうのWebページでは、標準のDOM APIを直接さわる形に変更した。フレームワークは使わずRxJSのみ使っている。結果、パフォーマンスと細かいUIの挙動とコードの透明度が改善された。

標準のDOM APIは、べつに不必要に冗長なところがあるわけではないし、扱っているものが特別プリミティブ過ぎるとも思わない。むしろ、意図しない動作が入りずらく、インターフェイスが明示的にできている点なんかは優れている。 欠点があるとすれば、あらゆるスコープから好きなNodeの書き換えが禁止されてない点、クライアントサイドでのレンダリングのサポートが弱い点、何をするにもまず検索 (querySelector) しないといけない点かな。

しかし、これらを解決するにあたって、今流行しているようなアプローチが、将来に渡って必要とされ続けるかどうかは少し疑問視している。

今流行しているアプローチというのは、標準DOM APIをラップしたレイヤーを介すようなもの。たとえば、DOM要素を常にコレクションとみなして抽象化するjQuery。HTMLテンプレにDSLを埋めて暗黙の動作をさせるもの(vue, angular)。仮想DOMや、仮想DOMにコンパイルされるJSXでのみ記述するものとか。

これまでは、そうしたアプローチが良いと思って、従ってきた。 しかし、最近はあまりそう考えなくなった。

jsが辿ってきた進化の道を一旦引き返し、現代のようにブラウザ互換性にそこまで問題がなくなった状況からもう一度進化をはじめたとき、別のやりかたが見えてくる気がする。

最初期に必要とされたライブラリであるjQuery は、ブラウザ間の互換性を吸収する必要があったからこそ広く使われたことは間違いない。 これは現在はさほど問題にならない。babel や polyfill が必要ではあるけれど、ブラウザのAPIはそのまま使える状況になった。

また、jQueryの、よりショートハンドでDOM操作が記述できてかっこいい、という魅力的な面は、ファッション的な良さの域をそこまで出ていないと思う。 もちろん、コードにおけるファッション的な良さは気分的にはとても重要なことには変わりないけど。

jqueryに限った話ではなく、独自のHTMLテンプレを書くのようなものも、コード量がかなり減ることは間違いない。

ただし、近頃は、「暗黙の動作をしようが何しようがとにかくコードが短く書ける」ことの価値が昔ほど高くなくなってきている。それによって支払う代償が高くつくなら、多少コードの行数の面で不利だとしても、明示的なインターフェイスが正しい。という価値観になってきてないだろうか。

Webプログラミングの仕事をして10年くらいになるのでなんとなくそれはわかる。 証拠としてはすこし弱いが、TypeScriptがけっこう人気になっている点が挙げられる。コード量が多少増えてもコンパイル時に型安全が保証されるメリットが遥かに上回るとされる価値観。最近の静的型な言語は、型推論によってファッション的にそこまで悪くないということがあるけど。

大きく変わったのは、アプリケーションというものが多様化したことだと思う。 プロジェクトごとに、作りたいものの完成図に開きがありすぎるので、それら全ての需要に応える、「皆が欲しかった暗黙の動作」というものがない。フロントエンドになればなるほどこの傾向が強い。だから、これさえ使っていればだいたいうまくいくというフレームワークはない。

僕が想像している将来のjsフレームワークは、標準DOM APIをそのまま使いつつ、コードを構造化してくれるようなもの。

// たとえば、
class HogeComponent extends Component {
  constructor() {
    super()

    // Viewレイヤで、標準DOMElementオブジェクトが安全かつ自動で参照できる    
    this.hogeField.value = 'hoge' 
  }
}

こうしておくと、たとえばデータバインディングのようなものも、ふつうにjsで書けばよく、暗黙のDSLのようなものでifとか書く場合と比較してパフォーマンスが良く、動作も明示的。

// Rx ならこんなかんじで書けますね
observable
  .subscribe(v => {
    this.hogeElement.value = v
  })

考えてみると、他のGUI環境ではこうしたアプローチが当然だ。とにかく標準のViewオブジェクトはラップしてから使う。というjsの価値観はすこし奇妙と言うこともできる。

標準DOM APIをさわるようなViewレイヤをつくることはいくつか反論が考えられる。

  • ユニットテストが書けないのでは?
  • HTMLテンプレの上にさらにViewレイヤができてしまい冗長では? 
  • クライアントサイドレンダリングをきれいに書けないのでは?

ユニットテストについては、上のようなインターフェイスであれば、スタブをつくるのはそこまで難しくない。あるいは、ViewModelレイヤを別でつくってそこを重点的にテストする。

HTMLテンプレの上にさらにViewレイヤができるのはたしかに冗長だが、iOSのViewControllerと同じようなものと思えば慣れそう。

クライアントサイドレンダリングを標準DOM APIがサポートするまでは仮想DOMを併用するのが現時点では良いとおもっている。WebComponentsに期待。

そんなかんじです。