jQueryはJavaScriptライブラリの中で最も人気だと言えるでしょう。2021年の時点で世界の8割程度のWebサイトがjQueryを利用しているという調査もあったようで、いかにまだ愛されている技術かが分かります。
しかしながら、jQueryを使いつつ本当は「もうjQueryから脱却したい」と感じている人もいるかもしれません。 今回は
- なぜ脱jQueryする必要があるのか?
- 具体的な脱jQuery方法(WordPress等)
の二つについて語っていきます。
jQueryで何ができる?
この記事を見てくださっているということはある程度jQueryのことをご存じかと思うのですが、最初に軽く説明しておきましょう。
jQueryがJavaScriptライブラリの一種であることは恐らくご存じかと思いますが、では一体jQueryで何ができるのか、軽くおさらいしていきましょう。
コードを短くできる
jQueryが掲げているキャッチコピー、それは「Write less, Do more」です。より少ないコードでより多くのことをできるという意味ですが、実際にjQueryではある一定の操作について、生のJavaScript(通称:バニラJS) で記述するよりも短く、より見やすく書くことができたりします。
HTMLのDOM操作をとても楽に実装することができたり、Ajax通信(POST等)を簡単に実装できることなどが特に注目され、活用されてきました。
クロスブラウザ対応
JavaScriptはブラウザ上で動くプログラムですが、ChromeやInternet Explore等のブラウザの違いによってサポートしていない関数があったりもします。 そのためバニラJSだとそういったクロスブラウザ対応に神経を使わないといけなくなるのです。
そこでjQueryを使うと、内部でブラウザの種類を判別してくれて勝手に処理を変えてくれます。そのため、ブラウザの違いによってうまく動作しないという事件が起きにくくなるのです。
アニメーション実装
jQueryの恩恵を特に受ける場面としてアニメーションの実装があります。フェードイン(徐々に表れてくる) などのアニメーションはなかなか実装しづらいですが、jQueryを使うと「要素.fadeIn()」という超単純な関数だけで実装できるなどの強みがあります。
プラグインが用意されている
jQueryライブラリは、jQuery本体のファイルとは別に「プラグイン」と呼ばれる、jQueryと組み合わせることでさらに機能を拡張することができる仕組みが用意されています。
例えば「jQuery UI」はダイヤログボックス等のUIパーツをより簡単に実装することができるようにしたプラグインで、Webアプリ作りの手助けになります。
他にもCookieをより簡単に操作するためのプラグイン等も用意されていたりして、組み合わせることで膨大な機能を利用することができます。
脱jQuery、その理由は?
僕自身これまでに結構jQueryを使ってきた人間なのでjQueryの良いところみたいなのはいくらでもあげられる気がしますが、良いところばかり目を向けていては前に進めないですね。
そしてふとしたきっかけで「脱jQuery」みたいなのを調べていたら脱jQueryするべき理由が結構見つかってしまったので、紹介していきたいと思います。
JavaScriptが進化したから
jQueryが登場したのは2006年の頃で、その時jQueryを使えばとても簡単にDOM操作を行うことができると話題になっていたわけですが、そこから10年以上経った今、生のJavaScript自体に様々な関数が追加されたりして生のJavaScriptで同じことが楽に実装できるようになってきています。
document.querySelectorAll('div.sample ul li')[5].textContent = 'テキスト'; //Vanilla
$('div.sample ul li').eq(5).text('テキスト'); //jQuery
例えばdiv.sample ul liというCSSセレクタによって指定されるli要素のうち、0から数えて5番目のものの中のテキストを「テキスト」に変更するという処理を実装しようとしたら上のようになります。
確かにjQueryの方が短くはあるのですが、バニラJSに「querySelector」というメソッドが追加されたことで同等のことをほぼ同じコード量で実現することができるようになっています。
しかもこのクエリセレクタによって得られる要素は、jQueryでは独自の「jQueryオブジェクト」というものなので「eq」というよくわからないメソッドを使わないといけなかったりする一方で、
バニラJSではHTMLElementオブジェクトという一般的な配列のようなものが得られるので、番号を指定するときも単純に「[5]」とやるだけで良かったりして非常に扱いが楽です。
他にも、通常の配列として扱える分forEachやmapなどの便利なJS関数を利用することもでき、なんだかんだでJavaScriptの方が便利かもしれません。
また、アニメーションについても、最近ではCSS(スタイルシート)である程度アニメーションが作れるようになっているので、正直JavaScript側でそこまで頑張らなくてもってのはありますね。
jQuery処理の具体的な書き換えについては後程紹介します。
クロスブラウザ対応を考えなくて良くなったから
以前まではIE(Internet Explorer)などの比較的機能が遅れているブラウザに対応するために工夫する必要がありましたが、現在ではIEはそこまで使われていない上に、ブラウザにおけるJavaScriptの機能の足並みがそろってきているので、クロスブラウザ対応についてそこまで神経質になる必要がなくなったというのがあります。
jQueryはクロスブラウザ対応を実現するために中で複雑なコードが組まれているところもあるので、その分動作が遅くなってしまうんですよね。わずかですが。
重い
jQueryは非常に高機能なライブラリであり、びっくりするほど奥深いです。そしてライブラリ自体のコードもびっくりするほど長いです。最新版(3.7.0)についてもコード全体が100KBくらいあったりして、読み込む際にレンダリング処理を阻害してしまうなどしてページの表示速度に影響が出てしまう恐れがあります。
とはいえ、当サイトBableTechもjQueryを使っているときにページ表示速度スコア(Google)99点をとったくらいなので、別に表示速度を改善したいなら絶対にjQueryは使うなってわけでもないです。
でも、同じ機能を生のJavaScriptでほぼ同じコード量で記述することができるなら、ここまで重たいライブラリを読み込むメリットがあまりないですよね。
脱jQuery手順
さていよいよ本題です。脱jQueryを行う手順についてです。
今回、実際に当サイト(BableTech)の脱jQueryを実現してみたのですが、その際の具体的なコードの書き換え例を紹介していきたいと思います。
ちなみに、以下の記事で紹介している通り、jQueryを使っているつもりが無くてもWordPressなどにおいてはプラグインやテーマがjQueryを自動的に読み込んでいるケースがあるため、ご注意ください。
【WordPress】間違ったjQueryの読み込み方【みんなやってる】
その場合はそういったプラグインを削除したりしないと完全に脱jQueryできたとは言えず、あまり意味がありません。
要素取得・操作
jQuery
//要素取得・操作(jQuery)
const element = jQuery('div.sample ul li'); //セレクタで要素を取得
element.css({color:'black'}); //該当の要素の色を黒に
element.eq(5).attr('id','5th'); //5番目の要素のIDを変える
element.each(function(){
jQuery(this).text(jQuery(this).text() + 'テキストを追加'); //それぞれの要素のテキストを書き換える
console.log(jQuery(this).prop('tagName')); //タグの名前をコンソールに出力
});
let DOM = "";
element.each(function(){
DOM += `<li>${jQuery(this).text()}</li>`; //li要素を作っていく
});
jQuery('#here').html(DOM); //HTML出力
Vanilla JS
//要素取得・操作(Vanilla)
const element = document.querySelectorAll('div.sample ul li'); //セレクタで要素を取得
element.forEach(e => e.style.color = 'black'); //該当の要素の色を黒に
element[5].id = '5th'; //5番目の要素のIDを変える
element.forEach(e => {
e.textContent += 'テキストを追加'; //それぞれの要素のテキストを書き換える
console.log(e.tagName); //タグの名前をコンソールに出力
});
document.getElementById('here').innerHTML =
[...element].map(e => `<li>${e.textContent}</li>`).join(''); //li要素を作ってHTMLコードを作ってそれを出力
HTML要素の取得・操作は最も基本的なJavaScriptの処理と言えるでしょう。 jQueryでは非常に簡単にCSSセレクタで要素(jQueryオブジェクト)を作ることができています。
一方で先ほど紹介したようにVanilla JSについてもquerySelectorAllを使っていとも簡単に要素(HTMLElementオブジェクト)を取得することができます。
ここで、querySelector()では1つ目の要素が取得できるのに対して、querySelectorAll()ではセレクタにマッチした要素がすべて配列形式で取得できます。
また、jQueryでは.cssメソッドによって簡単にCSSを書き換える(インラインで) ことができます。jQueryでは該当のすべて要素のCSSを一気に書き換えられるところが良いですね。
一方でVanillaについてはHTMLElementオブジェクトの.styleプロパティの値を変えていくことでCSSを書き換えることができます。
しかしquerySelectorAllによって取得した要素は配列であり、HTMLElementオブジェクトではないので、すべての要素に適用するためにはforEachで回す必要があります。 でも上のようにアロー関数を使うことで非常に簡単に実装ができます。
続いてidなどの属性値については、jQueryでは.attrというメソッドを使うことで取得、編集ができます。
一方でVanillaについては一部の属性を除いて、基本的にプロパティ形式で取得、編集ができます。これに関してはJavaScriptの方が直感的で良いですよね。
また、HTMLや要素内テキストの書き換えについてもjQueryではメソッドで対応しますが、VanillaではinnerHTMLやtextContentなどのプロパティで対応します。
個人的にこちらの方が直感的で好きです。
tagName(要素のタグ名)などのプロパティの取得についても、Vanillaではプロパティ形式ですぐに取得することができ、素晴らしいですね。
また、一番下の処理のように、Vanillaの方ではmap関数を駆使することができるので便利ですね。ただしquerySelectorAllによって得られた配列は直接書き換えられないため、スプレッド構文を使って新しい配列を作っています。
要素位置・大きさ
続いて要素の位置や大きさの取得等についてです。
jQuery
//要素位置・大きさ(jQuery)
const element = jQuery('#sample'); //セレクタで要素を取得
console.log(element.width()); //要素の幅を取得
console.log(element.offset().top); //要素のページ内でのY座標を取得
Vanilla JS
//要素位置・大きさ(Vanilla)
const element = document.getElementById('sample'); //セレクタで要素を取得
console.log(element.clientWidth); //要素の幅を取得
console.log(element.offsetTop); //要素のページ内でのY座標を取得
VanillaではclientWidthとかoffsetWidthとかいろいろあったりしてややこしいですが、プロパティ形式で取得できるのがなんか個人的に好きです。jQueryだと何を取得するにしてもメソッド(関数)を実行しないといけない傾向にあって、なんとなく好まないですね。
アニメーション・動き系
jQuery
//アニメーション・動き系(jQuery)
const element = jQuery('li.sample').eq(0);
element.fadeIn(); //フェードイン
element.scrollLeft(500); //横スクロール
Vanilla JS
//アニメーション・動き系(Vanilla)
const fade = (mode,e) => {
if(mode=="in"){
if(e.style.display != "none") return false;
e.style.display = "block";
e.style.opacity = "0";
const anime = e.animate({opacity:"1"},500);
anime.onfinish = () => {e.style.opacity = "1";}
}else{
if(e.style.display == "none") return false;
const anime = e.animate({opacity:"0"},500);
anime.onfinish = () => {e.style.display = "none";}
}
}
const element = querySelectorAll('li.sample')[0];
fade("in",element); //フェードイン
element.scroll({left:500,behavior:"smooth"}); //横スクロール
アニメーションに関してはJavaScriptだとそこまで簡単にいかないですね。それを補うためのライブラリもあったりはしますが、別に簡単なフェードイン関数ならanimateなどの関数を使って上のように実装できます。 これでうまく動作する保証はできませんが、なんかとりあえず大丈夫そうだったので私はこうしました。
また、スクロールなどについてもscrollという関数を使えば簡単に実装できます。なんだかjQuery関数のほとんどがVanilla JSの方ですでに実装されている感じがしますね~
イベント系
jQuery
//イベント系(jQuery)
jQuery(window).on('load', function() { //ページが読み込まれた直後の処理
const button = jQuery('div.sample a');
button.on('click',function(){ //それぞれのa要素がクリックされたとき
console.log(jQuery(this).data('content')); //data-content属性値を出力
});
});
Vanilla JS
//イベント系(Vanilla)
window.addEventListener('load', () => { //ページが読み込まれた直後の処理
const button = document.querySelectorAll('div.sample a');
button.forEach(e => { //それぞれのa要素について
e.addEventListener('click',() => { //クリックされたとき
console.log(e.getAttribute('data-content')); //data-content属性値を出力
})
});
});
addEventListenerメソッドを使えば簡単にイベント検出処理を行うことができます。jQueryの方が若干、直感的に実装できる気はしますが、慣れてくればVanillaの方が見やすく感じてきますね。
POST通信
jQuery
//POST通信(jQuery)
const url = 'sample.php';
const id = 1000;
jQuery.ajax({
async: true,
type: "POST",
url: url,
data: {
"action": "get_info",
"id": id
}
}).done(function (data) {
data = JSON.parse(data); //JSON文字列を配列化
console.log(data);
});
Vanilla JS
//POST通信(Vanilla)
const url = 'sample.php';
const id = 1000;
let params = new URLSearchParams();
params.append('action','get_info');
params.append('id',id);
fetch(
url,{method:'POST',body:params}
).then(res => res.json()
).then(data => {
console.log(data);
});
Ajax通信についても、一昔前では圧倒的にjQueryの方が書きやすかったイメージですが、現在ではVanilla JSでfetchという関数を使ってここまで簡単に実装できます。
もはやjQuery要らないですね。
以上になります。他にもVanilla JSでも同じくらいのコード量でjQueryと同じ機能を実現できる事例がたくさんありますので、ぜひ「~ jQueryなしで」みたいにいろいろな処理を検索してみてください。
また、ChatGPTなどの対話型AIを駆使してもjQuery→Vanilla JS変換ができるみたいなので、やってみてください。まぁコーディングをChatGPTに任せるのは極力やめた方が良いと思いますけどね…
上のような書き換えを行って、実際にBableTechでは一般投稿ページでの脱jQueryを果たしました。もともと表示速度はバグレベルで速かったのですが、さらに速くなった気がしますね。
BableTechよりも表示速度が速いサイトはほとんど見たことが無いです。 以下の記事でそのノウハウをたっぷりと紹介していますので、ぜひご覧ください。