jQueryの負荷を延期することは可能ですか?
-
27-10-2019 - |
質問
それに直面してみましょう、jquery/jquery-uiは重いダウンロードです。
Googleがお勧めします JavaScriptの繰延荷重 初期レンダリングをスピードアップします。私のページでは、jQueryを使用して、ページに低く配置されたタブを設定します(ほとんどが最初のビューから外れています)、ページがレンダリングされるまでjQueryを延期したいと思います。
Googleの延期コードは、ボディオンロードイベントに引っ込んでページが読み込まれた後、DOMにタグを追加します。
<script type="text/javascript">
// Add a script element as a child of the body
function downloadJSAtOnload() {
var element = document.createElement("script");
element.src = "deferredfunctions.js";
document.body.appendChild(element);
}
// Check for browser support of event handling capability
if (window.addEventListener)
window.addEventListener("load", downloadJSAtOnload, false);
else if (window.attachEvent)
window.attachEvent("onload", downloadJSAtOnload);
else window.onload = downloadJSAtOnload;
</script>
このようにjQueryのロードを延期したいのですが、試してみたとき、私のjQueryコードはjQueryを見つけられませんでした(私の側では完全に予想外ではありません):
$(document).ready(function() {
$("#tabs").tabs();
});
したがって、jQueryがロードされるまで、jQueryコードの実行を延期する方法を見つける必要があるようです。追加されたタグが読み込みと解析が終了したことを検出するにはどうすればよいですか?
結果として、それはそうです 非同期負荷 答えも含まれている場合があります。
何かご意見は?
解決
これを試してみてください。これは、Jquerifyブックマークレットから少し前に編集したものです。頻繁に使用して、jqueryをロードしてロードした後に実行します。もちろん、カスタマイズされたjQueryにURLを独自のURLに置き換えることができます。
(function() {
function getScript(url,success){
var script=document.createElement('script');
script.src=url;
var head=document.getElementsByTagName('head')[0],
done=false;
script.onload=script.onreadystatechange = function(){
if ( !done && (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete') ) {
done=true;
success();
script.onload = script.onreadystatechange = null;
head.removeChild(script);
}
};
head.appendChild(script);
}
getScript('http://ajax.googleapis.com/ajax/libs/jquery/1.5.2/jquery.min.js',function(){
// YOUR CODE GOES HERE AND IS EXECUTED AFTER JQUERY LOADS
});
})();
私は本当にjqueryとjquery-uiを1つのファイルに組み合わせて、URLを使用します。本当に個別にロードしたい場合は、getScriptsをチェーンするだけです。
getScript('http://myurltojquery.js',function(){
getScript('http://myurltojqueryUI.js',function(){
//your tab code here
})
});
他のヒント
これは重要な主題に関するトップランキングの質問であるため、@valmarvと@Amparsandからの以前の答えに基づいて、これを自分の見解を提供してくれます。
スクリプトをロードするために多次元配列を使用しています。それらの間に依存関係がないものをグループ化する:
var dfLoadStatus = 0;
var dfLoadFiles = [
["http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"],
["http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.11/jquery-ui.min.js",
"/js/somespecial.js",
"/js/feedback-widget.js#2312195",
"/js/nohover.js"]
];
function downloadJSAtOnload() {
if (!dfLoadFiles.length) return;
var dfGroup = dfLoadFiles.shift();
dfLoadStatus = 0;
for(var i = 0; i<dfGroup.length; i++) {
dfLoadStatus++;
var element = document.createElement('script');
element.src = dfGroup[i];
element.onload = element.onreadystatechange = function() {
if ( ! this.readyState ||
this.readyState == 'complete') {
dfLoadStatus--;
if (dfLoadStatus==0) downloadJSAtOnload();
}
};
document.body.appendChild(element);
}
}
if (window.addEventListener)
window.addEventListener("load", downloadJSAtOnload, false);
else if (window.attachEvent)
window.attachEvent("onload", downloadJSAtOnload);
else window.onload = downloadJSAtOnload;
ロードされた後、最初のjQueryをロードします。他のスクリプトを一度にロードし続けます。ページのどこにでも配列に追加することで、スクリプトを簡単に追加できます。
dfLoadFiles.push(["/js/loadbeforeA.js"]);
dfLoadFiles.push(["/js/javascriptA.js", "/js/javascriptB.js"]);
dfLoadFiles.push(["/js/loadafterB.js"]);
これが良い説明です Async/Defer JavaScriptロードのための最新のアプローチ. 。ただし、インラインスクリプトでは機能しません
<script type="text/javascript" src="/jquery/3.1.1-1/jquery.min.js" defer></script>
<script type="text/javascript" defer>
$(function () { // <- jquery is not yet initialized
...
});
</script>
@nilskp-外部化スクリプトによって提案された非同期荷重の最も単純なソリューションが提案されました。
<script type="text/javascript" src="/jquery/3.1.1-1/jquery.min.js" defer></script>
<script type="text/javascript" src="resources/js/onload.js" defer></script>
htmlファイルの最後にjqueryとjquery依存コードを置きます。
編集:もう少し明確です
<html>
<head></head>
<body>
<!-- Your normal content here -->
<script type="text/javascript" src="http://path/to/jquery/jquery.min.js"></script>
<script>//Put your jQuery code here</script>
</body>
</html>
element.addEventListener("load", function () {
$('#tabs').tabs()
}, false);
それを試してみてください。
特定の状況では、jQueryがロードされたときにイベントを発射できます。
<script type="text/javascript">
(function (window) {
window.jQueryHasLoaded = false;
document.body.addEventListener('jqueryloaded', function (e) {
console.log('jqueryloaded ' + new Date() );
}, false);
function appendScript(script) {
var tagS = document.createElement("script"),
s = document.getElementsByTagName("script")[0];
tagS.src = script.src;
s.parentNode.insertBefore(tagS, s);
if ( script.id == 'jquery' ) {
tagS.addEventListener('load', function (e) {
window.jQueryHasLoaded = true;
var jQueryLoaded = new Event('jqueryloaded');
document.body.dispatchEvent(jQueryLoaded);
}, false);
}
}
var scripts = [
{
'id': 'jquery',
'src': 'js/libs/jquery/jquery-2.0.3.min.js'
},
{
'src': 'js/myscript1.js'
},
{
'src': 'js/myscript2.js'
}
];
for (var i=0; i < scripts.length; i++) {
appendScript(scripts[i]);
}
}(window));
</script>
次に、依存関係を関数に包みます。
// myscript1.js
(function(){
function initMyjQueryDependency() {
console.log('my code is executed after jquery is loaded!');
// here my code that depends on jquery
}
if ( jQueryHasLoaded === true )
initMyjQueryDependency();
else
document.body.addEventListener('jqueryloaded', initMyjQueryDependency, false);
}());
jQueryが他のスクリプトの後にロードして終了した場合、jQueryloadedイベントが起動されると依存関係が実行されます。
jqueryがすでにロードされている場合、 jQueryHasLoaded === true
, 、依存関係が実行されます initMyjQueryDependency()
.
Async/Defered JQueryスクリプトタグの後にこのコードを追加します。これは、すべてが終了したときに実行する必要があるものを蓄積する一時的な関数$を定義します。関数を実行するために上書きされます。このコードを使用すると、ドキュメントのjQueryオンロード構文をさらに下に変更する必要はありません。
<script defer async src="https://code.jquery.com/jquery-2.2.0.min.js">
<script>
var executeLater = [];
function $(func) {
executeLater.push(func);
}
window.addEventListener('load', function () {
$(function () {
for (var c = 0; c < executeLater.length; c++) {
executeLater[c]();
}
});
})
</script>
....その後...
<script>
$(function() {
alert("loaded");
});
</script>
まあ、それは私には、あなたがしなければならないのは、a)ロードで実行するjQueryコードを追加するか、jqueryファイルの最後に追加するか、b) downloadJSAtOnload
SOのように機能:
<script type="text/javascript">
// Add a script element as a child of the body
function downloadJSAtOnload() {
var element = document.createElement("script");
element.src = "deferredfunctions.js";
document.body.appendChild(element);
$("#tabs").tabs(); // <==== NOTE THIS. This should theoretically run after the
// script has been appended, though you'll have to test this
// because I don't know if the JavaScript above will wait for
// the script to load before continuing
}
// Check for browser support of event handling capability
if (window.addEventListener)
window.addEventListener("load", downloadJSAtOnload, false);
else if (window.attachEvent)
window.attachEvent("onload", downloadJSAtOnload);
else window.onload = downloadJSAtOnload;
</script>
次のコードは、ウィンドウの読み込みが終了した後、スクリプトをロードする必要があります。
<html>
<head>
<script>
var jQueryLoaded = false;
function test() {
var myScript = document.createElement('script');
myScript.type = 'text/javascript';
myScript.async = true;
myScript.src = jQueryLoaded ? 'http://ajax.googleapis.com/ajax/libs/jquery/1.5.1/jquery.js' : 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.11/jquery-ui.min.js';
document.body.appendChild(myScript);
if(!jQueryLoaded){
alert('jquery was loaded');
jQueryLoaded = true;
test();
} else {
alert('jqueryui was loaded');
}
}
if (window.addEventListener){
alert('window.addEventListener');
window.addEventListener("load", test, false);
} else if (window.attachEvent){
alert('window.attachEvent');
window.attachEvent("onload", test);
} else{
alert('window.onload');
window.onload = test;
}
</script>
</head>
<body>
<p>Placeholder text goes here</p>
</body>
</html>
Chrome、FF、IE9で私のために働いた - それが役立つかどうか教えてください
次に、スクリプトが次々とロードされていることを確認するためにチェーンをサポートする私のバージョンです。 アンパサンド'のコード:
var deferredJSFiles = ['jquery/jquery', 'file1', 'file2', 'file3'];
function downloadJSAtOnload() {
if (!deferredJSFiles.length)
return;
var deferredJSFile = deferredJSFiles.shift();
var element = document.createElement('script');
element.src = deferredJSFile.indexOf('http') == 0 ? deferredJSFile : '/js/' + deferredJSFile + '.js';
element.onload = element.onreadystatechange = function() {
if (!this.readyState || this.readyState == 'loaded' || this.readyState == 'complete')
downloadJSAtOnload();
};
document.body.appendChild(element);
}
if (window.addEventListener)
window.addEventListener('load', downloadJSAtOnload, false);
else if (window.attachEvent)
window.attachEvent('onload', downloadJSAtOnload);
else
window.onload = downloadJSAtOnload;
<!doctype html>
<html>
<head>
</head>
<body>
<p>If you click on the "Hide" button, I will disappear.</p>
<button id="hide" >Hide</button>
<button id="show" >Show</button>
<script type="text/javascript">
function loadScript(url, callback) {
var script = document.createElement("script")
script.type = "text/javascript";
if (script.readyState) { //IE
script.onreadystatechange = function() {
if (script.readyState == "loaded" ||
script.readyState == "complete") {
script.onreadystatechange = null;
callback();
}
};
} else { //Others
script.onload = function() {
callback();
};
}
script.src = url;
document.body.appendChild(script);
}
loadScript("http://ajax.googleapis.com/ajax/libs/jquery/1.10.2/jquery.min.js",
function() {
//YAHOO.namespace("mystuff");
$("#show").click(function() {
$("p").show();
});
$("#hide").click(function() {
$("p").hide();
});
//more...
});
</script>
</body>
</html>
Modernizr.load()はここで言及する価値があると思います - それは依存関係の負荷を非常にうまく処理します
必要なように見えます <script defer>
: http://www.w3schools.com/tags/att_script_defer.asp
見てください jQuery.holdReady()
「JQueryのReady Eventの実行を保持またはリリースします。」 (jquery1.6+)
HTMLの最後にすべてのスクリプトをロードします http://labjs.com, 、それは100%の解決策であり、GTMetrixルールに対して何度もテストしました。例 http://gtmetrix.com/reports/interactio.cz/jxomhslv