This has been frustrating me for years.  My CSS fix sets a background image on the img. When a dynamic image src doesn't load to the foreground, a placeholder is visible on the img's bg.  This works if your images have a default size (e.g. height, min-height, width and/or min-width).
You'll see the broken image icon but it's an improvement.  Tested down to IE9 successfully.  iOS Safari and Chrome don't even show a broken icon.
.dynamicContainer img {
  background: url('/images/placeholder.png');
  background-size: contain;
}
Add a little animation to give src time to load without a background flicker.  Chrome fades in the background smoothly but desktop Safari doesn't.
.dynamicContainer img {
  background: url('/images/placeholder.png');
  background-size: contain;
  animation: fadein 1s;                     
}
@keyframes fadein {
  0%   { opacity: 0.0; }
  50%  { opacity: 0.5; }
  100% { opacity: 1.0; }
}
.dynamicContainer img {
  background: url('https://picsum.photos/id/237/200');
  background-size: contain;
  animation: fadein 1s;
}
@keyframes fadein {
  0% {
    opacity: 0.0;
  }
  50% {
    opacity: 0.5;
  }
  100% {
    opacity: 1.0;
  }
}
img {
  /* must define dimensions */
  width: 200px;
  height: 200px;
  min-width: 200px;
  min-height: 200px;
  /* hides broken text */
  color: transparent;
  /* optional css below here */
  display: block;
  border: .2em solid black;
  border-radius: 1em;
  margin: 1em;
}
<div class="dynamicContainer">
  <img src="https://picsum.photos/200" alt="Found image" />
  <img src="https://picsumx.photos/200" alt="Not found image" />
</div>