5
2

Image.onloadはやめてImage.decodeを使おうね

Last updated at Posted at 2024-01-11

TL;DR;

タイトルの通りで、古典的なImage.onloadよりImage.decode使おうね
2024年なら、という話です

そもそもImage.onloadってなに?

const image = new Image();
image.src = 'hoge.jpg'
image.onload = {
    //読みこまれたら実行するよ
}
// なんかしら処理

画像ファイルが読みこまれたらonloadイベントが呼ばれて、なんか処理をするというやつです
動的に画像をどうこうするコードでは誰もが使うやつですよね

Image.decodeとは?

やってることは同じですがdecode()はPromiseを返します
https://developer.mozilla.org/ja/docs/Web/API/HTMLImageElement/decode

const img = new Image();
img.src = "nebula.jpg";
img
  .decode()
  .then(() => {
    document.body.appendChild(img);
  })
  .catch((encodingError) => {
    // エラー時に何かをする。
  });

コードはMDNのやつのコピペな

どうしてdecodeの方がいいの?

人間の脳にとってイベント処理は複雑すぎるからです
たとえばこちらのコードの実行順序を把握できるでしょうか?

const image = new Image();
image.src = 'hoge.jpg'
image.onload = {
    // 2読みこまれたら実行するよ
    // こちらはあとで処理される。つまり
    console.log('画像がよみこまれたら実行されるよ')
}
// 
console.log('こちらが先に処理される')

読みこんだあとの処理はonloadで書かれるので、コードの実行フローが下にいってまたもどることになります
読みこんだときの処理と読みこんでない状態の処理をきちんと意識しないと不具合を起こします

ではdecodeでは?となるのですが、async/awaitつかうと話がかわります

const loadImage = async() => {
    const img = new Image();
    img.src = "nebula.jpg";
    try {
        await img.decode()
        document.body.appendChild(img);
    }catch(encodingError){
        // エラー時に何かをする。
    }
}
loadImage()

loadImageのなかでは

  • ファイルを読みこむ
  • 読みこんだらなんかする
    という処理が上から下にながれます。この方が読みやすいし間違いがないですね

イベントモデル vs Promise

もともとJavascriptにはイベントモデルしかなかったわけですが、今はPromise時代に生きてるわけですので、そちらが使えるところでは使わないといけないし、理解していないと火傷しますね
(これの理解の不足で障害とかやらかしてますよね、きっと)

まとめ

この記事は画像の動的読みこみを調べると古典であるonloadが基本的にヒットしてくるのでdecodeをつかうといいですよ、という目的のために書かれました

おまけ

new Promise((resolve, reject) => {
  const img = new Image();
  img.onload = () => resolve(img);
  img.onerror = (e) => reject(e);
  img.src = 'hoge.jog';
})

アーニャなみだでる

5
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
2