そもそもjQueryとは何なのか
jQueryは、2006年に登場したJavaScriptライブラリで、
平成の時代で最も採用率が高かったライブラリと言っても過言ではないだろう。
jQueryUIや jQueryMobileなど、数多くのプラグインが公開され続け、
ReactやAngularと言ったSPAフレームワークがある中で、数多くのサイトで使われ続けている。
jQueryの目的
そもそも、jQueryの本来の目的は「ブラウザ間のJavaScript実装の差異を埋める」ことであった。
例として、とあるspan要素の中のテキストを操作したい場合、
とあるブラウザでは下記のように記述する。
var elem = document.getElementById('elem');
elem.innerText = 'Text';
一方上記の方法では動かず、下記のように記述する必要があるブラウザがあった。
var elem = document.getElementById('elem');
elem.textContent = 'Text';
こんなことが日常茶飯事であった。
これがChromeとFirefoxで差異が出たりしていたのだから笑えないものである。
ジオシティーズの全盛期、普通のWebサイトですら推奨ブラウザが各サイトに記載されていたのも納得である。
HTML5が策定された今、これらの差はだいぶ縮まったとも言えよう。
jQueryは、そんなWeb開発者の悩みを解決するのに一役買った。
どのブラウザであろうとも、下記のコードだけで済んだのだ。
$('elem').text('Text');
このように、jQueryはHTMLのDOM要素を書き換えるにはうってつけだった。
そして、何よりも「$」を使えばなんでもできると言う学習コストの低さ。
それもあってか、どんどんプラグインが作られていき、
「jQueryでできないことはない」とまで言われていた。
実際、「やりたいこと + jQuery」でだいたい事足りた。
どう考えても最強だった。
HTML5, CSS3の策定
HTML5とCSS3が策定されたことにより、
JavaScriptを使用せずによりリッチなUIを提供できるようになった。
簡単なアニメーションや見た目の操作を、
すべてCSSで実現することが出来るようになった。
SPAの登場
しかしその後、非同期通信が普通になり、よりスムーズなページ遷移が求められるようになった。
jQueryMobileは、遷移先のページを先読みし、アニメーションとともに画面遷移する方式を採用した。
それにより、モバイルのネイティブアプリのようなUXを実現した。
近年では、SPA(Single Page App)の採用率が増えており、
React.jsやAngular、Vueを採用するWebアプリが増えている。
SPAとjQueryを比べる
目的の違い
簡単にいうと、そもそもの目的が違う。
jQuery
→ サーバサイドレンダリングされたHTMLのDOMを弄るSPA
→ JavaScriptを利用して、クライアントで全てのDOMを生成する
jQueryの最大の利点にして欠点
jQueryの最大の特徴は、「描画されたDOMを書き換える」ことにある。
JSP(Java)やRazer(.NET)で書かれたHTMLを、
非同期で弄るのであるから、ビフォーとアフターの確認がしやすい。
しかしながら。
「DOMを操作するために一度描画される必要がある」のが最大の欠点とも言える。
とにかく動作が遅いのである。
HTMLの描画(ライブラリの取得)
→要素の取得
→書き換え
と言う順序をたどるため、HTMLの描画が遅ければ遅いほど、
画面が真っ白になる時間が増える。
これを画面遷移ごとに繰り返すわけだから、そりゃ重いわけである。
なぜSPAが早いのか
なぜ早いのかと言われれば、「ライブラリのロードが一回」であることに全てが起因する。
もちろん、「一度に全てをロードする」のだから、初速はとにかく遅い。
しかし、一度ロードされればその後は早い。
早い理由は簡単で、クライアントサイドで様々な処理を行っているからである。
その昔はクライアントの処理能力が貧弱であったため、
なんでもサーバサイドでやるのが普通だった。
しかし、近年はスマートフォンですら8コアが当たり前になるくらいで、
Webブラウザ(が動作する)PCの性能がどんどん上がった結果、ちょっとくらい重い処理でも簡単にこなせるようになった。
言ってしまえば、「クライアント処理時間」が早くなった結果、
「サーバ処理+通信時間」の方が長くなってしまった。
例として、100件のデータを表示することを考える。
サーバサイドレンダリングでの実装を考えると、
100件分のデータを含むHTMLデータを生成し、クライアントに返す。
つまり、HTMLとしてのデータが重くなる。
一方SPAの場合、
100件分のデータのみをサーバから取得する。
その後、HTMLのデータをクライアントが自身で生成する。
HTMLのテーブルを作成したことがある皆様ならピンと来るかと思うが、
HTMLタグは案外テキスト量としては結構多い。
なるべく通信するテキスト量を減らすことで、
通信コストを抑えてより早い描画を実現できる。
じゃあ、jQueryは捨てていいね!
そんなことはない。
例えば、こんなコードしかない場合、わざわざSPAに移行する必要もないだろう。
非同期通信もせずに、マウスイベントから説明を変更するような場合である。
$(function(){
// ホバー時のイベント
$(li).on('hover', function(){
// フッターのメッセージ書き換え
$('#footer_content').text($(this).text() + ' is selecting.');
});
})
ただし、こんなコードをjQueryで書く必要があるのであれば、切り替えを検討しても良いと思う。
<ul></ul>
<div id="loading" class="loading" style="display:none;">
now loading...
</div>
$(function(){
// ローディングの表示
$('#loading').show();
// 非同期通信
$.ajax({
url: 'http://sample.com',
success: function(data){
$.each(data, function(row){
// li要素の生成
var elem = $('<li>'+row.name+'</li>');
// クリックイベント
$(elem).on('click', function(){
// 中身を表示
alert($(this).text() + 'is clicked!');
});
$('ul').append(elem);
});
// ローディング終了
$('#loading').hide();
}
});
})
ポイントとしては、非同期通信とDOMの生成・追加を行っている事である。
ここまで来ると、SPAの方がコードも綺麗になるし、クライアントの処理も軽くなる。
ちなみに、同様のコードをAngularでかくとこうなる。
<ul>
<li *ngFor="let row of data" (click)="onRowClick(row)">{{row.name}}</li>
</ul>
<div *ngIf="data.length < 1" class="loading">
now loading...
</div>
// ~ 略 〜
export class ListComponent extends OnInit{
// 表示データ
data: DataRow[];
// 初期表示イベント
ngOnInit() {
this.loading();
}
// ローディング
loading(){
http.get<DataRow[]>('http://sample.com')
.subscribe((data) => {this.data = data});
}
// 行選択時のイベント
onRowClick(row: DataRow) {
alert(row.name + 'is clicked!');
}
}
行数は増えているように感じる・・・が、
処理と描画を分離してかける分、コードとしてはスッキリして見えないだろうか?
jQueryを採用するべきかのチェックシート
以下の条件に当てはまる項目が多ければ多いほど、SPA採用の利点が薄い。
よって、まだjQueryを採用して問題ないと言える。
- 静的なWebサイト
- UIはサーバサイドでHTMLをレンダリングした内容で固定
- 画面中に非同期通信はほとんどしない
- クライアントサイドの処理はほとんどない
- クライアントサイドでDOMを生成しない
- 業務アプリのため、カッコいいモダンなUIである必要はない
- アニメーションなど不要。あってもフェードイン/アウト程度でいい。
- IE対応が必須
逆に言えば、以下のような条件がある場合には、SPAを採用するべきであると言える。
- モダンなUXを提供する必要がある
- データの取得は全てREST API経由の非同期通信
- よく動くUI
最後に
- "jQueryは害悪・不要"と言った過激な意見をすぐ鵜呑みにしない
- jQueryは学習コストの低さが最強の利点
- もはやjQueryに固執する必要は全くない。
- すべてIEっていう奴の仕業なんだ