Cancelling a HEIC to JPG conversion that has already started

You cannot. There is no cancel button, no keyboard shortcut and no abort path — the page has exactly one button, and it is Convert another. Once a file is handed over, it runs to completion: as little as 164 ms for a phone-sized photo, 5–7 seconds for a 12-megapixel one, 10–15 seconds for a 27-megapixel one. The only exit is to reload the page or close the tab, and that throws away everything done so far.

No cancel control 7 interventions tried 24 conversions measured

Short answer: no. I tried seven different ways to stop a conversion that had already begun — clicking the upload area, pressing Escape, clicking Convert another, changing the quality setting, handing over a second file, clicking the spinner itself, and clicking a link to leave the page. Six of them did nothing at all: the conversion finished anyway and produced the same 3,177,680-byte file every time. The seventh left the page, which is the only thing that genuinely stops the work.

There is nothing to click. The live page I measured today is 14,457 bytes and contains one <button>, eighteen links, one <select> and one file input. The word "cancel" appears zero times in the visible text, and AbortController, abort( and terminate appear zero times in the page source. The spinner is a plain <div> reading "Converting…" with no role, no aria-live and no click handler.

Reloading is the only cancel, and it is a real loss. On a 12-megapixel file whose conversions were taking a median of 5,518 ms, reloading a quarter of the way in discarded 1,426 ms of work; halfway in, 2,783 ms; three quarters in, 4,209 ms. Nothing survives — no partial result, no message, no error.

What the page actually puts on screen

I loaded the converter and inventoried every interactive thing on it. This is the whole list:

ElementWhat it isCan it stop a conversion?
#again (the only button)"Convert another"No — it hides the result area and clears the file input
#drop (upload area)A clickable region, 714 × 180 pxNo — it opens the file picker
#q (quality)A select with three optionsNo — it is read when the file is handed over
#finput (file input)Hidden, enabled, not multipleNo — it starts conversions
#busy (spinner)A div, text "Converting…"No — no role, no handler, no aria-live
18 linksNavigation and guide linksOnly by leaving the page

I also searched the page for the machinery a cancel button would need. In the 14,457 bytes of live HTML: AbortController 0, abort( 0, cancel 0, terminate 0, setTimeout 0, setInterval 0, six addEventListener calls, one .then( and one .catch(. In the decoder itself, the 2,999,737-character heic-to.js: AbortController 0, abort( 0, cancel 0, terminate 1, setTimeout 3. On screen there are zero <progress> elements, zero <dialog> elements and zero aria-live regions, and the 4,064 characters of visible text contain no instance of "cancel", "stop", "abort" or "interrupt".

That last point matters as much as the missing button: there is no progress indicator either. You are not told how far along a conversion is, only that it is running.

What the controls look like while one is running

I started a 12-megapixel conversion (11,084,868 bytes) and took a snapshot of every control 1,209 ms in, while it was still working:

ElementState mid-conversion
Spinnervisible (block), pointer events auto, plain cursor — clickable, but nothing happens
Upload areavisible, pointer events auto, cursor pointer, no disabled attribute
Quality menuvisible and enabled — not greyed out, not disabled
File inputhidden, enabled
Convert anothercomputed as inline-flex, but its container is hidden, so it is not on screen
Result area / error areaboth hidden

Nothing is locked during a conversion. The upload area still invites a click, the quality menu still looks usable, and neither does anything to the work in flight — which is exactly why this feels like it ought to be cancellable. That conversion went on to finish normally at 3,177,680 bytes after 14,257 ms.

Seven things I tried while one was running

Each row is a separate run on a freshly reloaded page, using the same 12-megapixel file. The intervention was applied about 1.5 seconds in, while the spinner was still visible. Every conversion that was allowed to finish produced the same file: 3,177,680 bytes, 4032×3024, identical SHA-256.

What I didWhenDid it stop?What happened instead
Nothing (control)——finished in 8,348 ms
Clicked the upload area1,527 msnothe file picker opened; spinner stayed visible; finished in 6,113 ms
Pressed Escape1,572 msnospinner stayed visible; finished in 8,075 ms
Clicked Convert another1,519 msnoresult area stayed hidden, info line stayed empty; finished in 6,412 ms
Changed quality 85% → 75%1,544 msnothe converter still used 0.85 and produced the same file; finished in 6,123 ms
Handed over a second file1,534 msnotwo conversions ran; the first still finished in 8,889 ms
Clicked the spinner itself1,531 msnofinished in 6,100 ms
Clicked a footer link to leave1,572 msyesthe page navigated 142 ms after the click

Two of those deserve a note. Handing over a second file does not replace the first — it starts a second, parallel piece of work, which I measured separately in dropping a second photo in mid-conversion. And changing the quality setting does not stop or restart anything, because the setting is read once, at the moment the file is handed over, as I measured in changing quality midway.

Leaving the page by clicking a link is the one action that works, and it works quickly: the navigation began 142 ms after my click, against 373 ms for the same link clicked on an idle page. The main thread is not blocked while a conversion runs, so you can always walk away — you just cannot stop the work and keep the page.

Reloading: the only cancel, and what it costs

I first measured the file's normal cost — three uninterrupted conversions of the same 12-megapixel HEIC took 12,249, 5,518 and 4,374 ms, a median of 5,518 ms. Then I started three more and reloaded the page at a quarter, a half and three quarters of that median.

Reload issued atWork discardedPage ready again afterState after reload
25% (1,380 ms target)1,426 ms208 msclean
50% (2,759 ms target)2,783 ms235 msclean
75% (4,139 ms target)4,209 ms227 msclean
idle page (control)—249 msclean

"Clean" means the same four things every time: spinner hidden, result area hidden, error area hidden, info line empty, download link empty, file input holding zero files, and zero console entries. There is no partial JPG and no "you cancelled something" message. That matches what I found in reloading or switching away mid-conversion: the work is simply gone.

The reload itself is cheap and indifferent to how much work it is destroying: the page came back in 208, 235 and 227 ms, against 249 ms for a reload of an idle page. Abandoning a conversion costs no more than reloading a page that was doing nothing.

The one place you genuinely can cancel

Before the file is handed over, you are still in charge. I clicked the upload area on a fresh page and let the file picker open without choosing anything: three seconds later, zero conversions had started and the spinner was not showing. So dismissing the picker really is a cancel — it is just a cancel of a conversion that never began.

It is also harmless to an existing result. After one photo had finished converting (38,078 bytes, 700×476), I opened the picker again and ignored it; three seconds later the result area was still on screen and the info line was unchanged. Nothing was destroyed by opening and dismissing the dialog in my test.

A caveat on how I measured this: rather than pressing Cancel in a real operating-system dialog, I had Chrome intercept the picker and then never answered it. The effect on the page should be the same — no file arrives, so nothing starts — but I did not click a real Cancel button.

How long you are actually stuck

Whether any of this matters depends on the file. These are three consecutive conversions each, at the default quality, of four different sizes. The first conversion after a page load carries the decoder warm-up cost, which is why the first number in each row is the largest.

SourceHEIC inJPG outThree runs
700 × 476 (phone photo)41,465 B38,078 B778 / 196 / 164 ms
2000 × 15002,768,977 B795,543 B2,030 / 1,242 / 1,317 ms
4032 × 3024 (12 MP)11,084,868 B3,177,680 B7,062 / 5,317 / 6,036 ms
6000 × 4500 (27 MP)24,470,938 B7,013,308 B14,956 / 12,945 / 10,207 ms

At the top of that table the whole question is academic — 164 ms is over before you can reach for anything. At the bottom it is not: a 27-megapixel file holds the page for ten to fifteen seconds with no way to call it off. For reference, the largest file I have pushed through this converter is 108 megapixels, which took 75,996 ms, as measured in how large a HEIC it can take.

There is no timeout either

This part is a probe rather than something you can do as a visitor, so treat it as evidence about the page rather than advice. The decoder runs in one worker. I started a 12-megapixel conversion, killed that worker 1,529 ms in, and then watched the page for almost 22 seconds.

The spinner stayed visible the whole time, sampled every two seconds. The result area never appeared, the error area never appeared, no console entry was written, and the page still answered every query I sent it. Nothing gave up, nothing timed out, nothing explained itself. The page has no watchdog: if the work disappears without reporting back, it waits forever.

That is the flip side of having no cancel button. A cancel control needs the same plumbing as an error path, and neither exists here — the only two outcomes the page knows how to draw are "Converting…" and "done".

What to do instead

  1. For one photo, just wait. A phone-sized HEIC finished in 164–196 ms once the page was warm. There is nothing to cancel in that time.
  2. For a big file, decide before you drop it. 12 megapixels costs about 5–7 seconds and 27 megapixels about 10–15. Those are the numbers you are committing to.
  3. If you must abort, reload — and expect to redo it. Reloading discards everything done so far and leaves no trace. There is no cheaper option.
  4. Switching tabs does not help. A background tab keeps converting and produces the same bytes; I measured that in the interruption tests.
  5. Download as soon as the result appears. The JPG only exists in the page's memory, and reloading or closing the tab destroys it — see what survives after you delete the source.
  6. A retry costs the same as the first attempt. The output is deterministic, so aborting and starting over gives you an identical file for double the time, never a different one — measured in the determinism test.

Questions

Is there a cancel button I am missing?

No. I counted one <button> on the page and it is "Convert another". The words "cancel", "stop" and "abort" do not appear anywhere in the 4,064 characters of visible text, and AbortController does not appear in the page source or in the decoder.

Does Escape cancel it?

No. I pressed Escape 1,572 ms into a 12-megapixel conversion and it finished 8,075 ms in, producing the same 3,177,680-byte file. There is no keyboard route to the upload area at all, which I measured in the keyboard-only test.

Will closing the tab stop it faster than reloading?

Both abandon the work completely. I measured reloading at three points in this article; closing the tab behaves the same way and also produces no warning, as I found in the tests on leaving the page.

Why is there no cancel button?

I can only describe what is there, not why. The conversion is a single call that hands the file to the decoder and waits for one result, with no mechanism in the page or in the decoder to interrupt it, and no error path other than the generic failure message. Adding a real cancel would mean changing both.

Does this change on a phone or in another browser?

The output does not change — I have measured identical bytes across browsers and device pixel ratios in the browser support tests. The durations in this article are from one desktop machine running Chrome 154, and a slower device will stretch every one of them, as measured in the slow-CPU tests.

Try it: open the converter and drop in one photo. Watch the spinner — that is the whole interface until it finishes.

First published: 13 October 2026