What is the difference between
asyncanddeferon a script tag?Both download the script without blocking parsing.
asyncruns it as soon as it arrives, in any order;deferruns scripts after parsing, in document order, beforeDOMContentLoaded.<script src="analytics.js" async></script> <script src="vendor.js" defer></script> <script src="app.js" defer></script> <!-- runs after vendor.js -->Use
deferfor app code andasyncfor independent scripts like analytics. Module scripts are deferred by default, and both attributes are ignored on inline classic scripts.How does the browser turn HTML into pixels (the critical rendering path)?
HTML becomes the DOM and CSS the CSSOM; they combine into the render tree of visible nodes, then the browser runs layout, paint and compositing.
A classic script without
asyncordeferpauses parsing, and stylesheets block rendering. To speed up the first render, defer scripts, inline the critical CSS and preload the hero image.What is the difference between
DOMContentLoadedandload?DOMContentLoadedfires when the HTML is parsed and deferred scripts have run;loadfires later, after images, stylesheets and iframes have loaded too.HTML<!DOCTYPE html> <ol id="log"></ol> <script> const log = (msg) => { const li = document.createElement('li'); li.textContent = msg + ' at ' + Math.round(performance.now()) + ' ms'; document.getElementById('log').append(li); }; log('inline script'); document.addEventListener('DOMContentLoaded', () => log('DOMContentLoaded')); window.addEventListener('load', () => log('load')); </script>Start DOM code on
DOMContentLoaded(or withdefer); waiting forloaddelays the app until every image arrives.What does the browser do with invalid HTML like a
<div>inside a<p>?It never shows an error; the parser follows defined recovery rules. A
<div>start tag closes an open<p>, so the div ends up after the paragraph.HTML<!DOCTYPE html> <div id="box"><p>One<div>Two</div></p><table><tr><td>Cell</td></tr></table></div> <p>What the parser built:</p> <pre id="out" style="white-space: pre-wrap;"></pre> <script> document.getElementById('out').textContent = document.getElementById('box').innerHTML; </script>The result is
<p>One</p><div>Two</div><p></p>: the stray</p>makes an empty paragraph, and the table gets a<tbody>you never wrote, sotable > trmatches nothing. The parser keeps a stack of open elements to decide what closes what.Practice it: Valid Parentheses
Can an
<a>element contain a<div>?Yes, since HTML5.
<a>has a transparent content model: it may contain whatever its parent may contain, minus interactive content (another link, a button, an input). So a link wrapping a card is valid inside a<div>but not inside a<p>, which accepts only phrasing content.HTML<!DOCTYPE html> <style> .card { display: block; max-width: 260px; padding: 8px 12px; border: 1px solid #cbd5e1; border-radius: 8px; color: inherit; text-decoration: none; } .card:hover { border-color: #3b82f6; } </style> <a class="card" href="#course"> <div><strong>HTML course</strong></div> <div>40 lessons, free to start</div> </a> <p id="course">The whole card is one link.</p>What is the difference between
preload,prefetchandpreconnect?preloadfetches a resource the current page needs soon, at high priority.prefetchfetches what the next page will probably need, at low priority.preconnectopens the connection (DNS, TCP, TLS) to another origin without fetching anything.<link rel="preload" href="/fonts/inter.woff2" as="font" type="font/woff2" crossorigin> <link rel="preload" href="/hero.avif" as="image"> <link rel="prefetch" href="/checkout.js"> <link rel="preconnect" href="https://cdn.example.com"> <link rel="dns-prefetch" href="https://analytics.example.com">preloadneedsasto get the right priority, and fonts needcrossorigineven on the same origin or they download twice.How do you lazy load images, and which image should not be lazy loaded?
Add
loading="lazy"to<img>or<iframe>and the browser waits until it nears the viewport. Never lazy load the largest image visible on first load (usually the hero), because that delays the Largest Contentful Paint.<img src="hero.avif" alt="..." width="1200" height="600" fetchpriority="high"> <img src="card.avif" alt="..." width="400" height="300" loading="lazy" decoding="async">Set
widthandheighton every image so the browser reserves the space and nothing shifts (CLS).How do
srcset,sizesand<picture>work?srcsetlists sizes of one image andsizessays how wide it will display, so the browser downloads the smallest file that is sharp enough.<picture>chooses between different images or formats.<img src="photo-800.jpg" srcset="photo-400.jpg 400w, photo-800.jpg 800w, photo-1600.jpg 1600w" sizes="(max-width: 600px) 100vw, 50vw" alt="Team at work" width="800" height="533"> <picture> <source srcset="photo.avif" type="image/avif"> <source srcset="photo.webp" type="image/webp"> <img src="photo.jpg" alt="Team at work" width="800" height="533"> </picture>wdescriptors give each file's width;xdescriptors (1x,2x) suit fixed-size images. The<img>inside<picture>is required: it renders and carriesalt.What are Web Components and the Shadow DOM?
Web Components are browser-native reusable elements: custom elements (your own tags, defined with a class), the shadow DOM (a private tree whose styles do not leak in or out) and templates with slots.
HTML<!DOCTYPE html> <style>p { color: crimson; }</style> <p>Outside: styled by the page.</p> <user-badge name="Asha"></user-badge> <script> class UserBadge extends HTMLElement { constructor() { super(); this.attachShadow({ mode: 'open' }); } connectedCallback() { const p = document.createElement('p'); p.textContent = 'Hello, ' + this.getAttribute('name'); const style = document.createElement('style'); style.textContent = 'p { color: teal; font-weight: bold; }'; this.shadowRoot.replaceChildren(style, p); } } customElements.define('user-badge', UserBadge); </script>The page's
p { color: crimson }does not reach the paragraph inside the component. Custom element names need a hyphen, and inherited properties likecolorand CSS custom properties do pass into the shadow tree.How do you embed third-party content safely with an iframe?
Add
sandboxand grant only the permissions the frame needs. An emptysandboxblocks scripts, forms, popups and top-level navigation, and gives the frame a unique origin.<iframe src="https://widget.example.com" sandbox="allow-scripts allow-forms" allow="fullscreen" referrerpolicy="no-referrer" loading="lazy" title="Weather widget"></iframe>Never combine
allow-scriptswithallow-same-originfor content from your own origin: the framed script could remove its own sandbox. To stop other sites framing yours, sendContent-Security-Policy: frame-ancestors 'self'. See the iframe page.Why is setting
innerHTMLwith user input dangerous?innerHTMLparses the string as HTML, so user input becomes markup. Inserted<script>tags do not run, but event handler attributes do:<img src=x onerror="steal()">runs the attacker's code. That is cross-site scripting (XSS).HTML<!DOCTYPE html> <input id="name" value="<b>Asha</b> <i>Rao</i>" size="30"> <p>textContent: <span id="safe"></span></p> <p>innerHTML: <span id="unsafe"></span></p> <script> const input = document.getElementById('name'); const show = () => { document.getElementById('safe').textContent = input.value; document.getElementById('unsafe').innerHTML = input.value; }; input.addEventListener('input', show); show(); </script>Use
textContentfor text, and sanitize any user HTML with a library such as DOMPurify.What is progressive enhancement?
Progressive enhancement means building the core of the page in plain HTML that works everywhere, then adding CSS and JavaScript on top, so the page still works when a layer fails or loads slowly.
<form action="/search" method="get"> <input name="q" type="search" aria-label="Search"> <button>Search</button> </form> <!-- JavaScript can intercept this form for instant results; without JavaScript it still submits and works. -->Graceful degradation goes the other way: it starts from the full experience and adds fallbacks.
Advanced HTML Interview Questions
Script loading, the rendering path, parser error recovery, resource hints, responsive images, web components and security.