Edited at

片手間のJavaScriptから脱出するためにこれからのWebエンジニアが理解すべきこと


はじめに

最近、こういった記事が世間をにぎわせている。こりゃエヴァの話なんてしてる場合じゃねぇ!と思ってさくっとこの辺の事情を理解するために必要なことをまとめてみる。


GoogleやTwitterでも実現できないのだから使うな問題

この話は、どの地点の何の話をしているのかよくわからないのです。現在ではかなりステップバック&改善が行われ、Safari自体のクラッシュはアプリのクラッシュと比べて、あまり多いとは思いません。むしろ、一昔前に比べてかなり改善しているという認識です。iOSのバージョンが古いとかでなければ、現状でも十分ユーザビリティの改善につながっているでしょう。

しかし、この問題の結構大部分を占めているのは個人的にはいわゆるアプリっぽいListViewの実装についてだと思うのです。twitter、facebook、gmailはいわゆるListViewと個別のView、固定のナビゲーションヘッダというアプリ的なUIにmobile safariのCSSがposition:fixedを理解しない当時から取り組むというチャレンジングなことをしていました。

その当時の認識も結構あるのかなと思います。あるいは未だにandroid2.1系つかっているひとは、お願いだから買い替えてください。お願いします。IE5.5のほうがまだましです。


ListViewの問題

ListView、とくに無限スクロールできるものはコンテンツが増えれば増えるほどメモリを圧迫し、動作が重くなったりします。これに対応するために独自スクロール+リングバッファのようなものを用意したり、表示外のデータのサイズだけ固定し、DOMを削除し、必要なタイミングで再描画したりと結構な工夫が必要です。iOS、AndroidのListViewも再描画させる設計のインタフェースを持っています。

Ember.jsの無限スクロールの改善

シンプルに実装するのであれば、このあたりを読んで実装するのがいいかと思います。

また、必要ないのであればこういったUIを使わないほうがいいでしょう。なにかとアプリっぽくするとアプリの挙動との違いに違和感を覚えるユーザーは多いです。

ListViewに求められるスクロールスピードとブラウザのスクロールスピードが違うというのも問題を複雑にしています。できればCSSでコントロールできるようになってほしいですが、ユーザビリティのために慣性スクロールを実装しているところもあります。

Facebookは比較的早い段階で、fixed+慣性scrollから、シンプルで高速なListViewという実装に切り替えているようです。

ザッカーバーグ氏の「HTML5に賭けたのは失敗」発言には続きがある。長期的にはHTML5への期待も語る

Twitterは2年くらい前にフロントエンドを大幅に改善しています。このタイミングで、自前scrollをやめてたりします。

Twitterがページ表示時間を5分の1に高速化。どのようなテクニックを使ったのか?

この記事には次にのべるhistory API+initial Viewの話が大半なのですが、だいたいこのくらいの時期でした。

アプリにはアプリ、ブラウザにはブラウザのユーザビリティ改善があります。それは、アプリと一致させることとは限りません。しかし、それとJavaScriptを使う使わないは関係ないです。それはガラケーのUI設計の場合に有効な考えですので、昔を懐かしんでお酒でも飲むといいと思います。

プラットフォームごとに適したユーザビリティを実現しましょうというのがこの記事の結論です。


history APIとinitial viewの問題

数年前までhtml5のhistory APIはすべてのブラウザで利用できるという状態ではありませんでした。

その代替として、hashfragmentとonhashchangeイベントまたはsetIntervalなどでのhashfragmentの監視という手段をtwitterは利用していました。( URLがtwitter.com/#!/user/postid から twitter/user/postidに変わったので覚えている方も多いと思います。)

twitterはtweetごとのリンクが外部に張られることの多いサービスなので、hashfragmentによるSPAの実現では、indexページのロード+XHRによるコンテンツのロードと2回のロード+ jsのtemplate engineのコンパイル、描画といくつもフェーズを挟む必要がありました。


よく訓練されたSPAはSPAと気がつかない問題

そういえば、githubのファイルブラウザ部分も、history APIとXHRの組み合わせであることにお気づきでしょうか?少し前まで、アニメーションがわずかに付与されていたので、わかりやすかったかと思います。

ですが、現在の実装では、ページ遷移とほぼ区別がつきません。これも部分viewの実現ではありますが、高速化に寄与しています。

google mapのUIもページのリロードをしていませんが、一般ユーザーはほとんどそのことに違和感を覚えないでしょう。JavaScriptを捨てるというのは、2006年以前のwebに戻ることとほぼ同義です。


viewの二重定義問題

history APIなどで、URLを書き換えて、XHRリクエストを行って部分viewの更新を実現する場合には二通りの手段があります。

一つは、サーバー側で部分ViewのHTMLのレンダリングと全体のHTMLのレンダリングを等価的に行う方法です。

この場合、ネイティブアプリ向けのAPIも作らなければならないので、3通りのレスポンスが1つのドメインロジックにひもづくことになります。

もう一つは、ネイティブアプリ向けもJS向けも同じAPIを用いて、フロントエンド側でレンダリングする方法です。この場合、全体Viewがサーバサイド、PartialViewがフロントエンド実装になるなどし、場合によっては二つテンプレートを書く必要があります。

この問題に5年半前くらいに取り組んだ記事がこちらです。

http://alpha.mixi.co.jp/2009/10682/

現在では、node.jsなどでサーバサイドを実装することでjsのtemplate engineであればこの問題は解決しますよね。


飽きた

他にも


  • Application CacheやLocal Storageなどの高速化とキャッシュの破棄問題、

  • Sever Push、リアルタイムメッセージングなどのステートレスサーバでほんとにいいの問題、

  • Webコンポーネント、Object.observe、Model driven ViewでMVVMどうよ問題、

  • Deferred、Promise非同期コールバックの透過的なUIパーツ化どうするよ問題、

  • アプリとWebViewどうやって共存させるよ問題、

  • 名前空間、依存関係管理、アセットパイプラインどうするよ問題などなど

現代的でユーザビリティの高いWebアプリケーションを作るために必要なパーツはいろいろあって、

個人的には、その都度作ったり、作ってもらったり、探して組み込んだりというのが2010年くらいからの流れで、そのとき必要なものを作っていった感じ。

https://github.com/hirokidaichi/namespace-js

https://github.com/hirokidaichi/brook

最近はこれらの問題を個別に解決するソリューションが百花繚乱のごとくあらわれ、HTML5の実装もかなり進んできて、方向性もいくつかに定まってきたねというところ。

これをワンストップソリューションで、どんなアプリケーションでもいい感じにかつ簡単でかつオープンソースで!というのはあと数年は必要だろうなというのが個人的感覚です。

逆にそうなったときにはもっと別の技術的な潮流が出てきていて、誰でも簡単にできるようなるまで使わないポリシーだと仕事にならんので、それぞれが必要なものを作っていくのがいいのかなと思います。