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

平日WEB系SE 週末時々自転車屋

WEB系の技術ネタや大好きなお酒、週末手伝う自転車屋の話などを書きます。

超便利!はてなブログに自動でグローバルメニューを表示させる方法(チューニングバージョン)

表示が遅い

以前作ったグローバルメニューですが、機能的には満足いくものにはなったのですが、PCでも表示がもっさりして遅く、スマホでは表示される前に画面を下に移動してしまう位遅いので、チューニングしてみることにしました。

 

 以前の記事 

jitenshaya-se.hatenablog.com

 

遅い原因

遅い原因ですが、jQueryで遅い場合の大体の原因がこの4つです。 

  • 要素の指定(セレクタ)の仕方が悪い
  • 同じセレクタの使い回しをしていない
  • DOMの操作の回数が多い
  • ループのまわし方が悪い

 

要素の指定(セレクタ)の仕方が悪い

特に要素の指定の仕方が悪く、要素を見つけるまでに効率の悪い順番で処理をされてしまう場合が多いです。前回のコードでは要素を特定するのにclass指定とタグのみで指定していたので遅いです。

※前回のコード

$(".hatena-module.hatena-module-category .hatena-module-body .hatena-urllist li a");

 言い訳になりますが、ソースの読みやすさを優先したためこのようなコードを書いていたのですが、やはり体感できる位遅い場合はそんなことを言っていられないので修正します。

IDだけで指定できれば一番早いのですが、IDだけではサイドメニューのカテゴリは指定できないので、IDでサイドバーの中だけに絞り、クラスとタグで一気に絞り込みます。

※修正後のコード

$("#box2-inner").find("div.hatena-module-category li");

その際にclassの指定については全てのタグを探すのではやはり効率が悪いのでタグを指定しました。

 

同じセレクタの使い回しをしていない

何度も利用するようなセレクタは最初に変数に入れてその変数を使いまわすほうが早いです。※前回のソースではこちらに当てはまる部分はありませんでした。

 

DOMの操作の回数が多い

何度もDOMの操作をしてHTMLを組み立てるよりも、あまり格好良くないですが、文字列としてHTMLを組み立てて、最後にDOMに追加するようにした方が早くなります。

 

ループの回し方が悪い

また、ループを回す際にもjquery特有の便利なeachなどを使ってしまいますが、できるだけjavascriptの素の処理を使ったほうが早いの、for文を使うようにします。

 

※前回のコード

globalnavi = $("#globalmenu nav ul");
$(".hatena-module.hatena-module-category .hatena-module-body .hatena-urllist li a").each(function(index, element) {
globalnavi.append('<li><a href="' + $(element).attr("href") + '">' + $(element).text() +'</a></li>');
});

※修正後のコード

var categoryobj = $("#box2-inner").find("div.hatena-module-category li");
for (var i=0; i< categoryobj.length; i++) {
var category = categoryobj.eq(i).find('a');
title = title + '<li><a href="' + category.attr("href") + '">' + category.text() + '</a></li>';
}

 

最終的なコードはこんな感じになりました。

$(function(){
var title = '<div id="globalmenu"><nav id="globalnavi"><ul><li><a href="/archive">記事一覧</a></li>';

var categoryobj = $("#box2-inner").find("div.hatena-module-category li");
for (var i=0; i< categoryobj.length; i++) {
var category = categoryobj.eq(i).find('a');
title = title + '<li><a href="' + category.attr("href") + '">' + category.text() + '</a></li>';
if(i > 3){
break;
}
}
title = title + '</ul></nav><div>';
$("#blog-title").after(title);
});

 

PCで表示した場合はヘッダーの画像とそれほど変わらない時間で表示され、スマホの場合はやはり多少は遅れますが、まあ許容範囲だと思います。

 

 ※2015 6/25にこちらのグローバルメニューを画面をスクロールした際に画面上部に固定されるように改修した内容について公開しました。 

jitenshaya-se.hatenablog.com