web-dev-qa-db-ja.com

インラインJavascriptを延期する方法は?

次のHTMLコードがあります。

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Document</title>
    <script src="https://cdn.jsdelivr.net/blazy/1.8.2/blazy.min.js" defer></script>
    <script src="https://code.jquery.com/jquery-2.1.4.min.js" integrity="sha256-8WqyJLuWKRBVhxXIL1jBDD7SDxU936oZkCnxQbWwJVw=" crossorigin="anonymous" defer></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/lightbox2/2.9.0/js/lightbox.min.js" defer></script>
    <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous" defer></script>
    <!-- 26 dec flexslider js -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/flexslider/2.6.3/jquery.flexslider.min.js" defer></script>
    <script defer>
    (function($) {
        $(document).ready(function() {
            //do something with b-lazy plugin, lightbox plugin and then with flexslider
        });
    })(jQuery);
    </script>
</head>
<body>
</body>
</html>

JQueryが定義されていないというエラーが表示されます。インラインJSコードからdeferを削除しても、jQueryは未定義です。何らかの理由で、jQueryプラグインを頭に入れて、JSコードをインラインにしておく必要があります。私の質問は:

  1. defer属性が存在する場合、インラインJavascriptコードが遅延しないのはなぜですか?

  2. インラインJavascriptコードの遅延動作を模倣する方法はありますか?必要に応じて、bodyタグの最後に配置できます。

39
user31782

defer属性を持つスクリプトは指定された順序でロードされますが、前ではなくドキュメント自体がロードされました。 deferは、script属性も持たない限り、srcタグに影響を与えないため、最初に実行されるスクリプトはインラインスクリプトです。そのため、その時点ではjQueryはまだロードされていません。

これは少なくとも2つの方法で解決できます。

  • インラインスクリプトを.jsファイルに配置し、src属性(既にあるdefer属性に加えて)を使用して参照するか、または

  • ドキュメントと遅延スクリプトがロードされるまで、インラインスクリプトを待機させます。 DOMContentLoadedイベントは、それが発生すると起動します:

    <script>
        window.addEventListener('DOMContentLoaded', function() {
            (function($) {
                //do something with b-lazy plugin, lightbox plugin and then with flexslider
            })(jQuery);
        });
    </script>
    

注意:後者の場合、$(document).ready(function()はもう含まれないことに注意してください。これは同じイベント(DOMContentLoaded)を待つためです。 couldは元のコードと同じようにそれを含めますが、jQueryはコールバックを実行するだけですimmediatelyで、実際の違いはありません。

77
trincot

スクリプトからBase64 URLを作成し、srcに配置できます!

<script src="data:text/javascript;base64,YWxlcnQoJ0hlbGxvIHdvcmxkIScpOw=="
        defer>
</script>

動作を確認する簡単なテストを作成しました。 deferが機能している場合は、Hello world! lastのアラートが表示されます。

<script defer>
  alert('Why no defer?!?');
</script>

<!-- alert('Hello world!'); -->
<script src="data:text/javascript;base64,YWxlcnQoJ0hlbGxvIHdvcmxkIScpOw=="
        defer></script>

<script>
  alert('Buh-bye world!');
</script>

手動で行うのは少し面倒ですので、HTMLを何らかの方法(ハンドルバー、Angularなど)でコンパイルする余裕がある場合は、非常に役立ちます。

私は現在使用しています:

<script src="data:text/javascript;base64,{{base64 "alert('Hello world!');"}}"
        defer>
</script>
36
Brook Jordan

MDNドキュメントから:

遅延
このブール属性は、ドキュメントが解析された後、DOMContentLoadedを起動する前にスクリプトが実行されることをブラウザに示すために設定されます。 defer属性は外部スクリプトでのみ使用する必要があります。

これはIIFE(Immediately Invoked Function Expression)と呼ばれ、DOMが利用可能になる前に実行されます。したがって、その場合、jQueryはDOMにないため未定義です。

5
Jai

プレーンテキストデータURI-ChromeおよびFFでの読み込みを延期する

#noLib #vanillaJS

クロスブラウザPRODuctionで使用しないことを推奨

mS IEが消滅し、MS EdgeがChromiumオープンソースを採用するまで;)

スクリプトを延期する唯一の方法は、external fileまたはData_URI(使用せずにイベントDOMContentLoaded)

延期する

spec script#attr-defer(MDN web docs) :「src属性が存在しない場合(インラインスクリプトの場合)、この場合は使用しないでください。この場合、効果はありません。」

Data_URI

spec Data_URI

正しいtype "text/javascript"を使用する必要はありませんbase64まったく...;)

プレーンテキストを使用するので、シンプルを使用できます:

<script defer src="data:text/javascript,

//do something with b-lazy plugin, lightbox plugin and then with flexslider

lightbox.option({
  resizeDuration: 200,
  wrapAround: true
})

">

はい、それは少し奇妙なハックですが、<script type="module">はデフォルトで延期され、正確な順序でmixする他のオプションはありません

  • モジュール外部ファイル-デフォルトで遅延
  • モジュールのインラインスクリプト-デフォルトで遅延
  • 外部ファイル-オプションで遅延
  • インラインスクリプト-これのみhack-私が知っているように(ライブラリ/フレームワークなし)

遅延/非同期スクリプトタグでは不十分です

<script src=".." async defer>を使用(またはJSから行う場合はsrcを割り当てる前にscript.async = trueを設定)および/またはページの一番下にスクリプトを配置する必要があるという一般的な知識があります。 、可能な限り高速にページがロードされ、ユーザーにレンダリングされるようにします。

defer.js (注:私はこのスクリプトの著者です)プレーンJavaScriptで記述されており、遅延読み込みを他のコンテンツはより高速でパフォーマンスが向上します。インラインスクリプトブロックと同様に、javascriptファイルを効率的に延期できます。

Defer loading of JavaScript

ページがJavaScriptで強化されたHTMLページである場合は、<script async>だけで十分です。ブラウザがこれらのスクリプトを解析して実行するのに時間がかかります。UIを変更するたびにレイアウトがリフローし、ロード速度が遅くなります。ユーザーは短気で、すぐに離れます。

さまざまなケースで、asyncまたはdeferを使用しても、 defer.js よりも速いページ速度は得られません。

1
shinsenter