인라인 자바스크립트 연기하는 방법?
저는 다음과 같은 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 코드를 인라인으로 유지해야 합니다.제 질문은 다음과 같습니다.
왜 인라인 자바스크립트 코드가 지연되지 않습니까?
defer
속성이 거기에 있습니까?내 인라인 자바스크립트 코드에서 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을 사용할 수 있기 전에 실행됩니다.그래서, 그 경우에는jQuery
DOM에 없기 때문에 정의되지 않습니다.
일반 텍스트로 로딩 연기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(참고: 나는 이 스크립트의 작성자입니다)는 일반 자바스크립트로 작성되어 다른 콘텐츠를 더 빠르고 성능적으로 로딩합니다.인라인 스크립트 블록뿐만 아니라 모든 자바스크립트 파일을 효율적으로 연기할 수 있습니다.
만약 당신의 페이지가 단지 일부 자바스크립트로 향상된 HTML 페이지라면, 당신은 단지 그것만으로 좋습니다.<script async>
. 브라우저가 스크립트를 구문 분석하고 실행하는 데 시간이 걸리고, 각 UI 변경 시 레이아웃이 다시 흘러 로드 속도가 더 느려질 수 있으며, 아무도 빈 흰 페이지를 쳐다보는 것을 좋아하지 않으며, 사용자는 참을성이 없어 빨리 떠날 것입니다.
다양한 경우 사용하기async
아니면defer
deefer.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
'source' 카테고리의 다른 글
html 페이지의 div에 외부 웹페이지를 로드하는 방법 (0) | 2023.11.06 |
---|---|
ORA-32795: 생성된 always identity 열에 삽입할 수 없습니다. (0) | 2023.11.01 |
자바스크립트에서 배열을 선언할 때 지켜야 할 가장 좋은 방법은 무엇입니까? (0) | 2023.11.01 |
C의 포인터 크기 가져오기 (0) | 2023.11.01 |
2-D 배열 앨리어싱 시 예기치 않은 스트렐렌 최적화 (0) | 2023.11.01 |