Svelteでifの条件分岐で画像表示がチラつく場合の解決方法

ifで非表示にした画像は読み込まない

Svelteでifの条件分岐で非表示の画像の表示をすると表示時にチラつくことがあります。

これはifで非表示にした画像は読み込まないことが原因です。

例えば以下のようなカルーセルの場合は最初の画像のみを読み込むため、それ以外の画像を表示させた際に画像の読み込みが発生するためチラつきます。

<script>
  let images = [
    'https://dummyimage.com/300x200/ccc/000&text=1',
    'https://dummyimage.com/300x200/ccc/000&text=2',
    'https://dummyimage.com/300x200/ccc/000&text=3',
    'https://dummyimage.com/300x200/ccc/000&text=4',
    'https://dummyimage.com/300x200/ccc/000&text=5'
  ]

  let current = 0

  const next = () => {
    current = (current + 1) % images.length
  }

  const prev = () => {
    current = (current - 1 + images.length) % images.length
  }
</script>

<div class="carousel">
  {#each images as image, i (i)}
    {#if i === current}
      <div class="carousel-item">
        <img src={image} width="300" height="200" alt="">
      </div>
    {/if}
  {/each}
</div>
<hr>
<button on:click={prev}>Previous</button>
<button on:click={next}>Next</button>

Svelteで画像表示時にチラつくサンプル

ChromeのNetworkを見ると表示されている1枚目しか読み込んでいないことがわかります。

Svelteでifの条件分岐で画像表示がチラつく場合の解決方法

ifで非表示にした画像をプリロードする

ifで非表示にした画像が読み込み時にチラつく問題は以下のようにプリロードの処理を入れておけば解決します。

<script>
  let imageUrls = [
    'https://dummyimage.com/300x200/ccc/000&text=1',
    'https://dummyimage.com/300x200/ccc/000&text=2',
    'https://dummyimage.com/300x200/ccc/000&text=3',
    'https://dummyimage.com/300x200/ccc/000&text=4',
    'https://dummyimage.com/300x200/ccc/000&text=5'
  ]

  let images = imageUrls.map(url => {
    const img = new Image()
    img.src = url
    return img.src
  })
  let current = 0

  const next = () => {
    current = (current + 1) % images.length
  }

  const prev = () => {
    current = (current - 1 + images.length) % images.length
  }
</script>
<h1>Svelteで画像表示時にチラつくサンプル</h1>
<div class="carousel">
  {#each images as image, i (i)}
    {#if i === current}
      <div class="carousel-item">
        <img src={image} width="300" height="200" alt="">
      </div>
    {/if}
  {/each}
</div>
<hr>
<button on:click={prev}>Previous</button>
<button on:click={next}>Next</button>

Svelteで使用する画像をプリロードするサンプル