has_rich_text :content
これで文章、画像などもcontentカラムに埋め込めるわけですが、
生のcontentのデータはhtml(imgタグなど)そのものではなく、画像などの埋め込み情報(どのテーブルのどのidなのか)を持っているだけです。
そして生のhtmlコードを作るにはcontent.to_s
を呼ぶ必要があります。
def full_content
self.content.to_s
end
こういうコードを書いてる人も多いでしょう。
1つのレコードの1つのcontentカラムに多数の画像を埋め込むこともあります。
1記事に20枚の画像があれば、20の画像(blob)インスタンスが作られます。
そして各画像をvariantでリサイズ、圧縮やwebpなど生成している場合は、
content.to_s
が呼ばれると、20回、variantが存在するのかを確認しにいきます。
"既にvariantが存在する"というフラグなどをテーブルに突っ込めばいいのに、毎回gcpやawsなどにアクセスします。
1回あたり40msくらいかかります。20回行えば800msです。
たとえば30レコードの記事を一括でjsonでとってくる必要があり、1記事で20の画像がある場合、
content.to_s
が30回呼ばれ、それぞれのcontent.to_s
の中でvariant checkが20回行われ、
合計600回variant checkが走ります。
それで24000ms = 24秒かかります。
解決策としては、
- 1回content.to_sを呼んだらstatic_full_contentカラムなどにその結果を保存しておく。contentが上書きされるたびに、after_saveなどでフックしてstatic_full_contentに結果を保存するようにする。一番速くなる。
- application.rbに
config.active_storage.track_variants = true
を追記して、variantが存在することをテーブルに保存する。
2の解決策が楽です。
毎度のことながら、自分のメモでゴミのような文章ですね。明日自分で読んでも意味わからないでしょう。