Draw gray blocks matching the size and position of the real content, then swap in the actual content without moving anything once data arrives. That reduces sudden layout shift and, unlike a blank screen, lets people predict something is about to appear — which feels faster.
The difference from a spinner was covered above: a spinner only announces "loading," while a skeleton previews the future shape of the content. The soft left-to-right shimmer is made by animating a CSS gradient's background-position.
From an accessibility angle, the skeleton blocks themselves don't need to be read by a screen reader — mark them aria-hidden="true" — and announce the start/end of loading through a separate aria-live region instead.