source

인라인 자바스크립트 연기하는 방법?

manysource 2023. 11. 1. 22:27

인라인 자바스크립트 연기하는 방법?

저는 다음과 같은 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 코드에서 지연을 제거해도 jQuery가 정의되지 않았다고 표시됩니다.어떤 이유에서인지 저는 jQuery 플러그인을 머리에 꽂고 JS 코드를 인라인으로 유지해야 합니다.제 질문은 다음과 같습니다.

  1. 왜 인라인 자바스크립트 코드가 지연되지 않습니까?defer속성이 거기에 있습니까?

  2. 내 인라인 자바스크립트 코드에서 deefer 동작을 모방할 수 있는 방법이 있습니까?필요하다면 바디 태그 끝에 넣을 수 있습니다.

다음과 같은 스크립트.defer지정된 순서에 따라 속성 로드가 발생하지만 문서 자체가 로드되기 전에는 발생할 수 없습니다.defer에 영향을 미치지 않는script태그들은 또한 그들이 또한 가지고 있지 않는 한.src속성, 가장 먼저 실행되는 스크립트는 인라인 스크립트입니다.그래서 그 때 jQuery는 아직 로딩되지 않았습니다.

이 문제는 적어도 두 가지 방법으로 해결할 수 있습니다.

  • 인라인 스크립트를 에 넣습니다..js파일을 작성하고 a와 함께 참조합니다.src특성(추가)defer이미 가지고 있던 속성) 또는

  • 인라인 스크립트가 문서와 지연된 스크립트가 로드될 때까지 기다리십시오.DOMContentLoaded발생 시 이벤트가 발생합니다.

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

NB: 후자의 경우 주의하십시오.$(document).ready(function()더 이상 포함되지 않습니다. 그러면 동일한 이벤트가 발생할 것이기 때문입니다(DOMContentLoaded). 원래 코드에 있던 것처럼 포함할 수 있지만 jQuery는 콜백을 즉시 실행하므로 실질적인 차이가 없습니다.

스크립트에서 Base64 URL을 생성하여 src에 입력할 수 있습니다!

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

나는 그것을 실제적으로 보기 위해 빠른 테스트를 만들었습니다.다음과 같은 알림이 표시됩니다.Hello world!마지막으로defer작동 중:

<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을 어떤 식으로든 컴파일할 수 있는 여유가 있다면(핸들바, 앵글 등) 많은 도움이 됩니다.

현재 사용 중인 항목:

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

사용할 수도 있습니다.type="module":

<meta charset="utf-8">

<script type="module">
let t = document.getElementById('top');
console.log(t);
</script>

<h1 id="top">Top Questions</h1>

https://developer.mozilla.org/docs/Web/HTML/Element/script#attr-type

MDN 문서에서:

미루다
이 부울 특성은 문서가 구문 분석된 후 실행되기 전에 스크립트가 실행되도록 브라우저에 지시하도록 설정됩니다.DOMContentLoaded. 지연 특성은 외부 스크립트에서만 사용해야 합니다.

이를 IIFE(Imediate Invocated Function Expression)라고 하며, DOM을 사용할 수 있기 전에 실행됩니다.그래서, 그 경우에는jQueryDOM에 없기 때문에 정의되지 않습니다.

일반 텍스트로 로딩 연기Data URI - Chrome and FF

#noLib #vanillaJS

Cross Browser PRODUCT에서 사용하지 말 것을 제안합니다.

MSIE가 죽고 MS Edge가 Chrome 오픈 소스를 채택할 때까지 ;)

스크립트를 지연할 수 있는 유일한 방법은 외부 파일 또는 Data_URI입니다(이벤트 DOM ContentLoaded를 사용하지 않음).

미루다

사양 스크립트#attr-dfer(MDN문서):"이 특성은 src 특성이 없는 경우(즉, 인라인 스크립트의 경우)에는 사용되지 않아야 하며, 이 경우에는 영향을 미치지 않습니다.)"

데이터_URI

사양 데이터_URI

올바른 타입의 "text/javscript"에서는 64를 베이스로 할 필요가 전혀 없습니다.. ;)

간단한 텍스트를 사용하여 다음을 사용할 수 있습니다.

<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">기본적으로 다음을 정확한 순서로 혼합할 수 있는 다른 옵션은 없습니다.

  • 모듈 외부 파일 - 기본적으로 지연됨
  • 모듈 인라인 스크립트 - 기본적으로 지연됨
  • 외부 파일 - 선택적으로 연기됨
  • 인라인 스크립트 - 이 해킹에서만 - 제가 알고 있는 (라이브러리/프레임워크 없이)

연기/비동기 스크립트 태그가 충분하지 않습니다.

사용해야 할 공통 지식이 있습니다.<script src=".." async defer>(또는 세트script.async = true할당하기 전에src, JS)에서 작업을 수행할 때 및/또는 페이지 맨 아래에 스크립트를 배치하여 페이지가 최대한 빨리 로드되고 사용자에게 렌더링되도록 합니다.

deeper.js(참고: 는 이 스크립트의 작성자입니다)는 일반 자바스크립트로 작성되어 다른 콘텐츠를 더 빠르고 성능적으로 로딩합니다.인라인 스크립트 블록뿐만 아니라 모든 자바스크립트 파일을 효율적으로 연기할 수 있습니다.

Defer loading of JavaScript

만약 당신의 페이지가 단지 일부 자바스크립트로 향상된 HTML 페이지라면, 당신은 단지 그것만으로 좋습니다.<script async>. 브라우저가 스크립트를 구문 분석하고 실행하는 데 시간이 걸리고, 각 UI 변경 시 레이아웃이 다시 흘러 로드 속도가 더 느려질 수 있으며, 아무도 빈 흰 페이지를 쳐다보는 것을 좋아하지 않으며, 사용자는 참을성이 없어 빨리 떠날 것입니다.

다양한 경우 사용하기async아니면deferdeefer.js보다 빠른 페이지 속도를 제공하지 않습니다.

제안된 솔루션을 모두 확인했지만 모두 단점이 있습니다.그래서 제가 직접 발명했습니다.

이 인라인 스크립트를 머리 태그에 넣거나 본문 태그 시작 직후에 입력합니다.

<script>var Defer = []; document.addEventListener('DOMContentLoaded', function() { while (Defer.length) Defer.shift().call(); }); </script>

이 하나의 라이너는 문서가 완전히 로드되는 즉시 연기할 모든 인라인 스크립트를 수집하고 각각 실행합니다.이제 지연된 인라인 스크립트를 실행해야 할 때는 언제든지 다음과 같이 등록하십시오.

<script>
  alert('This alert will show immediately.');

  Defer.push(function() {
   alert('This alert will show only after document is loaded.');
   // You can use anything which is not loaded yet, like jQuery
   $(".selector").doSomeJqueryStuff();
  });

  // You can use it as many times as you like and in any place of your DOM.
  Defer.push(function() {
    // Any inline code you want to defer
  });
</script>

이 인라인 스크립트는 문서가 로드된 후에만 실행됩니다.즉, 인라인 jQuery 스크립트를 실행하여 jQuery를 DOM 끝에 유지할 수 있습니다.

이 데이터 URL을 src 속성으로 사용할 수 있습니다.

data:application/javascript,eval(document.currentScript.textContent)

현재 스크립트 태그를 사용하여 외부 파일 안에 있는 것처럼 내용을 평가합니다.그것은 게으른 속성에도 작용합니다.IE 브라우저에서 지원하지 않는 document.currentScript를 사용합니다.

<script defer src="https://cdn.jsdelivr.net/npm/vue"></script>
<script defer src="data:application/javascript,eval(document.currentScript.textContent)">
    console.log('defered', typeof Vue); // function
</script>
<script>
    console.log('not defered', typeof Vue); // undefined
</script>

콜백, 약속 또는 데이터 URL을 필요로 하지 않는 지연을 달성하는 데 다소 덜 모호한 방법이 있습니다.배경에서 약간의 DOM 조작을 하기는 하지만요.작은 라이브러리(109바이트 압축/gzip) https://www.npmjs.com/package/deferscript 이렇게 해보세요.아래 예시는 원래 게시물을 기반으로 한 것입니다.

<script src="https://cdnjs.cloudflare.com/ajax/libs/flexslider/2.6.3/jquery.flexslider.min.js" defer>
</script>
<script src="./deferscript.js" defer>
    (function($) {
        $(document).ready(function() {
            //do something with b-lazy plugin, lightbox plugin and then with flexslider
        });
    })(jQuery);
</script>

당신이 해야 할 일은 단지 a를 삽입하는 것입니다.src값을 가진 속성./deferscript.js.

jQuery 변수 $가 정의되지 않은 것이 문제라면 DOM ContentLoaded를 기다리는 준비된 함수를 반환하는 가짜 $ 함수를 만들 수도 있습니까?

모든 인라인 스크립트에 $(문서)가 있습니다.ready(.....) 그리고 문제는 헤더 스크립트가 지연됨에 따라 $가 정의되지 않는다는 것입니다.

따라서 인라인 스크립트에 가짜 $를 추가하면 됩니다.

<script type="text/javascript">
var $ = function(element) {
    return {
        ready: function(callback) {
            // in case the document is already rendered
            if (document.readyState!="loading") callback();
            // modern browsers
            else if (document.addEventListener) 
                document.addEventListener("DOMContentLoaded", callback);
            // IE <= 8
            else document.attachEvent("onreadystatechange", function(){    
                if (document.readyState=="complete") callback();
            });
        }
    };
};
</script>

언급URL : https://stackoverflow.com/questions/41394983/how-to-defer-inline-javascript