[英]Async Loading of non-critical assets (Javascript, CSS)
我們的布局或頁眉/頁腳可以包含此代碼,該代碼可加載指定的資源並在完成后觸發事件。
<body>
...
<script>
// Callback after window is loaded
if (window.addEventListener) {
window.addEventListener("load", downloadFilesAtOnload, false);
} else if (window.attachEvent) {
window.attachEvent("onload", downloadFilesAtOnload);
} else {
window.onload = downloadFilesAtOnload;
}
function downloadFilesAtOnload() {
// List of Javascript files to be loaded
var jsFiles = ["js/library1.min.js", "js/library2.min.js", "CDN.library3.min.js"];
loadScriptArray(jsFiles, function() {
triggerEvent(document, 'scripts_loaded');
});
// List of CSS files to be loaded
var robotoFonts = "https://fonts.googleapis.com/css?family=Roboto:400,300,300italic,400italic,500,500italic,700";
var cssFiles = ["css/cssfile1.min.css", "css/cssfile2.min.css", robotoFonts];
for (var i = 0; i < cssFiles.length; i++) {
var l = document.createElement('link');
l.rel = 'stylesheet';
l.href = cssFiles[i];
var h = document.getElementsByTagName('head')[0];
h.parentNode.insertBefore(l, h);
}
}
function loadScriptArray(contentArray, contentLoadedCallback){
var contentQuantity = contentArray.length; //Number of Files that needs to be loaded
var contentCompleted = 0; //Number of Files, that have already been loaded
for (var i = 0; i < contentQuantity; i++) {
loadScript(contentArray[i], function(success, path){ //This anonymous function is called everytime a script is finished
//The only way to know which script finished, is to pass the path as an parameter
contentCompleted++;
if (contentCompleted == contentQuantity){ //this was the last file
if (typeof contentLoadedCallback == 'function'){
contentLoadedCallback();
}
}
});
}
}
function loadScript(path, scriptLoadedCallback){
element = document.createElement("script");
element.src = path;
element.async = false;
if (typeof(scriptLoadedCallback) == 'function') { //makes the callback-function optional
element.onload = function() {
return scriptLoadedCallback(true, path); //true = successfull; the path is needed later
};
element.onerror = function() { //you might also call the cb on error
this.parentNode.removeChild(this); //remove faulty node from DOM
return scriptLoadedCallback(false, path); //false = error; the path is needed later
};
}
document.body.appendChild(element); //insert the node in DOM (end of <head>), and load the script
}
function processEvent(el, eventName, handler) {
if (el.addEventListener) {
el.addEventListener(eventName, handler);
} else if (el.attachEvent) {
el.attachEvent('on' + eventName, function() {
handler.call(el);
});
}
}
function triggerEvent(el, eventName) {
var event;
if (window.CustomEvent) {
event = new CustomEvent(eventName);
} else {
event = document.createEvent('CustomEvent');
event.initCustomEvent(eventName);
}
el.dispatchEvent(event);
}
</script>
</body>
然后,我們可以使用依賴於此類任何頁面中的外部文件/庫的javascript代碼:
<script>
processEvent(document, 'scripts_loaded', function(e) {
// Code here
});
</script>
這是使用Javascript Promises的更好的解決方案
您的布局或頁眉/頁腳文件可以包含此代碼。
// Load css files
var cssFiles = [{
type: "CDN",
src: "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css",
integrity: "sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u",
}, {
type: "local",
src: "css/cssfile1.min.css"
}, {
type: "local",
src: "css/cssfile2.min.css"
}, {
type: "local",
src: "https://fonts.googleapis.com/css?family=Roboto:400,300,300italic,400italic,500,500italic,700"
}];
var loadcssFiles = function() {
cssFiles.forEach(function(file) {
var style = document.createElement('link');
style.rel = 'stylesheet';
style.href = file.src;
if (file.type == 'CDN') {
style.integrity = file.integrity;
style.crossOrigin = "anonymous";
}
document.head.appendChild(style);
});
}
var raf = requestAnimationFrame || mozRequestAnimationFrame || webkitRequestAnimationFrame || msRequestAnimationFrame;
if (raf) {
raf(loadcssFiles);
} else {
window.addEventListener('load', loadcssFiles);
}
// Load Javascript files
var jsFiles = [{
index: 1,
type: "CDN",
src: "https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/js/bootstrap.min.js",
integrity: "sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa",
}, {
index: 2,
type: "local",
src: "js/library1.min.js"
}, {
index: 3,
type: "local",
src: "js/library2.min.js"
}];
var loadjsFiles = new Promise(function(resolve, reject) {
var failed;
jsFiles.forEach(function(file) {
var script = document.createElement('script');
script.src = file.src;
script.onerror = function() {
failed = true;
reject(this);
}
script.async = false;
if (file.type == 'CDN') {
script.integrity = file.integrity;
script.crossOrigin = "anonymous";
}
document.head.appendChild(script);
script.onload = script.onreadystatechange = function() {
if (!failed && (!this.readyState || this.readyState == "complete") && file.index == jsFiles.length ) {
resolve(this);
}
}
});
});
然后,我們可以使用依賴於此類任何頁面中的外部文件/庫的javascript代碼:
loadjsFiles.then(function() {
// Code here
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.