jQueryについての所感

昨今jQueryについての所感とつきあい方を考える

はじめはPHPとa-blog cmsがメインだったこのブログも、いつの間にかJavaScript(jQuery)とご飯レシピブログという謎な方向への珍走を遂げています。

そんな中、個人的にjQueryとのつきあい方について色々聞いたり思ったりで、だらだらとアウトプットしてみます。オチはつきませんでした。ダラァ...('A`)

ってこれ、今年の3月に大半書いていて、なぜか8月も末の今頃に加筆修正かけたので色々アレなところあったらごめんなさい!!!もったいないから公開させてください、、てへぺろ(・ω<)

なぜjQueryなのか

jQuery周辺のノリ(何でもjQuery・コスト感なくjQuery・jQueryスニペット信仰)などに、正直ネガティブな感情抱くこともありますが、素直な気持ちで見ればjQueryはとても効率的だと思います。Web上の情報は十分に多く、書籍も沢山でていて、読み書きできる人も多いです。

そんなjQueryの価値を素直に認めた上で、以下のような点に注意して私たちはjQueryを採用します。

  • アプリケーションの最終規模を見据える
  • 実行環境に応じて、適切な代替手段をさがす(MobileならZeptoやRiddleで十分とか)
  • MVCやAMDといった必要な構造化は、別のライブラリを頼る

得意なDOM操作

個人的に、DOM操作専用DSLとしてのjQueryを上回るのは難しいと感じています。$elmたる主語(subject)から始まり、$elm.show()のようにメソッドが述語(predicate)としてつながり、DOM操作が行われる流れは非常に分かりやすく十分に簡潔です。

// 非表示の要素をbodyに加えてフェードインする
$('div', {display: 'none'}).prependTo('body').fadeIn('fast');

他にも、たとえばTraversalメソッド群を見ると、(言うほど使わないメソッドも多いのですが)個々人の感覚に応じて様々なメソッドを選択して利用できるようになっています。作法の強制というよりは、好きな道具を使える触りのよさが提供されています。

もちろん要素群をオブジェクトの中に抱え込んで、生えてるメソッドでグルグル回して適用する、という中の処理を考えると、後ろめたい気持ちにはなりますが、そこはムーアの法則を信じて割り切ります

不得意な構造化

jQueryは手続き型のようなノリでつらつらと書かれることが多いです。それも、ふつうのWebサイトや小規模システムであれば問題ありません。規模が多少大きくなっても、そこそこ規模が大きくても何とかなるjavascriptの設計(URL dispatcherの薦めで紹介されているようなスニペットで対応できます。

大規模Webアプリケーションで実装を十分に構造化する方法(構造化の需要は小中規模でもありえますが...)についてはオフィシャルに提供されてはいませんし、一般的なベストプラクティスもあまり無いように思えます。

ただ、もちろんJavaScriptの本来に立ち返れば色々な構造化はアプローチできますし、jQueryプラグインや、jQuery.fn.exntendによる拡張などによってもアプローチは可能です。単純に非エンジニアが大きい範囲をカバーするようなソリューションは「jQuery」というハコの中には用意されていないということでしょう。

非エンジニア、と括りましたが、ようはそこまでJavaScriptほかプログラミング一般にウェイトを置いていないスタンスのひとですね

肥大化した需要

jQueryは、ある一定のところでライブラリ本来の使いやすさとは別に、元のJavaScriptよりも読み書きできる対象が多い共通知としての価値が生まれました。

たとえばブログや書籍で、簡単なDOM操作やイベントハンドリングを伴うサンプルを掲載するときにもjQueryは好んで使われる傾向にあります。jQueryで書けば、間違いなくシンプルですし、本来の説明したいことを適切に伝えられる簡潔なコードを実現できます。それは、JavaScriptは読めないけどjQueryなら読める層にもリーチするでしょう

var elm = document.createElement('img');
elm.src = 'http://dummyimage.com/50x50';
elm.alt = "ダミー画像";
elm.width = 50;
elm.height = 50;
document.getElementById('#target').appendChild(elm);

/* ↑同意↓ */

$('<img src="http://dummyimage.com/50x50" alt="ダミー画像" width="50" height="50" />').appendTo('#target');

上記のコードを見ると、jQueryの知名度を持ってすれば下のほうのコードで十分に伝わりますし、エンジニアは察せますし、非エンジニアでも類推可能性が上がります。

window.jQueryに文字列を与えたときの挙動がマルチプルすぎて訳分からなかったりとか、脆弱性のトリガーになってたりとか、色々功罪は感じるところです。てかサンプルのjQuery自体あぶないかんじに乱暴ですね、、

jQueryのコストとパフォーマンス

コストどころか税金と称されていますが、jQueryのコストは小さくありません。設計上で関数呼び出しが富豪的だったり、レガシーブラウザ用の黒魔術が多かったり、最近はDOM操作以外の機能が増えてライブラリサイズそのものが肥大化しているという側面もあります。

jQueryライブラリの肥大化

ライブラリの肥大化は、近年のバージョンだとこのような推移です。(バイト数はminifiedされた本体JSファイルのもの)

  • 1.3.2 → 57,254 bytes
  • 1.4.4 → 78,601 bytes
  • 1.5.1 → 85,260 bytes
  • 1.6.4 → 91,669 bytes
  • 1.7.0 → 94,020 bytes
  • 1.8.0 → 92,557 bytes

Deferredのように使う・使わないがキッパリ分かれるような機能をはじめとして、全体的に機能とライブラリのファイルサイズは増加傾向です。

ビルトインされた多くの使わない機能によって、無為にコストを支払わされると思うと嬉しくはありませんが、質の安定しないプラグインをかき集めるよりは、よほど効率的だという感もあります。

実際、gzipされていたりCDNで提供されていたりキャッシュされていたりと、ライブラリのファイルサイズがパフォーマンスに極端に影響を及ぼす心配は、PCブラウザ向けであればそれほど気にしなくても良いのかも知れません。

モバイルデバイスにおいては、1kbのJavaScriptのパースに1msかかるとか、そんな話も @t32k 氏から聞きましたので注意が必要です。もしも有名ライブラリ寄せ集めて、300kbあったら300msですし、結構バカにならないコストです。

個人的には、正直sizzleとbind&カスタムイベントが使えれば用済み感もあります。結局1.3系相当で済ませるのは大いにアリです。好みでいったらon/offのEvevntEmitterスタイルですが、差分35kbの価値は無いです

機能の選択的ビルド

どこかでえらいひとがモダンなJavaScriptはビルドするもの!って言っていたような気がしますが、まさしくそういう方向で、必要な機能を選択できるようにするカスタムビルドのアプローチが求められています。

カスタムビルドが実現すれば、モバイルデバイス向けのビルドや、コード量がかさばる機能はオミットしたミニマルなビルドなど、フルスタックへの不満の多くは解消できます。現状、カスタムビルドがないからこそ、Zepto.jsやjqmobiが生まれているような感じです。

レガシーIEのサポート

Remove IE 6, 7, and/or 8 support... That said, we know that older-IE support is not required in some scenarios such as mobile browsers. jQuery Blog » Call for jQuery 1.8 Ideas

未来の話ですが、jQuery1.8ではIE6・7と、もしかしたら8についても何らかの形でオミットすることが検討されています。とはいえ完全な廃止ではなく、カスタムビルドでサポートする方向です。

  • IE関連のコードとその影響を過大評価しすぎ(言うほど諸悪の根源ではない)
  • IE6・7にある問題のほとんどは8にもあるから難しい
  • レガシーIEのサポート打ち切りは、多くのサイトを壊してしまう
  • モバイルサイトのように、明確に不要なシーンではオミットできるように検討してる
  • IEを削ってもgzip後のサイズはそれほど小さくならず、パフォーマンス向上は期待しない

jQueryのように広く使われているライブラリがレガシーIEのサポートを打ち切るのは難しそうです。まぁ、それこそレガシーIEを想定する環境では、小さくて軽量なレガシーjQueryを使えばいいんじゃないか説も感じますけど。

開発側としては、そもそもIEのサポートを切って最適なミニマルを実現できたとしても、それで実効速度が改善することは考えづらいという見解のようです。

jQuery1.8

とか言ってたら半年の間にjQuery 1.8が出ておりまして、 カスタムビルドは提供されるようになりました。ただし、カスタムビルドにはgruntが必要らしく、これまた中々半端な選択肢だなぁ、と思う次第。

別にgruntで構わんのですが、gruntが0.4.0になってGruntfile.jsを強要するようになったら、切り替え時に瞬間的な混乱を生みそうな悪寒。

文化的な問題

jQueryとは本質的には関係がなく、利用者のレベルに依存した問題ですが、サンプルスニペット文化やプラグイン文化がパフォーマンスに影響を及ぼしていることは否定できません。

プログラミング初級者であっても扱いやすいという性質の反面で、稚拙なコードが量産されることも少なくありません。ノンプログラマからすれば自分の思うとおりの結果を出せればそれで良く、コードの質を高めるという活動のプライオリティが低いという背景も考えられます。

とはいえ、それはそれで糾弾するものではなく、そのような難しいことを考えずに結果を引き出せる生産性もひっくるめて、jQueryが支えているクリエイティブと言えます。

そういう暗部に眉をしかめたくなる賢明なプログラマ諸氏は、実情がより良くなるような取り組みを考えるべきでしょう。理解しやすい・実践しやすいプラクティスを提供するとか。

自分自身、jQueryすらロクに扱えない頃のことを思えば、変数なんて使っておらず毎回セレクタを立ち上げてメソッドを実行するような感じで、処理を書き連ねていたりしたので笑えません。

重いと言われるjQueryのコストを気にすべき限られた層

ここまでまとまりなくjQueryのコストとパフォーマンスについて書き連ねましたが、その300msにも(たぶん)届かない細々としたコストを気にすべき層は、実のところjQueryのユーザー層全体に対する割合として高くはないと考えています。

月々のセッション数も細々としていて、さほどミッションクリティカルでないコーポレートサイトともなれば、なおのことです。jQueryの初期化コストやパフォーマンスに対する懸念よりも、ライトユーザーがjQueryで受けられる恩恵のほうが圧倒的に勝ります。

実際の所、jQueryのコストを気にしようとしたところで、jQueryユーザーの大半にとって他の選択肢があるわけでもありません。よって、コストを気にすべきは以下に当てはまるような層に限定されるでしょう。

  • AjaxバリバリでViewをJSが担っているようなWebアプリケーション開発
  • フロントのパフォーマンス調整がシビア(100msが売上に関わるトラフィックとか)
  • jQuery以外のライブラリ等を使う技術的な余地がある
  • jQueryを使わなくても協業コスト・メンテナンスコストを十分に保てる

かなり狭まりましたね。特に一番下が満たせないようなら、丁寧にjQueryのベストプラクティスを集めて効率的に使い倒す方向に振った方が、よっぽど安全なようにも思えます。

総じて、長いものに巻かれるには相応の理由があるのかもしれません。

総論

jQueryに巻かれよう!(えー)

前職では、非エンジニア層に対してjQueryのレクチャーが計画されていたりしまして、やっぱりjQueryないしモバイル&モダンフォーカスのjQueryクローン(Zeptoとか?)は共通言語の第一候補だと感じます。国内で広めたいなら日本語を使うし、世界で広めたいなら英語を使うし、そういう数の優位に立った言語選択と同じ論理です。

  • 非エンジニアに、良いプラクティスを
  • エンジニアには、良いつきあい方を

エンジニアとして閉じた世界、ないしハイレベルな世界に生きられるなら別の探求方法もあるのでしょうが、世間一般の大勢を占める部分としては、まだまだjQueryの恩恵に預かる風潮が続くのではないでしょうか。

個人としては、jQueryがなくなっても困らないようにJavaScriptの基礎鍛錬を怠るべからずと思ってますが、まあそんな感じで。