I know the original poster will have long since moved on from this 10yr-old question. But I hope this answer may help someone.
First off, good async programming and the use of window.onload are probably a big part of the solution. Individual implementations will vary.
Another problem that we're trying to overcome here, I think, is that too much work is being done in the main thread on the client. Other than writing more efficient code, there's no trick I can think of to get around that problem. The only solution is to not do that work on the main thread. One option is to do more work on the server.
Another option is to use a web worker to put that work in a background thread. You can't directly update the DOM from the worker thread, but you can still do most of the prep work.
If you've never used web workers before, don't be intimidated; they're pretty quick to implement, assuming you know JavaScript. All you really need to get started are new Worker()
to start a background thread, postMessage()
to send data from the main thread to the worker thread (or vice versa) and the onmessage
event handler for receiving the data (in either direction).
It's like a pure function that runs without blocking the DOM, and calls you back with data when it's done.
Here's an example implementation in which there's an initial page render of black text. Meanwhile, the web worker decides blue is better, thinking about it for 2 long, hard seconds, then reporting the result back to the main thread. The main thread then updates the DOM in response.
<body>
<div id="cool-div"></div>
<script>
let myData = [
"This is my sample data that I want to do a bunch of work to, such as parsing it and returning new html to render.",
];
document.getElementById(
"cool-div"
).innerHTML = `<p style="color:black">${myData}</p>`;
const myWorker = new Worker("worker.js");
myWorker.onmessage = (event) =>
(document.getElementById("cool-div").innerHTML = event.data);
myWorker.postMessage(myData);
</script>
</body>
Then in worker.js:
onmessage = (e) => {
const newData = `<p style="color:blue">${e.data}</div>`;
//pretend to do hard work, then pass the result back to main thread
setTimeout(() => postMessage(newData), 2000);
};