高性能のJavaScript仕上げ要約で[フロントエンドのパフォーマンスの最適化

高性能JavaScriptの仕上げの概要

フロントエンドのパフォーマンスの最適化には:最初に考えたのはあるヤフー軍事法規34
「高性能JavaScriptを」読んで最近と
例知識の一種とのいくつかの個人的な理解追加することを本のおそらく大多数の
この参考書は、ヤフーの特殊な性能を有しています研究チームは、34の軍の規制は非常に多くの類似点があるとの
コメントエリアにむらがあり、私を修正して感謝してください〜

表記法:多くの単語を構文例では、文書ドキュメントを指す略記され、重要な点は、符号ビットが省略された表現、コードワードが容易ではない(/手折り畳ま)

1.ロードして実行します


  • JavaScriptは、負荷ので、シングルスレッドで、JavaScriptが上から下にロードされ、実行した後、bodyタグ内のJavaScriptファイルので、通常、ページが読み込まリソースをブロックします、次のファイルへの完全なロードを実行し続けるの多くの後、下下のラベルの外側ボディの端の開発者は、これは悪い場所で、2があります:1、2、非標準、可能 jsのページ要素がエラーの結果を得ることができない原因は。フロントページのレンダリングの実施を確保するために、内側本体の底面のラベルには、完全なJSです 
<body>
js...                         //正确
</body>
<!-----------------------分界线---------------------------->
<body>

</body>
js...                         //错误
  • マージスクリプト、それぞれの<script>タグの初期のダウンロードには、<SCRIPT>タグの数は、最適化に埋め込まれたスクリプト外部スクリプトGMの役割を再生することができ、加算HTTPで追加のパフォーマンス消費をもたらすので、ページを縮小、ページのレンダリングをブロックしますスクリプトが4つ以上の1つの25キロバイトのファイルにダウンロードすることができますので、それがもたらすにHTTPリクエストを大量に消費するものの、マージダウンロードは100KBのファイルより速く、<SCRIPT>タグ番号2を、還元して、(外部スクリプトのために)低減しますツールは、私たちは合併作業を完了するに役立ちますが、原則は、まだ下の知っている必要があります。

専用ケース:期間埋め込まれた直後にスクリプト外の連鎖ので、チェーンのスタイルシートのダウンロードの外に待機を行って、最も正確なスタイル情報を取得するための時間の実施を確保するために、インラインスクリプト:CSSのラベルの背後には、につながりますこれは、障害物がスタイルシートをダウンロードするページを待つことがあります。次のとおりです。

//错误示范
<link ... href='...'>
<script>
  内嵌脚本...
</script>
  • 非ブロックJavaScriptをダウンロードする3つの方法:

1.延期属性の<script>タグ、延期説明:スクリプトの実行の規定は、ページが読み込まアップまで遅延するかどうか。
2.使用して、動的に作成した<script>要素をダウンロードすると、一般的に動的なスクリプトインジェクションとして知られているコードを、実行し、推奨されます:スクリプトを動的にbodyタグ、ページのロード中にスクリプトの特に実装、身体よりも安全headタグにロードされましたいないすべてのコンテンツのロードが完了すると、IEはエラーの可能性があります

var script = document.createElement('script');
    script.type = 'text/javascript';
    script.src = 'a.js';
    document.querySelectorAll('head')[0].appendChild(script);

などLAB.js LazyLoadライブラリ(遅延ロード)など3.ページをダウンロードするためにXHRオブジェクトおよびJavaScriptコード注入は、一般的に使用されるツール


2.データ・アクセス


  • JavaScriptの四つの基本的なデータ・アクセス・場所:

1.リテラル:自分の代理として、特定の場所のない、あって:文字列、数値、ブール値、オブジェクト、配列、関数、正規表現とnullとundefined
2.ローカル変数ます。varを/ / constキーワードのデータが定義されて聞かせ記憶部
3の配列要素:0からJavaScriptオブジェクト内のメモリアレイは、数値インデックス付け、インデックス開始
4.対象部材:JavaScriptが内部に格納されたオブジェクト、インデックス文字列
ローカル変数とリテラルからアクセス最小の消費性能(無視できる)、およびオブジェクトの配列データが若干高くなっています。
推奨:リテラルと(手動nullに設定するか、あまりにも不定に使用レリーズ操作方法の後に変数自体、)ローカル変数のメイク使用、及びそのような複数回唱える基準範囲の関数の値としてオブジェクトの配列の使用を減らします、それが使用されるローカル変数に格納することができます

var doc = document.querySelectorAll... ,
    a = doc.getElement... ,
    b = doc.getElement... ,
    c = doc.getElement... ;
  • スコープ

、VUEアセンブリで使用される場合、CSS、スコープ特性を考える:各関数は、オブジェクトが関数のインスタンスであるように、関数オブジェクトは内部プロパティを提供して表される[範囲] JSエンジンは、属性(トピックを読み取り変更されたパターンファイルは、[[スコープ]]が作成された機能の役割のドメイン内のオブジェクトのコレクションが含まれている場合のみ)アセンブリに作用するために、セットには、スコープチェーンの関数です。実行環境を作成する場合、スコープチェーンは、[範囲]のオブジェクトプロパティに初期化され、スコープチェーン実行環境にコピーされ、順番に現れます。そして、実行環境は、環境破壊の実装は、活動オブジェクトも破棄され、すべてのローカル変数、名前付きパラメータ、パラメータセットと、この、などの操作する変数オブジェクトの関数として「アクティブオブジェクト」、「アクティブなオブジェクト」を作成します。

関数が実行されると、各変数の面は、ここでデータを取得または記憶するように決定する(遅い読み出し変数に対応する識別子深い位置)解決プロセス識別子に供されます。
よく、類推を理解していない、スコープのスコープを含むA Bは、BはCスコープ、対応する識別子Cの範囲を見つけるための変数に応じて、C-範囲で見出さない場合、それを含むスコープ最終的グローバル変数で検索する場合、検索の範囲は、Bスコープは、変数が発見され、パフォーマンスが文書がグローバル変数で、やはり上記の例で消費検索範囲、検索処理を、見つける行かなかったBに移動します、それはローカル変数に置かれているが、より迅速に発見されます。
TIPS:第1のバックシールドを見つけ、最初の範囲を横断しながら、スコープチェーン変数に同じ名前の二つの異なる部分は、識別子が検出された存在します。各ブラウザ識別子解像度レート差。
推奨:可能な限り、ローカル変数を使用します

それは第二の目的でスコープチェーンが表示され、すべてのローカル変数を作るため、ステートメントとのtry catch文のスコープチェーンは、スコープチェーンを変更することを避けるために声明で、変化させることができるとともに、

function aa() {
        with(document){               //访问document变快了,访问其他局部变量变慢了
            var bd = body,
                links = getElementsByTagName('a'),
                i = 0,
                len = links.length;
            ...
        }
    }

次に試すキャッチはエラースローcatchブロックを処理する内部ブロックを試して、スコープチェーンは、catchブロック文が終了すると、スコープチェーンはその前の状態に戻ります、変更されています

  • ダイナミックスコープ

、とトライキャッチ、または含まれているのeval()関数は、動的範囲と考えることができますが、彼らは唯一の動的スコープの実装の過程であり、それは、コードの構造を見ることによって検出することができない、必要なだけで推奨ダイナミクススコープ

  • クロージャ
function assignEvents() {
        var id = '2341321';
        document.querySelectorAll('#aaa').onclick = function (event) {
            saveDom(id);
        }
    }
var idNew = id;  //undefined

ローカル変数として、idが唯一の現在のスコープで訪問することができ、適用範囲が訪問しませんが、スコープに、このイベントハンドラは、ローカル変数IDを取得することができ、それはassignEventsがassignEventsを取得する方法のsaveDomの外となりますローカル変数のID。この機能を達成するために、クロージャ[範囲]プロパティは、実行、実行環境破壊は、アクティブなオブジェクトも破棄されるべきオブジェクトassignEventsスコープチェーン実行環境(オブジェクトのid属性)を指すが、ためにクロージャが活性化されるアクティブなオブジェクトで、その結果、導入され、より多くのメモリ空間を必要とする、破壊することができません。目的を達成するために、非ネイティブIEのJavaScript DOMオブジェクトを使用するので、閉鎖は、メモリリークが発生することがあります。なぜなら閉鎖消費の性能をもたらすように、クロスsaveDom変数IDについて意見の範囲を、溶液である:共通クロススコープ変数はローカル変数に格納されています
スコープチェーンの実行環境と閉鎖


  • オブジェクトのメンバー

ほとんどのオブジェクト指向のJavaScriptコードが書かれている(カスタムオブジェクト、BOM / DOM)、それは非常に頻繁にアクセスオブジェクトのメンバにつながります。だから、また、ローカル最適化するためのアクセス権を持つオブジェクト
のネストメンバー:オブジェクトは、他のメンバーの中に入れ子にすることができる
ネスティング時間は読書の深さに比例しています

  • プロトタイプチェーン

前の紋切り型の回答に比べ見える答え、最初のソ連のメキシコのオレンジの答えを、オススメ、これは理解することが容易になり
、プロトタイプチェーンに


3. DOMプログラミング* *(一般的なパフォーマンスのボトルネック)


3つの質問:
1.アクセスとDOM要素変更
DOM要素のスタイルと再配列が再描画につながる2.変更を
DOMイベント処理とユーザーとの対話によって3を

  • JUDGMENT

DOMは:ドキュメントオブジェクトモジュールドキュメントオブジェクトモデル、オペレーティング・プログラム・インタフェースのドキュメントとして理解することができます
遅いDOMは、DOM操作は高価である理由、理解するためのシンプルな2点である独立した限りとして相互に接続されたインターフェイスを介した機能は、それが消費を生成します。例えば:中国の人々はiPhoneを買う、アメリカ人は魏ロング、給与税の必要性を買う、消費税は、JavaScriptからDOMへのDOMからJavaScriptに、同じまたは類似の消費を持っています。
だから、特定のパフォーマンスの最適化を実現するために、このような税の数を減らすためにしようと、
最悪のアクセス動作やDOMへの道は、サイクル性能で消費されます。

//bad
for(var i = 0; i < 10000; i++){
    document.querySelectorAll('#aaa').innerHTML += 'a';
}
//good
var aaaHtml = ''; 
for(var i = 0; i < 10000; i++){
    aaaHtml += 'a';
}
document.querySelectorAll('#aaa').innerHTML += aaaHtml;
  • innerHTMLプロパティやDOMメソッド(doc.createElement())については誰より速く

Web標準を考慮せずに、ほとんど。
WebKitのカーネル、innerHTMLの高速化の最新バージョンよりもブラウザ、古いブラウザより効率的に加えて、
WebKitのコアブラウザのDOMメソッドの新バージョンである速い
クローンノードは、効果は非常に明白ではない最適化をもたらし、スキップ
コレクションをローカル変数の要素を使用しているとき(操作要素は何回も理由であると、詳細には触れません)

  • DOMのトラバーサル

一般的には、querySelectorAllは()要素が最速のAPIが返すのNodeListで取得
querySelector()要素、返し
querySelectorAll()もう一つのポイントは、あなたが同時に要素の2種類を得ることができるということです

var two = doc.querySelectorAll('div.aaa,div.bbb');
  • 再描画と再配置

ブラウザのダウンロードすべてのコンポーネント--htmlタグページは、JavaScript、CSSの後に生成された構文解析し、画像2つの内部データ構造:
ページ構造の1.DOMツリー表現は、そのような遊び場の朝の練習としては、あなたがここに立って、赤、あなたの小さな緑そのステーション、ボブ...(出)、ヘクタール、ジョーク、などDOMツリーの位置などの構造が
ツリーレンダリング2.
DOMノードは、赤、緑、小さな赤い服のように緑の服を表示する方法を示していますが、暁明長い髪と緑の髪と赤いウールのコートを着て、そして小さなので、

レンダリング種の少なくとも存在に対応するノードに現れるDOMツリーの各ノード(ノードに対応する隠された要素が、それはこれを使用することが可能である、第一の表示要素の隠蔽は、パフォーマンスと消費を最適化するために処理)、レンダリングツリーノードは、モデルのCSSの定義に沿って、「フレーム」や「箱」と呼ばれています。DOMおよびレンダリングツリー構築が完了したとき(ボックスモデルは、ボックスの中に落ちていない)、ブラウザは、スタートページ要素を表示します。
とき、それは再描画し、それを再配置するために開始されます。

DOMの変更は、幾何学的属性に影響を与えた場合、ブラウザは、ツリーの患部を再構築レンダリングツリーに失敗レンダリングされます。このプロセスは、再編成を知られているが、そのようなクラスの座席正しく、暁明は時間グレート脂肪200ポンドの一定期間の後、暁明は今、他の学生が座って両側に必要か、当然のことながら、後ろに座る2つの位置を必要と、位置に座っていた、ボブはしません良いか悪いかは、暁明の結果に依存します出て行け。
再配置が完了した後,,ブラウザが画面に患部を再描画します、このプロセスが再描画と呼ばれ、
DOMの非幾何学的属性を変更する場合、再描画が行われます、再配置されません。
再描画し、再配列が高価である。最小化

:転位が発生
1.追加または可視DOM要素削除
2.位置変化素子
3素子サイズ変更(内側及び外側マージン、境界、広い高い厚さ)
(コンテンツ寸法変化をもたらす)4.コンテンツ変更
5.ページのレンダリングを初期
6.ブラウザのウィンドウサイズの変更

  • 転位還元再描画
//三次重绘
el.style.borderLeft = '1px';
el.style.borderRight = '2px';
el.style.padding = '5px';

//一次重绘
el.style.cssText = 'border-left: 1px;border-right: 2px; padding: 5px';

どのようにバルクを削減し、DOM修正再配置再描画するには:手順に:
1.そのフロー要素から文書
2.変更のマルチプレクス
3文書への要素の背面が//転位工程13倍

そう三つの方法から文書DOMこと:
1.隠し要素-アプリケーションの変更-表示
2.文書フラグメントは、現在のサブツリー外DOMを構築し、次いでバック文書コピー
文書からノードへの3コピーを、コピーを変更、コピーがオリジナルの要素を置き換えます

  • アニメーションストリームから要素をしてみましょう

一般的には、再配置は、レンダリング・ツリーのほんの一部に影響するだけでなく、大部分、あるいはそれらのすべてに影響を与える可能性があります。大規模な再編成は、ユーザーがユーザーエクスペリエンスに影響を与え、ページの食事食事を見つけてみましょうことが
最も転位のを避けるために:絶対位置を使用して要素は、文書の流出させる-アニメーション-復元します

  • IE和:hover

スタートIE7からは、IEは任意の要素で使用することができます:ホバー擬似セレクターができますが、多数の素子を使用したときの応答速度がよりIE8を発音され減少します

  • イベントのデリゲート:イベントが親にバブリングによって捕獲されます

各バインドは、イベントハンドラは、価格で
泡立てる-目標到達する-キャプチャ:3つの段階でイベント
のデフォルトを防ぐために(オプション)をバブリングキャンセル、イベントソースを決定するために、イベントオブジェクトのアクセス:互換性の問題イベントのデリゲートをアクション(オプション)
デリゲートイベントハンドラを減らすためにイベントを使用して数


4.フロー制御アルゴリズムと


  • 循環

ほとんどのプログラミング言語の1つの重要な部分は、ループの中で最も時間のかかるコードの実行は、ループのパフォーマンスを向上させることです

JavaScriptの4つの主要な反復:
1.Forサイクル

Tips:for循环初始化会创建一个函数级变量而不是循环级,因为JavaScript只有函数级作用域(ES6存在块级作用域if(){let n = ...}let定义的n只作用于if块内部,执行完就会释放不会导致变量提升),所以在for循环中定义一个变量和在循环体外定义一个变量时一样的
var i = 100;
for(var i = 0; i < 10; i++){
    console.log(i)  //0,1,2,3...9
}

2.whileサイクル
3.do-whileループの
循環で4.for
ヒント:任意のオブジェクトを列挙することができるサイクルのためにプロパティ名(ない値)が、他の3以上のサイクルにするためにかなり遅いので、あなたがしたい場合を除き繰り返し処理の対象と既知の属性の数のような、より速くよりも内のプロパティリスト、他のループを横断する場合、ループ内で使用して、未知のオブジェクトの属性の数、または避けます。

    var arr = ['name','age'],
        i = 0;
    while(i < arr.length){
        process(object[arr[i]]);
    }    

サイクルのタイプをサイクルの性能を最適化するように4つの上記特性は、2つの側面からのものであり得ることが想定される:
(場合、ループ複雑X、優先最適化ループの複雑さを低減し、ループの複雑さは、最適化Xよりも大きいです優先)反復回数を減らす
1.トランザクションの各反復を()ループの複雑さを軽減するために
反復の数を2(サイクル数は、百度「ダフ機器が」)ため、デバイスは周期ダフ分解されることを理解すべきで低減されます、配列の長さを横断する100のような、ループは通常の状況下で100回行い、各分割サイクルのダフ装置100と考えられている複数回(nは)を行っ100 N-Iが取る、私は実行の数を取りますそして次にN(丸いダウン)サイクルで割っ100を実行し、ループ本体が実行されているN倍通常のサイクリック操作体
Iが言ったダフ・デバイス・コード:(これは8 N)

    var i = items.length % 8;           //先循环余数次数
    while(i){
        process(items[i--]);
    }
    i = Math.floor(items.length / 8);   //再循环8的整数倍次数  循环体是普通循环的8倍 可以写成函数传参调用
    while(i){
        process(items[i--]);
        process(items[i--]);
        process(items[i--]);
        process(items[i--]);
        process(items[i--]);
        process(items[i--]);
        process(items[i--]);
        process(items[i--]);
    }

プロパティを最小限にして下さい:

for(var i = 0, len = arr.length; i < len; i++){
    ...
}

反復関数に基づい:forEachの()
のforEachのすべてのメンバーがアレイを横断し、機能を実行します

arr.forEach(function(value, index, array){
    ...
})

しかし、すべての場合で下。優先度ベースの反復ループ反復関数に基づいて8倍の速さよりも反復機能、厳しい速度要件に基づいて、ループの繰り返し

  • 条件文

if-else比較スイッチ:
使用のif-else条件読みやすいが少なく、ときのif-else条件よりパフォーマンスのオーバーヘッドの大きなスイッチよりとき、読みやすさは十分に切り替わりませんでした。
他に、もし最適化方法は次のとおりです:のような、最初の場所で発生する可能性があります条件できるだけ

    var i = Math.random(1);     
    if(i <= 0.8){            //i小于0.8是几率最大的,如果i的值满足i <= 0.8 后面的条件就不会再判断了
        ...
    }else if(i > 0.8 && i <= 0.9){
        ...
    }else{
        ...
    }

何度も、このような10や10など:(条件)、のif-else条件文の使用を避けるためには、最善の方法は、ハッシュテーブルを使用することです切り替えます

  • メモ化

: -作業負荷を軽減することは、最高のパフォーマンスの最適化手法である(私は実際にこれらの単語を言った魯迅あなたは、パフォーマンスの最適化のためのカットの需要を理解することができ、これは、魯迅が言っている)
キャッシュ前に計算作業のメモ化の回避の重複、結果は後ろ計算に使用され
、それぞれ4,5,6要因など
、私は5の階乗の結果をキャッシュするので、6要因が要因であり、階乗6、結果は6の5を乗じて

<!--Memoization缓存重复运算的值-->
            function memoizeA(n) {
                if(!memoizeA.cache){
                    memoizeA.cache = {
                        '0': 1,
                        '1': 1
                    }
                }
                if(!memoizeA.cache.hasOwnProperty(n)){
                    memoizeA.cache[n] = n * memoizeA(n-1)
                }
                return memoizeA.cache[n]
            }

            var a1 = memoizeA(4)
            console.log(a1)          //24
            var a2 = memoizeA(5)
            console.log(a2)            //120
            var a3 = memoizeA(6)
            console.log(a3)           //720

            <!--封装为方法-->
            function memoize(func, cache) {
                cache = cache || {};
                
                var shell = function (arg) {
                    if(!cache.hasOwnProperty(arg)){
                        cache[arg] = func(arg);
                    }
                    return cache[arg];
                }
                return shell;
            }
            var funCcc = function ccc(n){
                if(n == 0){
                     return 1;
                }else{
                    return n*ccc(n-1)
                }
            }
            var a4 = memoize(funCcc,{"0":1,"1":1});
            console.log(a4(6));         //720

文字列と正規表現


説明:正規表現私はしませんが画像のキャプション、ここで言うことができません

性能比較4つの縫合方法列:
A:str = str + 'a'+'b'
B:str += 'a' + 'b'
C:arr.join( '')
D:str.concat( 'B'、 'C')
AとBとの間の比較のために:Bがメモリ内に作成され一時的な文字列、「AB」割り当てられた一時的な文字列、アサイン一時的な文字列strの文字列の連結; Bよりも多くのブラウザが、IE8での以前のと、Bは、より良い、Aよりも
最初の二つの参加、連結プラススプライシング効率について:

    //+=
    (function () {
        var startTime = new Date().getTime();
        var str = '';
        var addStr = 'hello world~, hello xiaojiejie';
        for(var i = 0; i < 100000; i++){
            str += addStr;
        }
        var endTime = new Date().getTime();
        console.log('字符串str += a:');
        console.log(endTime-startTime);
    })();
    // +
    (function () {
        var startTime = new Date().getTime();
        var str = '';
        var addStr = 'hello world~, hello xiaojiejie';
        for(var i = 0; i < 100000; i++){
            str = str + addStr;
        }
        var endTime = new Date().getTime();
        console.log('字符串str = str + a:');
        console.log(endTime-startTime);
    })();
    //concat
    (function () {
        var startTime = new Date().getTime();
        var str = '';
        var addStr = 'hello world~, hello xiaojiejie';
        for(var i = 0; i < 100000; i++){
            str = str.concat(addStr);
        }
        var endTime = new Date().getTime();
        console.log('字符串str.concat:');
        console.log(endTime-startTime);
    })();
    //join
    (function () {
        var startTime = new Date().getTime();
        var str = '';
        var arr = [];
        var addStr = 'hello world~, hello xiaojiejie';
        for(var i = 0; i < 100000; i++){
            arr.push(addStr);
        }
        str = arr.join('');
        var endTime = new Date().getTime();
        console.log('字符串join:');
        console.log(endTime-startTime);
    })();

私は、統計的な平均値、平均値、A> B> C> Dの上に、下chrome65に簡単なテストでこのコードを使用していない他のブラウザをテストしていない
、IEの中で述べて、本の古いバージョンを参加比較的高速ですが、また、多数の文字スプライス文字列への唯一の効率的な方法
を用いて詳細いくつかの文字列連結のパフォーマンス


6.高速対応するユーザインタフェース


  • ブラウザUIスレッド

JavaScriptのコードであってもよいJavaScriptを実行し、ユーザインタフェースがUIスレッドのキュー・システムに基づいて作業、「ブラウザUIスレッド」と呼ばれる更新する処理プロセスがアイドル状態のときに、それは抽出タスクを実行するためにキューから変更され、 UIも(再描画、再配置)を更新することができます。
UI:ユーザーインターフェイスのGUI:グラフィカルこの画像からユーザインタフェースのリンクタイムリミットブラウザのJavaScriptタスクを実行し、リミット2分、悪質なコードの実行を防ぐことができますようにブラウザをロックし続けて単一のJavaScriptの総運転時間がかかるが少ない100msのに等しいよりべきです、100msの内の動作応答のユーザーが、それ以外の場合は、ユーザーが遅いの感覚を感じることができるようになることを意味しています
画像のキャプション

  • 時間にタイマーフラグメントをしてみましょう

コードは、操作が完了し、複雑な100msの場合は、その利得制御UIを更新することを、時間の作品を作るためにタイマーを使用することができます。

这个例子只是说明JavaScript单线程,定时器可以把任务放到后面执行,方便理解
console.log(111);
setTimeout(func(){console.log(222)},0);
console.log(333);
//111 333 222

タイマーは、JavaScriptのタスクに戻すことができるので、JavaScriptは、シングルスレッドで、最初にUIスレッドを制御
数ミリ秒偏差,, 25msのの、Windowsのシステムタイマの分解能のタイマー精度、最小の遅延時間を設定することが提案されています25msのの

サブ一連のタスクにタスクを置く
機能が短期実行サブルーチンに分解されて、長い時間を実行するために、

素早く最適化コード部分に長い上映時間を見つけるために、プログラムの実行のタイムスタンプを使用して計算して得られました

重复的定时器会抢夺UI线程的运行时间,1秒及以上的低频定时器不会有什么影响,当使用高频100ms-200ms之前的定时器时响应会变慢,所以高频重复定时器使用要注意

  • Web Workers (HTML5新特性)

在UI线程外运行,不占用UI线程的时间
来自W3C的worker demo
Web Workers不能修改DOM
运行环境组成:
一个navigator对象
一个location对象(与window.location相同 属性-只读)
一个self对象,指向worker对象
可以引入需要用到的外部文件importScripts()方法
可以使用js对象 Object、Array、Date等
XHR
定时器
close() 立刻停止Worker运行

W3C介绍Web Worker
博文:Web Worker原理和应用介绍
实际应用场景:处理纯数据或者与UI线程无关的长时间运行脚本,个人觉得大量的纯计算可以考虑使用


7. Ajax(阿炸克斯)


前面说到数据存取会影响性能,理所应当的,数据的传输同样影响性能
Ajax通过异步的方式在客户端和服务端之间传输数据。

  • 数据传输

请求数据的五种方式:

A:XMLHTTPRequest(简称XHR)
最常用异步异步发送和接收数据,包括GET和POST两种方式
不能跨域
GET--参数放在url后面,请求得到的数据会被缓存,当url加参数超过2048,可以使用POST方式
POST--参数在头信息,数据不会被缓存
XHR工作原理及优缺点参考选我选我

B:动态脚本注入
其实就是创建一个script元素这个元素的src不受当前域限制,但是不能设置请求头信息,也就是只能用GET方式

C.Multipart XHR
MXHR荀彧一个HTTP请求就可以传输多个数据
通过在服务端讲资源打包成一个双方约定的字符串分割的长字符串发送到客户端,然后根据mime-typed类型和传入的其他头信息解析出资源
缺点:资源不能被缓存

D.iframe
E.comet

发送数据:XHR、Beacons、

  • 数据格式

A.XML
优点:通用、格式严格、易于验证
缺点:冗长、结构复杂有效数据比例低

B.JSON
JSON.parse():JSON-->对象
JSON.stringify():js值-->JSON字符串
文件小、下载快、解析快

C.JSON-P
在客户端注册一个callback, 然后把callback的名字传给服务器。此时,服务器先生成 json 数据。 然后以 javascript 语法的方式,生成一个function , function 名字就是传递上来的参数 jsonp。最后将 json 数据直接以入参的方式,放置到 function 中,这样就生成了一段 js 语法的文档,返回给客户端。

D.HTML
E.自定义数据格式

  • Ajax性能

最快的Ajax请求就是没有请求(贫一句:最快的写程序方式就是天天跟产品拌嘴,砍需求,那啥,我先跑了,产品拿着刀追来了)

避免不必要的请求:
服务端设置HTTP头信息确保响应会被浏览器缓存
客户端讲获取的信息存到本地避免再次请求(localstorage sessionstorage cookice)
设置HTTP头信息,expiresgaosu告诉浏览器缓存多久
减少HTTP请求,合并css、js、图片资源文件等或使用MXHR
通过次要文件用Ajax获取可缩短页面加载时间


8. 编程实践


  • 避免双重求值

eval()、Function慎用,定时器第一个参数建议函数而不是字符串都能避免字符串双重求值

  • 使用对象或者数组直接量

直接量:

var obj = {
    name:...
    age:...
}

非直接量:

var obj = new Object()
obj.name = ...
...

运行时直接量比非直接量快

  • 避免重复工作

A:延迟加载(懒加载)
进入函数-->判断条件-->重写函数
B:条件预加载
函数调用前提前进行条件检测
var addEvent = doc.addEventListener ? funcA : funcB

  • 使用JavaScript速度快的部分

A.位操作
B.原生方法,首先原生方法是最快的,而且浏览器会缓存部分原生方法
C.复杂计算时多使用Math对象
D.querySelector和querySelectorAll是查询最快的
当用Document类型调用querySelector()方法时,会在文档元素范围内查找匹配的元素;而当用Element类型调用querySelector()方法时,只会在这个元素的后代元素中去查找匹配的元素。若不存在匹配的元素,则这两种类型调用该方法时,均返回null。


9. 构建并部署高性能JavaScript应用


这一章讲的都是其他章节的优化原理的实践,主要有:
1.合并多个js文件
2.预处理js文件
3.js压缩
4.js的HTTP压缩
5.缓存js文件
6.处理缓存问题
7.使用内容分发网络(CDN)这个有点效果显著的感觉,前年第一次用的时候感觉快了很多,打个比方就是:
京东网上水果蔬菜超市,假设你在上海买了一个榴莲,京东可以在上海的仓库给你发货,如果上海没有他们的仓库,就在离你最近的一个仓库发货,以保证最快速度送到你手上(吃什么不好,吃榴莲,别人会说食屎拉你)。这个仓库放的就是静态资源文件,根据请求发出的位置找到最近的CDN节点把资源返回给请求端,大概是这个意思,具体原理参考CDN原理
现在很多方式都在gulp、webpack工具里进行了,方便省事


10. 工具


  • JavaScript性能分析

使用Date对象实例减去另一个实例获得任务运行时间毫秒数

  • 匿名函数

测量分析匿名函数的方法就是给匿名函数加上名字

  • 调试工具

個人的にクロムデバッグツールのような
いくつかのより完全なチュートリアル貢献
基本
最適化された記事の
戦闘
リアル2
英語はじめに使用して、

  • スクリプトブロック

Safari4、IE8、Firefox3.5、クロム及び上記のスクリプトを並行してダウンロードすることができますが、実行ブロッキング、より高速なファイルのダウンロードが、しかし、スクリプトがなくなるまでページには、任意のブロックをレンダリング
不要、実行速度の遅いスクリプトの最適化や復興のスクリプトページのレンダリングが完了リロードするまで待ちます

  • ページスピード

表示と時間のかかるを解析JavaScriptを実行し、それはあなたがスクリプトを拡張できることを示しているがロードされ、レポート機能で使用されていません

  • フィドラー

フィドラーは、ボトルネックの負荷を見つけるために、すべてのネットワークリソースを検出することができHTTPデバッグプロキシツールです。

  • YSlowの

YSlowのツールの最初のページのロードのプロセスの全体的なパフォーマンスへの洞察力と実行

  • WebPagetest

WebPagetest:ユーザーのブラウザ真の接続速度に応じて、ウェブ速度テストが世界規模で行われ、詳細な最適化のヒントを提供します。
WebPagetest

  • GoogleのPageSpeedの

ベストプラクティスのWebページの解析と最適化のテストに基づいてのPageSpeed。

  • Pingdomのウェブサイトのスピードテスト

ページの読み込み速度テストにURLアドレスを入力して、パフォーマンスのボトルネックを分析し、特定します。
Pingdomのウェブサイトのスピードテスト

多くの同様のツールがあります参照フロントエンドのパフォーマンスの最適化およびテストツールまとめ


- 「高性能のJavaScript」およびその他の他のブログからのトランクのこの文書の内容とは、作者が削除侵害してください接触場合は、ソースを示すの
フォローアッププログラムは立証責任の効果によって、より説明し、常にこのドキュメントを改善します

注:内容が不適切または間違っている私を修正してください~~ありがとうソースを明記してください!

おすすめ

転載: www.cnblogs.com/baimeishaoxia/p/11963935.html