What is the difference between CSR, SSR, and SSG?
Client-side rendering (CSR) ships a minimal HTML shell and builds the page in the browser with JavaScript, which is simple to host but slow to first paint and weaker for SEO. Server-side rendering (SSR) generates full HTML on the server for each request, giving fast first paint and good SEO at the cost of server compute and a hydration step. Static site generation (SSG) renders HTML once at build time so a CDN serves it instantly, which is ideal for content that changes infrequently. Many modern frameworks let you mix them per route, choosing SSG for marketing pages, SSR for personalised pages, and CSR for highly interactive dashboards.
When should I use CSS Grid versus Flexbox?
Use Flexbox when you are laying out items along a single axis - a navigation bar, a toolbar, centring a card - where alignment in one direction dominates. Use CSS Grid when you need two-dimensional control, placing items into rows and columns at once, such as a page layout or a card grid that must align across both axes. They are complementary rather than competing: it is common to use Grid for the overall page structure and Flexbox inside individual components. As a rule of thumb, reach for Grid when you find yourself fighting Flexbox to control both rows and columns.
How do I improve my Core Web Vitals?
Target each metric specifically. For Largest Contentful Paint (LCP, good is 2.5s or less) preload the hero image, remove render-blocking CSS and JavaScript, and use a fast server or CDN. For Interaction to Next Paint (INP, good is 200ms or less) break up long JavaScript tasks, defer non-critical work, and avoid heavy main-thread computation during interactions. For Cumulative Layout Shift (CLS, good is 0.1 or less) set explicit dimensions or aspect-ratio on images and embeds and avoid inserting content above existing content. Measure with field data (Real User Monitoring) rather than only lab tools, because real devices and networks differ.
Do I need a JavaScript framework, or can I use plain JavaScript?
For small, mostly static sites, semantic HTML and a little vanilla JavaScript are often the simplest, fastest, and most resilient choice, especially with progressive enhancement. A framework like React, Angular, Vue, or Svelte earns its weight when you have substantial shared state, complex interactivity, many reusable components, or a large team needing consistent structure. The trade-off is added bundle size, build tooling, and a learning curve. Choose based on the application's complexity and your team's needs, not on hype, and remember you can adopt a framework incrementally.
What is hydration and why is it sometimes a performance problem?
Hydration is the step where client-side JavaScript attaches event listeners and reactive state to server-rendered HTML so the static page becomes interactive. The problem is that for large pages the framework must download, parse, and execute JavaScript for the entire tree before anything is interactive, which can delay responsiveness even though content appeared quickly. This "uncanny valley" - visible but not yet clickable - has driven techniques like partial hydration, islands architecture, and resumability that hydrate only the interactive parts or skip re-execution entirely. If hydration cost is hurting INP, look at shipping less client JavaScript per route.
How do I make a website accessible?
Start with semantic HTML - real buttons, headings, lists, labels, and landmarks - because native elements bring keyboard and screen-reader support for free. Ensure every interactive element is keyboard-operable with a visible focus indicator, provide text alternatives for images, maintain a colour contrast ratio of at least 4.5:1 for body text, and associate form inputs with labels. Use ARIA only to fill gaps native HTML cannot, following its first rule: prefer a native element over an ARIA role. Test with a keyboard alone and a screen reader, and validate against WCAG 2.1 AA, the common conformance baseline.
What causes cumulative layout shift and how do I prevent it?
Layout shift happens when content already on screen moves unexpectedly, typically because an image or ad loaded without reserved space, a web font swapped and reflowed text, or JavaScript injected content above existing content. Prevent it by always setting width and height (or aspect-ratio) on images and video so the browser reserves the box before the asset arrives, reserving space for ads and embeds, and using font-display: optional or size-adjust descriptors to minimise font reflow. Avoid inserting banners or notices above content the user is already reading. The target Cumulative Layout Shift is 0.1 or less.
Should I use TypeScript for a front-end project?
For anything beyond a trivial script, TypeScript is generally worth adopting because it catches a large class of errors at compile time, documents intent through types, and powers editor features like autocompletion and safe refactoring. The cost is a build step, some annotation overhead, and a learning curve around generics and advanced types. You can adopt it incrementally - TypeScript is a superset of JavaScript, so existing .js files keep working - and tune strictness over time. For teams and long-lived codebases the maintainability gains usually outweigh the upfront cost.
How do I reduce my JavaScript bundle size?
Begin by measuring with a bundle analyzer to see what is actually large. Apply code splitting so each route or heavy feature loads its own chunk on demand via dynamic import(), rely on tree shaking by importing only what you use from side-effect-free ES modules, and avoid pulling in heavy libraries for small needs. Replace large dependencies with lighter alternatives or native browser APIs where possible, and lazy-load below-the-fold and non-critical components. Finally, set and enforce a performance budget in CI so regressions are caught before they ship.
What is the difference between debouncing and throttling?
Both limit how often a handler runs in response to rapid events such as scroll, resize, or typing, but they behave differently. Debouncing waits until the events stop for a defined quiet period and then fires once - ideal for search-as-you-type, where you only want to query after the user pauses. Throttling guarantees the handler runs at most once per fixed interval while events continue - ideal for scroll or resize handlers that must update periodically but not on every frame. Choosing the wrong one leads to either missed updates or excessive work, so match the technique to whether you want the trailing call or a steady cadence.
How should I handle state management in a front-end app?
Keep state as local as possible: component-level state covers most needs, and lifting it up or sharing via context handles the rest. Reach for a dedicated library - Redux, Zustand, Pinia, or signals-based stores - only when you have genuinely global, frequently updated, or cross-cutting state that prop-drilling makes painful. Distinguish server state (data fetched from APIs, with caching and invalidation) from client UI state, since libraries like TanStack Query handle the former far better than a general store. Over-centralising state early adds boilerplate and coupling, so let the need drive the tool.
Is the Virtual DOM faster than direct DOM manipulation?
Not inherently - the Virtual DOM exists primarily to provide a simple declarative programming model, not raw speed. Diffing a virtual tree and applying minimal updates adds overhead that hand-tuned direct DOM manipulation can beat in narrow cases. Its value is that you describe the UI as a function of state and the framework figures out the updates, which scales far better for human authors than manual mutation. Newer fine-grained reactive frameworks (Solid, Svelte, signals in Angular and Vue) achieve the same declarative ergonomics while updating only the exact nodes that changed, often outperforming Virtual DOM diffing.
What is a Progressive Web App and do I need one?
A Progressive Web App is a website that adds a service worker, a web app manifest, and HTTPS to become installable, offline-capable, and app-like, reaching users without an app store. You benefit from one if users want offline access, home-screen installation, push notifications, or fast repeat visits - for example a productivity tool, a reader, or a field app on flaky networks. If your site is purely informational and always online, a PWA may add complexity for little gain. Treat it as progressive enhancement: the site should work as a normal website first, with PWA features layering on top.
How do I prevent cross-site scripting (XSS) in a front-end app?
Treat all user-controlled data as untrusted and rely on contextual output encoding, which modern frameworks do automatically when you interpolate values into templates. Avoid setting innerHTML (or React's dangerouslySetInnerHTML) with unsanitised content; if you must render HTML, sanitise it with a vetted library like DOMPurify. Deploy a strict, nonce-based Content Security Policy as defence-in-depth so that even an injected script cannot execute, and use Subresource Integrity for third-party scripts. Never build markup by string-concatenating user input, and validate input on the server as well, since client-side checks alone are not a security boundary.
What is the difference between responsive design and adaptive design?
Responsive design uses a single fluid layout that continuously adjusts to any viewport through flexible grids, flexible media, and media or container queries, so it flows smoothly across all sizes. Adaptive design instead detects the device or viewport and serves one of several fixed layouts designed for specific breakpoints, snapping between discrete versions. Responsive is the dominant modern approach because it handles the unpredictable range of devices with one codebase and degrades gracefully to new screen sizes. Adaptive can give more pixel-precise control per device but is more work to build and maintain.
When should I use a CSS framework like Tailwind versus writing custom CSS?
A utility-first framework like Tailwind speeds up development, enforces a consistent design system through configured tokens, and avoids the naming and dead-CSS problems of large hand-written stylesheets, at the cost of verbose markup and a build step. Plain CSS - possibly with modern features like custom properties, nesting, container queries, and cascade layers - gives full control, no framework lock-in, and cleaner markup, but requires discipline to stay maintainable at scale. The decision often comes down to team preference, project size, and whether you value rapid iteration with strong conventions or maximal control. Both can produce excellent, performant results when used well.