2022/02/18

ほんの少しHTMLを変更して検証したい時

本番のサイトを眺めていて、「あーここのHTMLこうしたら、もっと速くなるのになー」って思う時ありますよね。 僕はあります。でも、検証するだけのために、プロダクトのコードを直接いじるのは大げさ。 そんな時に、wgetmirrorというコマンドを使ってページをダウンロードして「ほんの少し」HTMLを変更しています。 紹介します(追記にLocal Overridesという「そのものズバリな」Chromeの機能も紹介してます)。

ほんの少しHTMLを変更して検証したい時

最近あった話です。特にCore Web Vitalsとか速度改善について。

トラベルブックのとあるページのスコアが落ちていて、Chrome DevToolsで観察してみると、どうもYouTubeの埋め込が足を引っ張っている。 表示領域外にも関わらずiframeの中身がロードされています。 これは直したい(本来なら本番へ上げる前に気づく仕組みを作りたいのですが、一旦置いておきます)。

Chromeなど対応しているブラウザではiframe要素にloading=lazy属性を付加してあげれば、遅延読み込みをしてくれます。 じゃあすぐにHTMLタグを書き換えて、ネットワークの様子を見て検証したいものですが、そうはいかないことがあります。 プロダクトのコードをいじる権限がなかったり、すぐに環境を用意するのが難しかったりします。 また、例えばAPIサーバーのレスポンスを書き換えなくてはいけなかったり。 エディタでHTMLを編集するだけで終わることが、億劫になることがあるのです。

「ほんの少し」HTMLを変更して検証したい時は他にもあります。

  • LCPの画像をResouce Hintでpreloadしたらどうだろう。
  • Width/Heightを指定したらCLSの点数はどれほどあがるだろうか。
  • 画像のURLをwebpのものにしたらどうだろう。
  • 広告が足を引っ張ってるから、「なし」の時と「あり」の時を比べてみよう。
  • いっそDOMの数削ったらスコアが上がるかな。
  • などなど

そんな時に、最近はwgetmirrorコマンドを使って「1ページだけ」ミラーリングしたHTMLをいじっています(繰り返しますが、後述するChromeのLocal Overridesを使うやり方もあります)。

wget

wgetはご存知の通り、コマンドラインのHTTPクライントです。

--mirrorというその名もずばりなオプションがありますが、何も考えずにつけるとサイト全体をミラーしてしまうので、今回はつけません。 実用的なのは以下のコマンドです。僕の個人ブログで試してみましょう。

$ wget -p -k -E --user-agent='iPhone' https://yusukebe.com/posts/2022/rj-and-t/
  • -p 必要な画像やCSSリソースもダウンロードする。
  • -k パスを相対パスに変換する。
  • -E 拡張子をつける。
  • -user-agent ユーザーエージェントを指定する。

HTMLだけではなくアセットも一緒にダウンロードして、表示崩れがないようにパスの書き換えまでする、というのがポイントです。

これで手元に対象ページのHTMLと画像とCSSが手に入るので、そのディレクトリまで行って静的ファイルサーバーを立ち上げます。 今回は http-server を使いました。

$ cd yusukebe.com
$ http-server

ちゃんのとlocalhostでページが配信されています。HTMLは手元にあるので、 VSCodeなりvimなりemacsなりお好きなエディタで書き換えて、結果を見てみましょう。

mirror

しかし、スクショを見てお気づきの通り、これでは画像がうまく取得できていません。 ローカルサーバー上でも404になっています。

この画像はamp-imgを使って、非同期で読み込んでいるので、静的にHTMLをダウンロードするwgetでは画像の取得ができないのです。 そこで拙作のmirrorコマンドを使ってみましょう。

このmirrorコマンドは上記のwgetとほぼ同じ挙動を見せますが、以下のような特徴があります。

  • 内部でヘッドレスChromeを使っている。
  • JavaScriptでレンダリングした結果のHTMLをダウンロードする。
  • amp-imgなど遅延読み込みしたリソースにも対応。
  • スクロールしないと読み込まれないリソースにも対応。
  • Gzip/Brotliの圧縮を解凍。

ということで、wgetでもいいのですが、mirrorコマンドを使えば、ほぼ本番と同じページを再現できます。

 $ mirror -A iPhone https://yusukebe.com/posts/2022/rj-and-t/

amp-imgで読み込んでいる画像もダウンロードしてますね。

画像が見えてます。

お手軽にチューニングをする

試しに、このページをチューニングをしてみます。というよりも、「チューニングできるか検証する」といった方が正しいでしょうか。 といっても「ほんの少し」HTMLを変更するだけです。

このページのLCPはこの画像なのですが、AMP関係のJavaScriptの読み込みが終わってからダウンロードが始まります。

これを真っ先にロードすることはできないでしょうか。 リソースヒントというテクニックを使ってみましょう。 headタグの中でpreloadを指定します。

<link
  rel="preload"
  href="http://localhost:8081/posts/2022/rj-and-t/ss01_huece009c54c296d4f9d95475813deb5cc_1010982_1200x0_resize_box_3.png"
  as="image"
/>

ローカルのHTMLを編集するだけなのですぐ終わりますね。 ではブラウザで確認してみましょう。

お、読み込みの順番が変わって、HTMLの次に読み込まれています。

この結果をどう見るか、リソースヒントを導入するかはさておき、お手軽にHTMLを編集して、その効果を見ることができました。

追記

はてなブックマークのコメントで以下2つを教えてもらいました。

同じ用途で「自分はCharlesを使っている」という方がいらっしゃいました。 ローカルでプロキシを実現するソフトですね。こちらが参考なります。

「Local Overrides」は知りませんでした。 見た感じmirror+http-serverと同等のことがブラウザでできるっぽいですね。試してみたいです。

追記2(Local Overrides)

Local Overridesすごいです。Chrome上のDevTools上で、HTMLを直接書き換えて、保存してリロードすると内容が書き換わっています。これこそやりたいことでした!

  1. Chrome DevToolsを開く。
  2. 「Source」=>「Overrides」。
  3. リソースを保存するフォルダを指定する。
  4. 「Network」から変更したいHTMLやCSSなどを選択。
  5. 右クリックして「Save for Overrides」。
  6. 「Source」画面に遷移。エディタで編集できる。
  7. 保存してリロード。
  8. ページが変更されている!

まとめ

以上、「ほんの少し」HTMLを変更して試したい時にwgetmirrorコマンドを使って、1ページだけミラーリングしているという話でした。

実際、僕は速度高速化・CWVの改善に取り込んでいるものの、プロダクトのコードをいじることは少ないです。 なので例で挙げた通り、気になるところがあっても検証しないまま、他のエンジニアに指摘するだけになってしまっていました。 この方法なら、自分だけで検証まで超簡単にできちゃうのでとてもよいです。

エンジニア募集中!

トラベルブックではエンジニアを募集中です。 ページの高速化やCore Web Vitalsの向上を試しているので、よろしくれば一緒にやりましょう!