AnyLearn
All interview prep
EngineeringMid-levelFrontend Engineer

Frontend Engineer Interview Prep: Questions and a Mock Test

Frontend interviews have drifted a long way from trivia about which browser supports what. The modern loop tests whether you understand the platform underneath the framework: what blocks the main thread, why a layout shifts, what a component re-renders and why, and what the browser will and will not let one origin do to another. This page covers what the rounds examine, one set of numbers that changed recently enough to catch people out, and ends with a graded mock across six areas.

The loop

How the process is structured

The interview loop: each round, how long it runs, and what it tests
RoundLengthWhat it tests
1.JavaScript fundamentals[1]Not publishedClosures and scoping, this binding, prototypes, promises and async ordering, and the event loop. Often delivered as short output-prediction snippets rather than as explanation questions.
2.Component build[2]Not publishedBuilding a working interface live, typically an autocomplete, a data table or a modal. Assessed on state modelling, handling loading and error and empty states, keyboard support, and whether you notice the race condition when requests return out of order.
3.Frontend system design[1]Not publishedArchitecture for a non-trivial interface: component boundaries, state ownership, data fetching and caching, rendering strategy, and performance budgets. Core Web Vitals are the usual measurement vocabulary, assessed at "the 75th percentile of page loads".
4.Accessibility and security review[2]Not publishedReading markup and finding what is wrong with it. WCAG 2.2 is the current standard, organised around perceivable, operable, understandable and robust, at conformance levels A, AA and AAA. Browser security questions cover same-origin policy, XSS and token storage.

Bracketed markers point to the dated sources at the end of this article. Loops change; check the retrieval dates before relying on a round count.

Core Web Vitals, with the current numbers

Performance questions in a frontend loop almost always route through Core Web Vitals, and the metric set changed recently enough that a lot of preparation material is wrong.

There are three. Largest Contentful Paint should occur within 2.5 seconds. Interaction to Next Paint should be 200 milliseconds or less. Cumulative Layout Shift should be 0.1 or less. All three are assessed at "the 75th percentile of page loads, segmented across mobile and desktop devices", which is worth saying out loud, because it means your median user's experience is not what is being measured.

The important currency detail: Interaction to Next Paint replaced First Input Delay. INP "was promoted in 2023 from experimental to pending status with the intent to eventually retire FID" and "became a stable Core Web Vital metric in 2024". Naming FID as a current Core Web Vital is a clean dating signal, and the difference is substantive rather than cosmetic. FID measured only the delay before the first interaction began processing, which flattered pages badly: an app could score well while every interaction after the first was slow. INP considers interactions across the whole page visit and includes the time to render the next frame, so it measures what the user actually feels.

The practical consequences follow. LCP is usually fixed by prioritising the hero resource, preloading it, avoiding lazy-loading it, and cutting render-blocking work. CLS is fixed by reserving space: explicit dimensions on media, space for anything injected late, and avoiding inserting content above what someone is already reading. INP is fixed by getting long tasks off the main thread, breaking up work, and not doing expensive rendering synchronously inside an event handler.

The event loop is the model everything rests on

Almost every JavaScript round contains a question that reduces to the event loop, because it explains both correctness and performance.

The model to be able to state: JavaScript runs on one thread with a call stack. When the stack empties, the runtime drains the microtask queue completely, then takes one task from the macrotask queue, then repeats. Promise callbacks are microtasks; setTimeout callbacks, and events, are tasks. That ordering is what makes a promise resolved with no delay run before a setTimeout with zero delay, and it is why an endlessly self-scheduling microtask starves the page while an endlessly self-scheduling timeout does not.

The performance consequence is the one interviewers care about. Rendering happens between tasks, so any synchronous work longer than a frame budget blocks painting and delays interaction response. That is the mechanism behind a poor INP score, and it is why the standard advice is to break long tasks up, yield to the main thread, and move genuinely heavy computation to a worker.

Expect the closure and scoping questions too, because they still separate people. A var declaration inside a loop shares one binding, which is the classic reason a set of callbacks all see the final value, while let creates a fresh binding per iteration. And expect this: arrow functions take this lexically from where they are defined, ordinary functions take it from how they are called, which is why a method extracted from an object and passed as a callback loses its receiver.

Rendering, reconciliation and re-renders

Framework rounds test whether you can explain why something rendered, not whether you can recite an API.

The general model: a change to state produces a new description of the UI, the framework compares it against the previous description, and applies the minimum set of real DOM operations. Keys exist so that comparison can match elements across renders. Using an array index as a key is the classic bug, because inserting at the front shifts every index, so the framework matches the wrong old element to each new one and component state ends up attached to the wrong row. A stable identifier from the data is the fix.

Re-render questions follow. A component re-renders when its own state changes, when its parent re-renders, or when a context it consumes changes. It does not re-render because a variable it closes over changed, which is a common source of confusion. Memoisation helps only when the comparison is cheaper than the render, and passing a freshly created object or inline function as a prop defeats it, since a new reference fails the shallow comparison every time.

Accessibility belongs in this section rather than as an afterthought, because in a strong loop it is examined alongside markup. The current standard is WCAG 2.2, published in October 2023, organised around four principles, perceivable, operable, understandable and robust, with success criteria at three conformance levels, A, AA and AAA. WCAG 3 exists only as an early draft. In practice the interview questions are concrete: use semantic elements rather than a div with a click handler, ensure keyboard operability and visible focus, label form controls, and reach for ARIA only when no native element expresses the semantics.

Data fetching, caching and the states people forget

Data fetching rounds are where interviewers find out whether you have shipped something real, because the failure modes are so specific.

The first is the incomplete state machine. Every fetch has at least four states, idle, loading, success and error, and a great many interfaces only implement two. Empty is a fifth that is distinct from loading and usually needs its own treatment, because a successful response with zero results is not an error and should not look like one.

The second is the race. Two requests fired for different queries can return out of order, so the slower earlier request overwrites the newer result. The answers are an abort controller cancelling the superseded request, or tracking the latest request identifier and discarding responses that are not current. Any candidate who has built a search-as-you-type interface will have met this.

The third is caching. A client cache needs a key that captures every input to the request, a staleness policy, and a story for invalidation after a mutation. Optimistic updates are the follow-up: applying the change locally before the server confirms makes the interface feel instant, and requires a rollback path when the request fails, which is the half candidates omit.

Beyond that, expect debouncing versus throttling as a distinction, retry with backoff for transient failures, and pagination, where cursor-based approaches avoid the duplicate and skipped rows that offset pagination produces when the underlying data changes between pages.

What the browser does and does not protect you from

Security questions in a frontend loop concentrate on the boundaries the browser enforces and the ones it does not.

The same-origin policy is the foundation: scripts from one origin cannot read responses from another, where origin means scheme, host and port together. Cross-Origin Resource Sharing is the server opting to relax that, which is why CORS errors are so often misdiagnosed as client bugs when the fix is always on the server.

Cross-site scripting remains the most commonly examined class, and the correct framing is contextual output encoding rather than input sanitisation, because the same string is safe in an HTML body and dangerous in a JavaScript context or a URL. Content Security Policy is defence in depth on top, and dangerously setting inner HTML from user content is the direct route to the vulnerability.

Token storage is a favourite because there is no clean answer. Local storage is readable by any script on the page, so an XSS becomes a token theft. A cookie with HttpOnly is not readable by script, which removes that path, but cookies are attached automatically and therefore need SameSite and CSRF protection. The strong answer states the tradeoff rather than pretending one option is simply correct.

Worth knowing that in OWASP's 2025 Top 10, broken access control remains first and injection has moved to fifth, and that neither of those is a browser-side fix. A frontend that hides a button is not enforcing anything, because the client is under the user's control and every check that matters happens on the server.

Open-ended

What they actually ask

  1. 1.Build an autocomplete search field. Talk me through what you handle.

    What a strong answer covers

    Interviewers use this because it contains most frontend concerns at once. Expected: debouncing input so a request is not sent per keystroke, and being clear that debounce delays until input stops while throttle limits rate. Cancelling superseded requests with an abort controller, or discarding stale responses, so a slow early request cannot overwrite a fast later one. A complete state machine including empty results, which is not an error. Keyboard support, arrow keys, enter, escape, and the ARIA combobox semantics that make the listbox announce properly, since a div-based dropdown is invisible to a screen reader. Caching by query string, minimum query length, and what happens offline. The strongest candidates mention that results must not shift the page layout as they load, which is a Cumulative Layout Shift concern.

  2. 2.Largest Contentful Paint on the marketing page is 4.5 seconds. How do you approach it?

    What a strong answer covers

    Measure before changing anything, and specifically at the 75th percentile on real devices rather than on a developer laptop, since the threshold is defined that way. Then identify which element is the LCP element, because the fix depends on whether it is an image, a text block or a video poster. Common causes: the resource is discovered late because it is inserted by JavaScript, it is lazy-loaded when it is above the fold, render-blocking stylesheets or fonts delay it, or the server response itself is slow. Fixes follow: preload the resource, mark it high priority, remove lazy loading for it, inline critical CSS, use font-display so text is not invisible while a webfont loads, and address time to first byte with caching or a CDN. The 2.5 second target should be stated as the goal.

  3. 3.A colleague says accessibility can be added at the end of the project. What is your response?

    What a strong answer covers

    The practical argument is that retrofitting is far more expensive, because the defects are structural rather than cosmetic: a custom control built from divs cannot be made keyboard operable by adding attributes, it has to be rebuilt or replaced with a native element. Strong answers name concrete things that are nearly free at build time and painful later, semantic elements, labels associated with inputs, focus management in modals, colour contrast, and not conveying meaning by colour alone. They reference the standard rather than opinion, WCAG 2.2 at level AA being the common contractual target, organised around perceivable, operable, understandable and robust. Mentioning the legal and procurement reality without being alarmist is reasonable, as is noting that automated tools catch only a fraction of issues and keyboard-only testing catches more.

  4. 4.Where would you store an authentication token in a single-page application?

    What a strong answer covers

    The strongest answers refuse the premise that one option is simply correct and lay out the tradeoff. Local storage is convenient and is readable by any script on the page, so a single cross-site scripting flaw becomes full token theft, and tokens there are not protected from third-party scripts you did not audit. An HttpOnly cookie cannot be read by script, which removes that path, but it is sent automatically with requests, which introduces cross-site request forgery and therefore requires SameSite and usually a token or origin check. In-memory storage is the safest against exfiltration and does not survive a refresh, which pushes you toward a refresh token in an HttpOnly cookie. Strong candidates conclude that the real mitigation is preventing XSS in the first place, because no storage choice survives arbitrary script execution on your origin.

  5. 5.A list of 10,000 rows makes the page unusable. What do you do?

    What a strong answer covers

    Expected first move is to establish where the time goes rather than guessing: is it initial render, is it re-render on every keystroke, is it layout and paint, or is it memory pressure. Then the structural answer, which is to stop rendering what is not visible, through virtualisation that mounts only the rows in the viewport plus a small overscan. Strong answers cover the complications virtualisation brings, variable row heights, keyboard navigation, and find-in-page no longer working, and mention pagination or progressive loading as simpler alternatives that may be better product decisions. They also address the re-render side: stable keys from data rather than array indices, memoised row components, and not creating new callback references per row, which defeats the memoisation.

  6. 6.How would you structure state in an application that has grown to fifty components?

    What a strong answer covers

    The organising principle is that different kinds of state need different homes. Server data is a cache of something you do not own and belongs in a data-fetching layer with staleness and invalidation, not in a global store copied by hand. URL state, including filters and the current page, belongs in the URL so it can be shared and restored. Local UI state should live in the component that owns it and be lifted only as far as the nearest common ancestor that needs it. Truly global client state is usually small, theme, session, feature flags. Strong answers warn that context re-renders every consumer when its value changes, so a single large context is a performance trap, and that the common failure is putting server data into a global store and then reimplementing caching badly.

Worked examples

Three sample questions, answered

These three show the level the mock is pitched at, with the answer and the reasoning in the open. The graded paper keeps its answer key server-side.

1.Which metric replaced First Input Delay as a Core Web Vital, and what is its 'good' threshold?
Performance and Core Web Vitals
  • Time to Interactive, at 3.8 seconds or less
  • Interaction to Next Paint, at 200 milliseconds or less
  • Total Blocking Time, at 200 milliseconds or less
  • First Contentful Paint, at 1.8 seconds or less

Why: Interaction to Next Paint became a stable Core Web Vital in 2024, replacing First Input Delay. The good threshold is 200 milliseconds or less. INP is stricter because it considers interactions throughout the page visit and includes rendering the next frame, rather than only measuring the delay before the first interaction began processing.

2.Why is using an array index as a list key a problem?
Rendering, semantics and accessibility
  • Indices are numbers, and keys must be strings
  • It prevents the list from being sorted
  • It causes the entire list to unmount on every render
  • Inserting at the front shifts every index, so state and DOM nodes get matched to the wrong items

Why: Keys let the reconciler match elements across renders. An index is a position, not an identity, so any insertion or reordering changes which item each key refers to. The visible symptom is component state, such as text typed into an input, staying with the position rather than following the data. A stable id from the data fixes it.

3.In the browser, a promise callback and a setTimeout with 0 delay are both scheduled. Which runs first?
JavaScript and the event loop
  • The promise callback, because microtasks drain before the next task is taken
  • The setTimeout callback, because timers have higher priority
  • Whichever was scheduled first, since both queues are FIFO together
  • They run in the same tick, so the order is not defined

Why: When the call stack empties, the runtime drains the entire microtask queue before taking one task from the macrotask queue. Promise reactions are microtasks; timer callbacks are tasks. This is also why a microtask that continually schedules another microtask starves the page, while a self-scheduling setTimeout does not.

The mock

An 18-question knowledge check

This is a knowledge check, not a simulation. The real loop happens on a whiteboard, in an editor, and in conversation. What this paper does measure is the underlying knowledge those rounds draw on: each question is tagged with a topic, grading happens per topic, and a weak topic points you at the course that fixes it.

Your paper0 / 18 answered
  1. 1.At what percentile are Core Web Vitals thresholds assessed?
    Performance and Core Web Vitals
  2. 2.Which change most directly reduces Cumulative Layout Shift?
    Performance and Core Web Vitals
  3. 3.Why is Interaction to Next Paint a stricter measure than First Input Delay was?
    Performance and Core Web Vitals
  4. 4.A loop using var to declare its counter creates three callbacks. What value do they all see?
    JavaScript and the event loop
  5. 5.An object method is passed directly as a click handler and this becomes undefined. Why?
    JavaScript and the event loop
  6. 6.Why does a long synchronous task hurt interaction responsiveness?
    JavaScript and the event loop
  7. 7.Which of these does NOT cause a React-style component to re-render?
    State, hooks and effects
  8. 8.Memoising a child component has no effect because it re-renders every time. What is the most likely cause?
    State, hooks and effects
  9. 9.Under WCAG 2.2, which is the strongest reason to use a button element rather than a div with a click handler?
    Rendering, semantics and accessibility
  10. 10.A user types quickly in a search box and sees results for an earlier query. What is happening?
    Data fetching and client caching
  11. 11.What does list virtualisation actually change, and what does it cost?
    Rendering, semantics and accessibility
  12. 12.What must an optimistic update always include?
    State, hooks and effects
  13. 13.Why does offset-based pagination produce duplicate or missing rows on an active dataset?
    Data fetching and client caching
  14. 14.A fetch succeeds and returns an empty array. How should the interface treat it?
    Data fetching and client caching
  15. 15.What exactly does the same-origin policy compare?
    Browser security
  16. 16.Setting innerHTML from a value the user supplied creates which vulnerability?
    Browser security
  17. 17.What does an HttpOnly cookie protect against, and what does it not?
    Browser security
  18. 18.In OWASP's Top 10 2025, which category ranks first, and what does that imply for frontend work?
    Browser security
18 questions left to answer.
Apparatus

Sources

Hiring loops change. Every claim above carries a retrieval date so you can judge how current it is.

  1. [1]web.dev, Web Vitals · retrieved 2026-08-13
  2. [2]W3C Web Accessibility Initiative, WCAG 2 Overview · retrieved 2026-08-13
  3. [3]OWASP, Top 10:2025 · retrieved 2026-08-13
Keep preparing

Refresh your memory

Free learning paths covering the ground this loop tests, whatever your score. Each one ends with a shareable certificate.