メインコンテンツへ移動

JS コードガイドライン

無料2015-03-17#JS#Mind#js代码优化#平稳退化#渐进增强

Web フロントエンドはバックエンドほど直接的ではなく、ブラウザの互換性の問題など、処理すべき煩雑なことがたくさんあります。良い JS コードはスムーズにデグレードし、後方互換性を持ち、パフォーマンス最適化が施されているべきです。良いコードを書くためには、プログレッシブエンハンスメントなどのガイドラインに従う必要があります

一.スムーズなデグレードとは何か?

JS コードを含むウェブページが、ユーザーのブラウザで JS がサポートされていない(または JS が無効化されている)場合でも、ユーザーが引き続き正常に閲覧できる(ウェブサイトの機能は正常で、視覚効果が若干劣る可能性がある)場合、そのウェブページはスムーズにデグレードしていると言えます

ウェブページがスムーズにデグレードすることは非常に重要です。JS は昔から評判が良くなく(さまざまな広告、ポップアップ、さらには XSS などの陰湿なものまである)、ブラウザの JS サポートを習慣的に無効にするユーザー層が存在します。このユーザー層は大きくないかもしれませんが、コーディング担当者としては、できるだけコードを完璧にすべきです(まるで自分の子供を育てるようなものです)。このような状況を考慮し、あらゆるユーザーに完璧な体験を提供すべきです

上記の理由がまだ十分でない場合、より重視すべき点があります。SEO、つまり検索エンジン最適化です。自分のウェブサイトを検索結果で上位に表示させたいなら、SEO を適切に行う必要があります。検索エンジンのクローラーは JS コードの意味を理解できないため、検索エンジンのクローラーは JS をサポートしない古いブラウザを使い続けるユーザーに相当します。明らかに、このユーザーは非常に重要です

二.どのようにしてスムーズにデグレードするか?

スムーズにデグレードするには、1 つの原則に従うだけで済みます。プログレッシブエンハンスメントです

いわゆる「プログレッシブエンハンスメント」とは、最も基本的で重要な機能を実装するために、いくつかの原始的で信頼性の高い方法を使用し、まず機能の完全性を保証してから、追加の情報層で元のページをラップして(表示効果を実現し、より良い視覚効果とユーザー体験を実現する)、たとえ服が剥がされても機能は完全なままですが、見た目が若干劣る可能性があるだけです

JS コードと HTML コードを完全に分離することで「プログレッシブエンハンスメント」を実現できます。HTML は機能が完全な元の層であり、外部 JS コードは華やかな外衣です(CSS のように聞こえますが、実際その通りです。JS 機能は非常に強力ですが、JS コードに過度に依存すると主従が逆転します)

三.後方互換性とは何か?

後方互換性とは、JS コードが低バージョンの DOM と互換性を持つことを指します(一部のブラウザは最新バージョンの DOM をサポートしていない可能性があり、特定の DOM API が使用できなくなることを意味します)。例えば:

最も一般的に使用される DOM API はこれらかもしれません:

document.getElementById();
document.getElementsByTagName();
document.getElementsByClassName();//HTML5 DOM 中的新特性

しかし、これらのメソッドを全くサポートしていないブラウザ、または一部のみをサポートするブラウザがあるかもしれません。その場合、JS コードのエラーによりページにアクセスできなくなるか、ページ機能が完全ではなくなります

以前、後方互換性を保証するために使用されていた方法は「ブラウザ検出」技術でした。つまり、BOM を使用してブラウザに「この DOM API をサポートしていますか?」と尋ねる方法です。ブラウザは非常に多いため、非常にシンプルな JS コードでも多くの層のブラウザ検出コードでラップする必要があり、コードが非常に膨らんでしまいます

ブラウザ検出技術は実際には CSS にもまだ存在します。もちろん CSS は BOM を通じてブラウザの機能を取得できないため、より受動的な方法を採用しています:

/*设置透明度为 0.75*/
filter: alpha(opacity =   25); /\*支持 IE 浏览器\*/
-moz-opacity: 0.25; /\*支持 FireFox 浏览器\*/
opacity: 0.25; /\*支持 Chrome, Opera, Safari 等浏览器\*/

DOM は現在まで発展し、ブラウザ検出技術を使用して後方互換性を保証する必要はなくなりました。次のようにすることができます:

if(document.getElementById){
    document.getElementById();
}
if(document.getElementsByTagName){
    document.getElementsByTagName();
}
if(document.getElementsByClassName){
    document.getElementsByClassName();//HTML5 DOM 中的新特性
}

このより良い方法は「オブジェクト検出」技術と呼ばれます。まだ完璧ではありません(完璧にするには、ブラウザ市場が統一される必要がありますが..)、ブラウザ検出よりもはるかに優れています(少なくとも市場に新しいブラウザが出現したからといって JS コードを修正する必要はありません)。オブジェクト検出は BOM に依存せず、DOM 自体が指定された DOM API をブラウザがサポートしているかどうかを検出します

四.JS パフォーマンス最適化テクニック

  1. DOM への JS アクセスを最小限に抑える
  2. HTML マークアップを最小限に抑える
  3. JS スクリプトを結合する
  4. script タグの位置
  5. JS コードを圧縮する

1.最適化前:

for(var i = 0;i < document.getElementsByTagName("a");i++){
    if(document.getElementsByTagName("a")[i].getAttribute("title") == "main"){
        //do something
    }
}

最適化後:

var elems = document.getElementsByTagName("a");
for(var i = 0;i < elems.length;i++){
    if(elems[i].getAttribute("title") == "main"){
        //do something
    }
}

DOM メソッドを呼び出してタグオブジェクトを取得するたびに、内部で DOM ツリーの完全検索が行われます。これは非常にコストのかかる操作です。DOM アクセスを最小限に抑えることでパフォーマンスを向上できます

2.最適化前:

<div>
    <div>
        <div>
            <div>
                <div>
                    <p>
                    正文
                    </p>
                </div>
            </div>
        </div>
    </div>
</div>

最適化後:

<p>
正文
</p>

この例はやや極端かもしれませんが、問題を説明するには十分です。HTML コードはできるだけ簡潔にすべきです(期待通りの表現効果を達成できれば十分です)

3.最適化前:

<scrpit src="./scripts/A.js" type="text/javascript"></script>
<scrpit src="./scripts/B.js" type="text/javascript"></script>
<scrpit src="./scripts/C.js" type="text/javascript"></script>

最適化後:

<scrpit src="./scripts/All.js" type="text/javascript"></script>

ブラウザはページをロードする際に script タグに遭遇するたびに、タグが外部スクリプトファイルを指している場合、外部ファイルをロードするためのリクエストを送信する必要があります。script タグが多すぎると、このオーバーヘッドは無視できなくなります。したがって、JS コードをすべて 1 つの外部ファイルに配置し、1 つの script タグでロードすべきです

4.最適化前:

<head>
    <script></script>
</head>

最適化後:

<body>
    html code
    <script></script>
</body>

つまり、script タグを body の末尾に配置してロードするのが最も速く、ここに配置しても window.onload などのイベントのトリガーには影響しません。なぜこの位置に配置するのが最も速いのかというと、ブラウザが HTML コードを解釈する順序に関連している可能性があります(head 部分を先にロードし、head が大きすぎると、ユーザーが body コンテンツを長時間見られないまま待たされることになります)

5.最適化前:

var elems = document.getElementsByTagName("p");
for(var i = 0;i < elems.length;i++){
    //do something
}

最適化後:

var elems=document.getElementsByTagName("p");for(var i=0;i<elems.length;i++){}

はい、その通りです。最適化後のコードは人間が読むためのものではありませんが、読みづらいものの、このようなコードは体积小さく、外部ファイルのサイズを小さくするため、当然パフォーマンスを向上できます

P.S.この作業を支援するための専用ツールがあります。例えば JSMin などです

参考資料:《JavaScript DOM プログラミングアート》

コメント

コメントはまだありません

コメントを書く