JavaScriptの最適化


最近、話をする機会がありましたNDC Sydney ウェブパフォーマンスについて、それは大きなフィードバックを受けました.
それは、私が私がその話でカバーした各々の話題に関する一連のポストを書くように促しました、そして、誰が知っていますか😃.
その他の部分
我々の古い友人JavaScriptのために何ができるかを見る時間.では始めましょう.

HTTP / 2に切り替える


より多くのホスティングプロバイダサポートHTTP/2 , その代わりにこのプロトコルに切り替えて、その多重化された性質から利益を得るのに良い時間になっています.それがパフォーマンスに関して意味することは、我々がサーバーへの呼び出しの数を減らすために大規模な束にすべてのJavaScriptを束ねる必要がないということです.
HTTP/2の多くの要求を処理するように設計された場合、ページをレンダリングするために必要なファイル数を増やすことができます.あまり多くない

Too much of a good thing is a bad thing.


非同期と延期


以前にも述べたように、JavaScriptはCSSのようにレンダリングブロック要素です.これは単にブラウザがロードして実行するのを待つ必要があることを意味しますHTML ドキュメント.
これは、我々を大いに増加させますFirst Meaningful Pain . この問題を解決するために、我々は多くの人々によって使用されていないが非常に効果的な機能の2つを使用することができます.

通常実行


を使用するとき<script> JavaScriptファイルを読み込むには、ドキュメントの解析を中断します.ブラウザはリソースを取得し、これを実行し、その後paringを続けます.

async属性


The Async 属性は、このリソースを非同期で実行できることを示すために使用されます.構文解析を停止する必要はありません.リソースがネットワークから取得され、準備ができた直後に行うことができます.
<script async src="script.js">
この属性は外部のJavaScriptファイルでのみ使用できます.ファイルをパラレルでダウンロードし、ダウンロードが完了すると、解析対象のスクリプトが解析されます.

遅延属性


The Defer 属性は、ドキュメントを解析した後にこのスクリプトを実行するようブラウザに指示するために使用されます.
<script defer src="script.js">
ライクAsync このファイルはパラレルでダウンロードされますが、実行はHTML ドキュメントをパースします:

最後にあなたのすべてを置くことを忘れないでくださいscript タグの右側のタグbody 構文解析の遅延を防ぐにはHTML .
ブラウザのサポートについては、幸いにもこれらの属性は完全にすべての主要なものによってサポートされています.

コード分割


最新のサイトのほとんどは、負荷時間の増加と負荷パフォーマンスからの苦しみで結果として、それらのJavaScriptのすべてを束ねるでしょう.
コード分割を使用すると、必要なときにアプリケーションのコードを別々のチャンクに分割し、それらを怠惰な負荷に分割することができます.また、クライアントに最小限の必要なコードを意味し、ページの読み込み時間を向上させます.
コードを3つの領域に分割できます.
  • ベンダーコード
  • エントリーポイント
  • ダイナミックスプリット
  • ベンダーコード


    角度、反応、モーメントなどのベンダーコードは、メインコードから分離できます.Webpack これと他のメソッドの完全なサポートがあります.あなたのアプリケーションまたはベンダーコードが互いに独立して変化するときはいつでも、このテクニックはあなたにあなたのバンドルのキャッシュ失効のより良い支配をすることができます.
    これはすべてのアプリケーションを行う必要があります.

    エントリーポイント


    このテクニックは、アプリケーション内のエントリポイントでコードを分離します.これらのポイントは、WebPackのようなバンドルが、アプリケーションの依存ツリーを構築するときに開始されます.
    これはバーコードを分割する最も簡単な方法ですが、マニュアルであり、いくつかの落とし穴があります.
  • エントリポイントの間に重複したモジュールがあれば、それらは両方ともバンドルされるでしょう.
  • それは柔軟ではなく、動的にあなたのアプリケーションのロジックでコードを分割するために使用することはできません.
  • このテクニックは、クライアント側のルーティングを持っているとき、またはサーバー側のレンダリングと1つのページのアプリのミックスを持っているときに適していません.

    ダイナミックスプリット


    動的に分離コードimport が使用される.これは、単一のページアプリケーションの最適なオプションです.あなたのスパで別のルートの異なるモジュールを持つことは、この例です.

    私も、コード分割が必要ですか?


    これは何度も私の意見を聞くときには😉). あなたのアプリケーションが孤立した機能で多くのルートを持っていて、重くフレームワークとライブラリを使用するならば、この答えはたぶんはいです.
    しかし、それはあなたがあなたのアプリケーションの構造とコードのあなた自身の理解によってそれを必要かどうかを決定することです.

    賢明にインポート


    あなたが使うならばnpm あなたの依存関係のための他のパッケージ管理システム、あなたはあなたのbuidフォルダに余分で不必要なファイルの多くを持っています.
    フレームワークやライブラリを使用する場合は、それらをインポートすることができます別のモジュールを持っているかどうかを調査することを確認し、yesの場合、必要なものだけインポートします.
    例えば、あなたが使用していると仮定しましょうunderscore , ただ使用groupBy , shuffle , and partition . ほとんどの人は以下のようにライブラリ全体をインポートします:
    import * as _ from 'underscore'
    
    代わりに、必要なものをインポートできます.
    import {
      groupBy,
      shuffle,
      partition,
    } from 'underscore'
    
    あなたがあなたの必要性とバンドルがあなたのために残りの世話をするものをもたらすこの方法.あなたの合計パッケージサイズと結果としてあなたのページの読み込み時間が減少します.

    絞りと非難


    を、十分なサイズについては、どこに我々は我々のパフォーマンスを向上させることができます参照してください.
    何度もイベントスクロールを追加する必要があります.それから、我々はリスナーがイベントが引き起こされるたびに、発火することを忘れます.
    window.addEventListener('scroll', function() {
      console.log('page scrolled')
    })
    
    上記の例では、スクロールするたびにメッセージがコンソールに印刷されます.このコールバック関数でいくつかの重い演算があると想像してください.
    あなたがそのイベントリスナーを取り外すことができなくて、異なるアプローチを使うことができないならば、あなたはどちらかを使うことができますdebounce or throttle 状況を緩和する.

    非難する


    それが最後の呼び出しである時から若干の時間が経過するまで、この機能は起こるために機能呼び出しを実施します.たとえば、100ミリ秒が最後の呼び出しから渡された場合、関数を呼び出します.
    アンダースコアからこの実装を見てください.
    const debounce = (func, delay) => {
      let inDebounce
      return function() {
        const context = this
        const args = arguments
        clearTimeout(inDebounce)
        inDebounce = setTimeout(
          () => func.apply(context, args),
          delay
        )
      }
    }
    
    今、我々は100ミリ秒ごとに我々のイベントリスナーを討議することができます
    var efficientScrollListener = debounce(
      function() {
        console.log('page scrolled')
      },
      100
    )
    
    window.addEventListener(
      'scroll',
      efficientScrollListener
    )
    

    スロットル


    関数は、時間の経過とともに関数を呼び出すことができる最大回数を強制するので、議論に似ています.たとえば、100ミリ秒ごとにこの関数を実行します.
    以下に簡単な実装を示します:
    const throttle = (func, limit) => {
      let inThrottle
      return function() {
        const args = arguments
        const context = this
        if (!inThrottle) {
          func.apply(context, args)
          inThrottle = true
          setTimeout(
            () => (inThrottle = false),
            limit
          )
        }
      }
    }
    
    これで、スクロールイベントリスナーを停止できます.
    var efficientScrollListener = throttle(
      function() {
        console.log('page scrolled')
      },
      100
    )
    
    window.addEventListener(
      'scroll',
      efficientScrollListener
    )
    

    それで


    JavaScriptを使用しているときに、アプリケーションのパフォーマンスを向上させるために焦点を当てることができるいくつかの領域についての十分な情報をあなたに与えてください.あなたが他の話題をカバーしたいならば、下でコメントしてください、そして、私はここまたは他のポストで彼らを加えます.
    そしていつものように❤️.