Which video event signals completion, and how do you track playback time?

Tests HTMLMediaElement events and UI performance. Answer: use ended for replay; read currentTime on timeupdate but throttle updates or use requestAnimationFrame. Red flag: setInterval polling, currentTime===duration checks, or unthrottled state writes.
What's really being asked
This question probes two separate HTMLMediaElement API concepts plus a hidden performance dimension. The interviewer wants to know if you understand native media lifecycle events versus manual polling, and whether you recognize that timeupdate is a high-frequency firehose that can wreck rendering performance if you update framework state or the DOM on every tick.
The full answer
First, the ended event is the correct signal that playback has finished. You should add an event listener for ended on the video element and use that to toggle the replay button visibility. Do not rely on comparing currentTime to duration because container metadata and floating point values can mismatch by fractions of a second. Second, for the running timestamp, listen to the timeupdate event and read video.currentTime, which gives elapsed seconds as a floating point number. Third, and this is what separates senior candidates, you must address update frequency. The timeupdate event does not fire at a fixed interval; browsers may dispatch it anywhere from roughly 4 Hz to 66 Hz depending on implementation and system load. Updating React state or writing to innerText on every callback can cause layout thrashing or unnecessary re-renders. A solid answer proposes throttling the UI update to 100-250 ms for a coarse label, or using requestAnimationFrame to read currentTime from a ref and manually updating a text node for a smooth counter. Fourth, formatting the raw seconds into a human-readable MM:SS string is expected.
The mistakes people make
Using onfinish, oncomplete, onstop, or load instead of ended. Polling with setInterval every second instead of using timeupdate. Checking if currentTime exactly equals duration to detect the end, which is brittle. Updating unthrottled React state inside the timeupdate handler with no mention of performance cost. Confusing the paused state with ended, which means the replay button might disappear if the user simply pauses.
What usually comes next
How does your approach change if the video has the loop attribute enabled? The ended event will not fire. How would you build a custom seek bar? Combine timeupdate with pointer events on a progress rail, using currentTime and duration. What happens if the user scrubs while the video is playing? You may want to suppress timeupdate-driven UI changes during seeking to avoid jitter.
A concrete example
Consider a two-minute video. In Chrome, timeupdate might fire roughly four to ten times per second. If you call setState with the currentTime on every event in React, you schedule four to ten commits per second. A senior implementation stores the video element in a ref, listens to timeupdate, and inside a throttled callback updates a local state or DOM text node at most four times per second. For a butter-smooth progress ring, you would instead use requestAnimationFrame to read ref.current.currentTime and compute the fractional progress against duration, writing directly to an SVG stroke-dashoffset without touching React state at all.
Interview question
How should you reliably detect that a video has finished while keeping playback-time UI updates performant?
- a.Listen for the ended event to detect completion, and throttle timeupdate-driven reads of currentTime to limit UI updates.Correct
- b.Check if currentTime exactly equals duration inside an unthrottled timeupdate handler to detect the end, and write the timestamp to the DOM on every callback.
- c.Listen for the ended event to show the replay button, but update framework state with currentTime on every timeupdate event.
- d.Poll currentTime with setInterval every second and show the replay button when the value exactly equals duration, updating the timestamp on each tick.
Why? this is the answer
The ended event is the reliable browser signal for completion, whereas comparing currentTime to duration is brittle due to floating-point mismatches. Throttling timeupdate-driven reads prevents layout thrashing and unnecessary re-renders that would occur if you updated state on every high-frequency tick.
Just read this? Test yourself on what you have been reading.
Read the original → developer.mozilla.org
- #htmlmediaelement
- #dom-events
- #performance
- #video-api
- #frontend
Put your scrolling time to good use
Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.
The iPhone app is on the way
We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.
Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.
We are hiring for this. Every open role lists the topics its interview covers, so you can prepare for the real thing rather than guessing.
See open roles