Common Frontend Developer interview questions spanning HTML, CSS, JavaScript, frameworks, performance, accessibility, and system design — from beginner to advanced.
'display: none' removes the element from the document flow entirely, so it takes up no space. 'visibility: hidden' hides the element visually but it still occupies space in the layout.
== performs type coercion before comparison, so '5' == 5 is true. === checks both value and type without coercion, so '5' === 5 is false. Always prefer === to avoid unexpected bugs.
The box model describes how every HTML element is rendered as a rectangular box consisting of content, padding, border, and margin. Understanding it is essential for layout control. Using 'box-sizing: border-box' makes width/height include padding and border.
'var' is function-scoped and hoisted; 'let' and 'const' are block-scoped and not accessible before declaration (temporal dead zone). 'const' additionally prevents reassignment of the variable binding, though the object it points to can still be mutated.
Semantic HTML uses meaningful tags like <article>, <nav>, <header>, and <main> to convey the purpose of content. It improves accessibility for screen readers, helps search engine indexing, and makes code more maintainable.
Flexbox is a one-dimensional layout system best suited for aligning items in a row or column. CSS Grid is two-dimensional and ideal for complex page-level layouts. Use Flexbox for component-level alignment and Grid for overall page structure.
Hoisting moves variable and function declarations to the top of their scope before code executes. Function declarations are fully hoisted (callable before their definition), while 'var' variables are hoisted but initialized as undefined. 'let' and 'const' are hoisted but remain in the temporal dead zone.
JavaScript is single-threaded and uses an event loop to handle asynchronous operations. The call stack executes synchronous code; when it's empty, the event loop picks tasks from the callback queue (macrotasks) or microtask queue (Promises). Microtasks always run before the next macrotask.
'undefined' means a variable has been declared but not assigned a value. 'null' is an intentional assignment representing the absence of a value. typeof null returns 'object' — a well-known JavaScript quirk.
A closure is a function that retains access to its outer lexical scope even after the outer function has returned. A practical use case is data encapsulation — e.g., a counter factory function that keeps a private count variable inaccessible from outside.
The browser parses HTML into a DOM tree, parses CSS into a CSSOM, combines them into a render tree, performs layout (reflow) to calculate element positions, then paints pixels to the screen. Blocking scripts and large stylesheets delay this process, so minimizing render-blocking resources improves performance.
The Virtual DOM is an in-memory lightweight copy of the real DOM. When state changes, React diffs the new and old virtual DOM (reconciliation) and applies only the minimal set of real DOM updates. This avoids costly full re-renders and improves performance.
Hooks (useState, useEffect, useContext, etc.) let functional components use state and lifecycle features that previously required class components. They were introduced to reduce boilerplate, improve code reuse through custom hooks, and eliminate confusing 'this' binding.
CORS (Cross-Origin Resource Sharing) is a browser security mechanism that blocks requests to a different origin unless the server explicitly allows it via response headers like 'Access-Control-Allow-Origin'. On the frontend you handle it by ensuring the backend sets proper CORS headers, or proxying requests through your own server during development.
Core Web Vitals are Google's metrics for user experience: Largest Contentful Paint (LCP) measures loading performance, First Input Delay (FID) / Interaction to Next Paint (INP) measures responsiveness, and Cumulative Layout Shift (CLS) measures visual stability. Optimizing these improves both UX and SEO rankings.
Code splitting breaks a large JavaScript bundle into smaller chunks loaded on demand, reducing initial load time. In React you implement it using React.lazy() with Suspense for component-level splitting, or dynamic import() for route-based splitting with tools like React Router and webpack/Vite.
Memoization caches a computed result so it isn't recalculated on every render. React.memo prevents re-rendering a component if its props haven't changed; useMemo caches an expensive computed value; useCallback memoizes a function reference. Overusing them adds overhead, so apply them only when profiling reveals a genuine performance bottleneck.
Web Workers run JavaScript in a background thread, separate from the main UI thread, preventing heavy computations from blocking rendering. Use them for CPU-intensive tasks like image processing, data parsing, or cryptographic operations where you can't afford to freeze the UI.
Key strategies include feature-based (vertical slice) folder structure, a clear state management strategy (local state vs. server state with React Query vs. global state with Redux/Zustand), component design systems, strict TypeScript typing, automated testing at unit/integration/e2e levels, and CI/CD pipelines with performance budgets. Module federation or micro-frontends can further scale independent team ownership.
CSR (Client-Side Rendering) renders in the browser, great for interactivity but poor initial load/SEO. SSR (Server-Side Rendering) renders HTML on each request, improving SEO and TTFB. SSG (Static Site Generation) pre-renders at build time for maximum performance. ISR (Incremental Static Regeneration, e.g. Next.js) combines SSG with on-demand revalidation, giving static speed without full rebuilds.
© RM Full Stack & AI Engineer · All interview questions · Roadmaps · Open the app