Sunday, May 19, 2024
 Popular · Latest · Hot · Upcoming
119
rated 0 times [  123] [ 4]  / answers: 1 / hits: 54294  / 10 Years ago, sun, november 16, 2014, 12:00:00

I have an html page with some pre-rendered content and some yet un-rendered content. I want to display the pre-rendered content immediately, and then begin rendering the rest of the content. I am not using jQuery.



See the following snippet. I have tried this various ways, including injecting my script before the closing body tag and providing my script to populate the DOM as a callback to window.onload, document.body.onload, and document.addEventListener('DOMContentLoaded'). In every case, the page does not display the pre-rendered content until the rest of the content is rendered.





<html><head></head>
<body>
<header>What it is, my doge?</header>
<div id=main></div>
<script>
var main = document.getElementById('main');
for (var i = 0; i < 500; i++)
main.innerText += new Date();
</script>
</body>
</html>







<html><head></head>
<body>
<header>What it is, my doge?</header>
<div id=main></div>
<script>
var main = document.getElementById('main');
document.body.onload = function() {
for (var i = 0; i < 500; i++)
main.innerText += new Date();
};
</script>
</body>
</html>







<html><head></head>
<body>
<header>What it is, my doge?</header>
<div id=main></div>
<script>
var main = document.getElementById('main');
window.onload = function() {
for (var i = 0; i < 500; i++)
main.innerText += new Date();
};
</script>
</body>
</html>







<html><head></head>
<body>
<header>What it is, my doge?</header>
<div id=main></div>
<script>
var main = document.getElementById('main');
document.addEventListener('DOMContentLoaded', function() {
for (var i = 0; i < 500; i++)
main.innerText += new Date();
});
</script>
</body>
</html>





One case that has worked is window.setTimeout with 0 timeout. However, this simply defers the function until there is nothing left to do. Is this the best practice, here?





<html><head></head>
<body>
<header>What it is, my doge?</header>
<div id=main></div>
<script>
var main = document.getElementById('main');
window.setTimeout(function() {
for (var i = 0; i < 500; i++)
main.innerText += new Date();
}, 0);
</script>
</body>
</html>




More From » html

 Answers
10

In terms of a best practice, there isn't one. In terms of a good, common, and acceptable practices, there are a handful. You've hit one:



setTimeout(function() { }, 1);


In this case, the function is executed within the browser's minimum timeout period after all other in-line processing ends.



Similarly, if you want to ensure your function runs shortly after some condition is true, use an interval:



var readyCheck = setInterval(function() {
if (readyCondition) {
/* do stuff */
clearInterval(readyCheck);
}
}, 1);


I've been using a similar, but more generalized solution in my own work. I define a helper function in the header:



var upon = function(test, fn) {
if (typeof(test) == 'function' && test()) {
fn();
} else if (typeof(test) == 'string' && window[test]) {
fn();
} else {
setTimeout(function() { upon(test, fn); }, 50);
}
}; // upon()


... and I trigger other functionality when dependencies are resolved:



upon(function() { return MyNS.Thingy; }, function() {
// stuff that depends on MyNS.Thingy
});

upon(function() { return document.readyState == 'complete';}, function() {
// stuff that depends on a fully rendered document
});


Or, if you want a more authoritative good practice, follow Google's example. Create an external async script and inject it before your first header script:



var s = document.createElement('script'); s.type = 'text/javascript'; s.async = true;
s.src = '/path/to/script.js';
var header_scripts = document.getElementsByTagName('script')[0];
header_scripts.parentNode.insertBefore(s, header_scripts);


Google's solution theoretically works on all browsers (IE < 10?) to get an external script executing as soon as possible without interfering with document loading.



If you want an authoritative common practice, check the source for jQuery's onready solution.


[#68793] Thursday, November 13, 2014, 10 Years  [reply] [flag answer]
Only authorized users can answer the question. Please sign in first, or register a free account.
albert

Total Points: 652
Total Questions: 105
Total Answers: 108

Location: Pitcairn Islands
Member since Fri, Oct 15, 2021
3 Years ago
;