4

I'm loading and playing audio files using the Audio() constructor. This works fine in most browsers, but Chrome seems to make a new GET request for the site's favicon every time .play() is called. It looks like this happens regardless of file type, if it's a local file, same site or cross site.

It also seems to create a lot of garbage memory. Is there a way to prevent this?

Open DevTools and look at the networks tab while clicking the button in the example below.

const bounce = new Audio('https://www.w3schools.com/graphics/bounce.mp3');

function playSound() {
    bounce.play();
}

document.getElementById('bounce').addEventListener('click', playSound, false);
<button id="bounce">Play</button>
Will Pierce
  • 107
  • 6

2 Answers2

5

This appeared to be a known bug in Chrome that is now marked as "fixed". However, as of September 19, 2020, someone commented that is still occurring.

One possible workaround for this would be to include a "fake" icon in the head of your HTML. For example, the link element below:

<!DOCTYPE html>
<html>
<head>
    <link rel="icon" href="data:,">
    ... Rest of your HTML ...

This assigns an empty data URL to the favicon, and should prevent Chrome from automatically sending an HTTP request for it.

JoshG
  • 6,472
  • 2
  • 38
  • 61
  • This solves the issue but there's also the question if I should make my game less nice with no favicon for everyone just because of a bug in one browser. Web development is not fun anymore. – Will Pierce Oct 03 '20 at 07:36
  • You could try base64 encoding the favicon and using that in the `href` instead of the empty `data:,`, similar to this solution: https://stackoverflow.com/a/5199989 – JoshG Oct 03 '20 at 07:46
  • The base64 encoded favicon is the best compromise. Thank you :) – Will Pierce Oct 04 '20 at 02:25
1

After a lot of research, trial and error I "developed" a working solution.

When the problem happens? It seems that the favicon.ico request happens every time you play an audio, but actually not necessarily! It happens ONLY if the audio stopped and so it needs to start again. Not if it paused!

Solution. So what you need is to pause the audio before it plays to the end and stops by itself.

function play(audio) { // any normal instance of Audio element/tag
    audio.currentTime = 0;
    audio.play();
    setTimeout(() => audio.pause(), audio.duration * 999)
}

const bounce = new Audio('https://www.w3schools.com/graphics/bounce.mp3');

function playSound() {
    bounce.currentTime = 0;
    bounce.play();
    setTimeout(() => bounce.pause(), bounce.duration*999)
}

document.getElementById('bounce').addEventListener('click', playSound, false);
<button id="bounce">Play</button>
UniBreakfast
  • 55
  • 1
  • 7