<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Web Performance on Keyuki Blog</title>
    <link>https://blog.keyuki.net/tags/web-performance/</link>
    <description>Recent content in Web Performance on Keyuki Blog</description>
    <generator>Hugo</generator>
    <language>en</language>
    <lastBuildDate>Thu, 07 May 2026 22:30:00 +0900</lastBuildDate>
    <atom:link href="https://blog.keyuki.net/tags/web-performance/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>PageSpeed改善で、ブログ画像の役割を分けることにした</title>
      <link>https://blog.keyuki.net/posts/pagespeed-mobile-thumbnail-image/</link>
      <pubDate>Thu, 07 May 2026 22:30:00 +0900</pubDate>
      <guid>https://blog.keyuki.net/posts/pagespeed-mobile-thumbnail-image/</guid>
      <description>&lt;h2 id=&#34;点数は出たけど何が起きたのかわからなかった&#34;&gt;点数は出たけど、何が起きたのかわからなかった&lt;/h2&gt;&#xA;&lt;p&gt;&lt;a href=&#34;https://pagespeed.web.dev/&#34;&gt;PageSpeed Insights&lt;/a&gt; は、GoogleがWebページの読み込み速度を100点満点で評価してくれる無料ツールです。スマホでの表示速度（モバイル）とパソコンでの表示速度（デスクトップ）を別々に測定してくれます。&lt;/p&gt;&#xA;&lt;p&gt;昔々、ブックマークに入れていたものを掘り起こしたわけですね。&lt;/p&gt;&#xA;&lt;p&gt;このブログのモバイル版を測定したら、こんな数字が出ました。&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;strong&gt;Performance: 67&lt;/strong&gt;（100点満点。低いほど遅い）&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;LCP: 175.2秒&lt;/strong&gt;&lt;/li&gt;&#xA;&lt;li&gt;Speed Index: 5.5秒&lt;/li&gt;&#xA;&lt;li&gt;Total network payload: 39,910 KiB（約39MB）&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;&lt;strong&gt;LCP&lt;/strong&gt;（Largest Contentful Paint）は、ページを開いてから「一番大きなコンテンツ」が表示されるまでの時間です。175秒というのは、ほぼ「ページが完成しない」という意味になります。&lt;/p&gt;&#xA;&lt;p&gt;パフォーマンス67という点数は見れば悪いとわかりますが、最初は何を直せばいいのかよくわかりませんでした。&lt;/p&gt;&#xA;&lt;p&gt;調べてみると、原因はサーバーの遅さでも、JavaScriptのブロックでもありませんでした。&lt;strong&gt;トップページが大量の画像を読み込んでいた&lt;/strong&gt;のが問題でした。&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;トップページが約39mbあった&#34;&gt;トップページが約39MBあった&lt;/h2&gt;&#xA;&lt;p&gt;サーバー応答は速かったです。JavaScriptのブロックも致命的ではありませんでした。大きかったのは、ひたすら&lt;strong&gt;画像&lt;/strong&gt;でした。&lt;/p&gt;&#xA;&lt;p&gt;トップページには最新記事のカードが並んでいます。各カードには記事のアイキャッチ画像が表示されます。見た目は小さなサムネイルですが、裏では5MB前後のPNGファイルをそのまま読み込んでいました。カードが10枚あれば、それだけで50MB近くになります。&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;小さく表示しているから軽い、とは限らない。&lt;/p&gt;&lt;/blockquote&gt;&#xA;&lt;p&gt;ブラウザは &lt;code&gt;width&lt;/code&gt; を小さく指定されても、画像ファイルのサイズは変わりません。表示を縮小しているだけで、5MBのPNGは5MBのまま読み込まれます。&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;まず背景画像を軽くした&#34;&gt;まず背景画像を軽くした&lt;/h2&gt;&#xA;&lt;p&gt;最初に手をつけたのは、ヒーロー背景画像でした。&lt;/p&gt;&#xA;&lt;p&gt;ヘッダーに使っている &lt;code&gt;hero-background.jpg&lt;/code&gt; が&lt;strong&gt;約7.6〜7.9MB&lt;/strong&gt;ありました。見た目はきれいですが、7MBは明らかに過剰です。&lt;/p&gt;&#xA;&lt;p&gt;これを&lt;strong&gt;WebP&lt;/strong&gt;（ウェブピー）形式に変換しました。WebPはGoogleが開発した画像フォーマットで、JPEGやPNGより同じ見た目で大幅にファイルサイズを小さくできます。変換後は&lt;strong&gt;約283KB&lt;/strong&gt;になりました。同じ見た目で、ファイルサイズが約1/27になる計算です。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;background-image: url(&amp;#39;/images/hero-background.webp&amp;#39;);&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;背景画像の変換を含むいくつかの修正をまとめてデプロイしたあと、この段階で計測し直しました。&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Performance: 67 → &lt;strong&gt;75&lt;/strong&gt;&lt;/li&gt;&#xA;&lt;li&gt;LCP: 175.2秒 → &lt;strong&gt;5.0秒&lt;/strong&gt;&lt;/li&gt;&#xA;&lt;li&gt;Total network payload: 39,910 KiB → 32,419 KiB&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;LCPは大きく改善しました。ただ、ペイロード（ページ読み込みに必要なデータの総量）はまだ32MBあります。トップページの記事カード画像がほぼそのまま残っていたからです。&lt;/p&gt;&#xA;&lt;hr&gt;&#xA;&lt;h2 id=&#34;lazy-loadingだけでは足りなかった&#34;&gt;lazy loadingだけでは足りなかった&lt;/h2&gt;&#xA;&lt;p&gt;背景画像の変換と並行して、記事カードのテンプレートに &lt;code&gt;loading=&amp;quot;lazy&amp;quot;&lt;/code&gt; と &lt;code&gt;decoding=&amp;quot;async&amp;quot;&lt;/code&gt; も加えました。&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-html&#34; data-lang=&#34;html&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;&amp;lt;&lt;span style=&#34;color:#f92672&#34;&gt;img&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;src&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;{{ .Permalink }}&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;loading&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;lazy&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;decoding&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;async&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;width&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;760&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;  &lt;span style=&#34;color:#a6e22e&#34;&gt;height&lt;/span&gt;&lt;span style=&#34;color:#f92672&#34;&gt;=&lt;/span&gt;&lt;span style=&#34;color:#e6db74&#34;&gt;&amp;#34;424&amp;#34;&lt;/span&gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;/&amp;gt;&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;それぞれの意味はこうです。&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
