本番のサイトを眺めていて、「あーここのHTMLこうしたら、もっと速くなるのになー」って思う時ありますよね。
僕はあります。でも、検証するだけのために、プロダクトのコードを直接いじるのは大げさ。
そんな時に、wget
とmirror
というコマンドを使ってページをダウンロードして「ほんの少し」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の数削ったらスコアが上がるかな。
- などなど
そんな時に、最近はwget
かmirror
コマンドを使って「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 Web Debugging Proxy • HTTP Monitor / HTTP Proxy / HTTPS & SSL Proxy / Reverse Proxy
- Chromeの「Local Overrides」機能
同じ用途で「自分はCharlesを使っている」という方がいらっしゃいました。 ローカルでプロキシを実現するソフトですね。こちらが参考なります。
- CharlesのMap Localを使って、Webサイトオープン後にJSやCSSの開発をする | MUSHIKAGO APPS MEMO
- プロキシアプリで開発をスムーズに | 前編 Charlesの基本 | CodeGrid
「Local Overrides」は知りませんでした。
見た感じmirror
+http-server
と同等のことがブラウザでできるっぽいですね。試してみたいです。
追記2(Local Overrides)
Local Overridesすごいです。Chrome上のDevTools上で、HTMLを直接書き換えて、保存してリロードすると内容が書き換わっています。これこそやりたいことでした!
- Chrome DevToolsを開く。
- 「Source」=>「Overrides」。
- リソースを保存するフォルダを指定する。
- 「Network」から変更したいHTMLやCSSなどを選択。
- 右クリックして「Save for Overrides」。
- 「Source」画面に遷移。エディタで編集できる。
- 保存してリロード。
- ページが変更されている!
まとめ
以上、「ほんの少し」HTMLを変更して試したい時にwget
とmirror
コマンドを使って、1ページだけミラーリングしているという話でした。
実際、僕は速度高速化・CWVの改善に取り込んでいるものの、プロダクトのコードをいじることは少ないです。 なので例で挙げた通り、気になるところがあっても検証しないまま、他のエンジニアに指摘するだけになってしまっていました。 この方法なら、自分だけで検証まで超簡単にできちゃうのでとてもよいです。
エンジニア募集中!
トラベルブックではエンジニアを募集中です。 ページの高速化やCore Web Vitalsの向上を試しているので、よろしくれば一緒にやりましょう!