DEV Community

Arthur Corenzan
Arthur Corenzan

Posted on

Pasting screenshots takes way longer than pasting image files

Update. The demo was previously broken, now it's fixed.


Let me show you;

  1. Take a screenshot using an utility that dumps the image directly to your clipboard, so you can paste it. Like the PrintScreen key on Windows/Linux or Cmd+Shift+3 on macOS.
  2. Open this up https://eivfjo.csb.app.
  3. Paste with Ctrl+V on Windows/Linux or Cmd+V on macOS.
  4. Now copy an existing image from your computer—perhaps a screenshot saved to disk.
  5. Go back to the page and paste it.
  6. See any difference?

Here's how it worked out for me (I'm using Chrome on Windows, by the way);

  • The first paste, of the screenshot just taken, took about 500ms—I'm on a 4k display, your mileage may vary.
  • The second one, of a file from my computer, took 0ms.

Now I'll reveal it to you. We're doing nothing. Okay, it's not technically nothing. But we're not really doing anything useful or that should take too long for that matter.

So what gives?

Below there's the whole code you just tested. You can also check it over on CodeSandbox.

document.addEventListener("paste", (event) => {
  const now = performance.now();
  void event.clipboardData.files; // This line is the culprit.
  document.body.textContent = `It took ${performance.now() - now}ms`;
});
Enter fullscreen mode Exit fullscreen mode

If you're not familiar or need a refresher, void simply evaluates the expression and returns undefined. That's it. We might as well omit it. I only added it for dramatic purposes. The important bit is you have to access the files property on the clipboardData object carried by the event.

If you're curious why that is it's because the files array is a shim, its content is gathered in the property accessor get files() in the DataTransfer interface. You can read more on the spec.

The odd part is why the difference between pasting a screenshot and pasting a file.

MDN doesn't say anything. The spec has some curious bits but didn't explain it either.

My wild guess is that it isn't the browser's fault. Perhaps the underlying implementation on the OS captures the screen as a simple bitmap and then lazily encodes it to more suited format line PNG as it's read? I don't know.

It's a problem in any case because for one I can't even show the user some feedback that something's going on since event handlers block—the next frame doesn't start until it returns, so any changes to DOM, like adding a loading class to an element, will have to wait—but it's also freezing up the whole page for that period. Yikes! :(

Any ideas?

Top comments (0)