Page Lifecycle Events

What They Actually Do:

These events tell you when different parts of the page are ready - like checkpoints in a loading race.

The Loading Timeline:

javascript

// 1. DOMContentLoaded - HTML parsed, DOM ready
document.addEventListener('DOMContentLoaded', () => {
    // DOM elements exist, but images might still be loading
    console.log('DOM ready!');
});
 
// 2. load - Everything loaded (images, styles, etc.)
window.onload = () => {
    // Page completely ready
    console.log('Everything loaded!');
};
 
// 3. beforeunload - User trying to leave
window.onbeforeunload = () => {
    return 'Sure you want to leave?'; // Shows browser dialog
};
 
// 4. unload - User actually leaving
window.onunload = () => {
    // Send analytics, cleanup
    navigator.sendBeacon('/analytics', data);
};

Interview Gotchas:

Gotcha #1: Scripts block DOMContentLoaded

javascript

// This script will delay DOMContentLoaded
<script src="big-library.js"></script> // Blocks everything
 
// These DON'T block:
<script async src="analytics.js"></script>
<script defer src="app.js"></script>

Gotcha #2: Styles before scripts matter

javascript

<link rel="stylesheet" href="styles.css">
<script>
    // This script waits for CSS to load first!
    alert(getComputedStyle(document.body).color);
</script>

Gotcha #3: document.readyState check

javascript

// Safe way to handle already-loaded DOM
if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', init);
} else {
    init(); // DOM already ready
}

Script Loading: async vs defer

What They Actually Do:

Control when scripts download and execute without blocking the page.

Normal Script (blocks everything):

html

<!-- Page stops, downloads script, executes, then continues -->
<script src="app.js"></script>

defer - Downloads parallel, executes after DOM:

html

<!-- Downloads in background, waits for DOM, executes in order -->
<script defer src="library.js"></script>
<script defer src="app.js"></script> <!-- Waits for library.js -->

async - Downloads parallel, executes immediately when ready:

html

<!-- Downloads in background, executes whenever ready -->
<script async src="analytics.js"></script>
<script async src="ads.js"></script> <!-- Race condition! -->

Quick Decision Guide:

Use CaseSolution
Script needs DOM elementsdefer
Script is independent (analytics, ads)async
Scripts must run in specific orderdefer
Script doesn’t need anythingasync

Interview Gotchas:

Gotcha #1: async has no guaranteed order

javascript

<script async src="jquery.js"></script>
<script async src="app.js"></script> // Might run before jQuery!

Gotcha #2: Dynamic scripts are async by default

javascript

let script = document.createElement('script');
script.src = 'app.js';
document.body.append(script); // Behaves like async
 
// To make it ordered:
script.async = false; // Now behaves like defer

Gotcha #3: defer only works with external scripts

html

<script defer>alert('hi');</script> <!-- defer ignored! -->
<script defer src="app.js"></script> <!-- defer works -->

Resource Loading Events

What They Actually Do:

Track when external resources finish loading or fail.

javascript

// Script loading
let script = document.createElement('script');
script.src = 'library.js';
 
script.onload = () => {
    // Script loaded successfully
    console.log('Script ready!');
};
 
script.onerror = () => {
    // Script failed to load
    console.log('Script failed!');
};
 
document.head.append(script);

javascript

// Image loading
let img = new Image();
img.onload = () => console.log(`Size: ${img.width}x${img.height}`);
img.onerror = () => console.log('Image failed');
img.src = 'photo.jpg'; // Starts loading

Interview Gotchas:

Gotcha #1: onload doesn’t catch script errors

javascript

script.onload = () => {
    // This fires even if the script has bugs inside!
    console.log('Loaded, but might have errors');
};
 
// For script execution errors:
window.onerror = (message, url, line) => {
    console.log('Script error:', message);
};

Gotcha #2: Cross-origin error details are hidden

javascript

// Same domain - detailed errors
<script src="/my-script.js"></script>
 
// Different domain - generic "Script error"
<script src="https://other-site.com/script.js"></script>
 
// To get details from other domains:
<script crossorigin="anonymous" src="https://other-site.com/script.js"></script>

Bottom Line Summary:

Page Events: DOMContentLoaded = DOM ready, load = everything ready, beforeunload = leaving confirmation, unload = actually leaving.

Script Loading: defer = download parallel + execute after DOM in order, async = download parallel + execute immediately (no order), normal = blocks everything.

Resource Events: onload = success, onerror = failed. Use these to know when external stuff is ready or broken.

Key Rule: Scripts block DOMContentLoaded unless they’re async or defer. Images and CSS don’t block DOMContentLoaded, but CSS blocks scripts that come after it.