ムラウチドットコム エンジニアブログ

日本最大級ブログランキング「にほんブログ村」、シンプルなブログサービス「muragon」を運営するムラウチドットコム メディアグループのエンジニアブログです。

異常な速さと話題のdev.to この素晴らしい体験はどうやって実装されたのか

最近話題になったプログラマのコミュニティサイト dev.to
何がそんなに話題になったのでしょうか?



百聞は一見にしかず、試しに上のリンクを押して頂くと分かると思います。
記事ページやカテゴリページのリンクを適当に押してもらい、遷移してもすぐに表示されるのが分かりますでしょうか?


twitterでも話題になり、一時期は日本のトレンド1位になっていました。



dev.to の管理者のBen Halpernさんが、記事を書いてくれていますのでこちらを読み解いてみます。面白いタイトルですね。


※注意

Google翻訳を利用しての意訳となります。
間違っている可能性もございますので、参考程度にご覧ください。


dev.to の速度は努力の賜物?

冒頭ではこのように述べられております。

From the beginning, the idea was that if we could make everything insanely fast, every other UX consideration was going to be a lot easier going forward. Performance of a webpage is the most important UX consideration for me. Nobody wants to spend their time staring at a blank screen.

But speed is not free. In order to ensure performance, a project must have a set of reasonable constraints. Focusing on performance early helped map out the site's architecture to fit within the constraints that ensure great time-to-render speeds. Future decisions are less likely to have to weigh performance, because the performance consideration is center to the whole structure of the website.

I believe a big part of this project's success has been because I had a pretty good grasp of the top-to-bottom problem and how to implement it.

  1. 表示速度は何よりも重要なUX(User Experience: ユーザー体験)
  2.  パフォーマンスを中心に設計
  3.  それにより今後の変更による影響が少なくなった
  4.  問題点と対応方法を十分に把握できていた

意訳ではありますがまとめるとこんな感じでしょうか。
彼らはどのような設計をしたのかを次にみてみます。

設計の制約

For dev.to, I took to thinking that this is a very read-heavy application, and there was a great opportunity to perform a lot of caching. It was an opportunity to be fairly minimalist in features and min-max the hell out of what's important: Content consumption.

Fundamentally, maximizing web performance is about caching and latency mitigation. This application is a series of blog posts. There is a lot of dynamic read-write action any time a post is updated or a comment is made, etc. But most of the behavior is that of a user coming to the site, reading, or glancing over the content, and leaving. In order to best service this behavior, we make good use of edge caching.

We use Fastly for our CDN edge-caching needs. We really like their service. Full disclosure, Fastly is now a sponsor of ours, but we made that happen because we love them, not the other way around.

  1. アプリケーションについての理解を深める
  2. dev.toは読み込みの重いアプリケーションなので、キャッシュを有効活用する
  3. 基本的にWebアプリケーションの最適化は、キャッシングとレイテンシの低減
  4. 記事作成や更新の操作もあるが、殆どはユーザの読み込みがメイン
  5. CDNサービスのFastlyを利用し、キャッシュを返すようにした

具体的なサービス名として、CDNのFastlyが出てきましたね。


最近ですと、日経新聞さんのサイトでも利用されていてその速度に騒然としていましたね。
キャッシュの即時消去(インスタント・パージ)ができる為、動的コンテンツでもキャッシュが出来る話題のCDNになります。

最初のページ要求

A typical request first returns a fully-cached, pre-gzipped HTML page served from the closest Fastly node if one is available. Additional "dynamic" info, such as which comments you've liked, etc. go through a second, lightweight, request that hits the application database and returns the relevant information.

  1. ページ要求に対して、近くのfastlyノードからgzipされたHTMLページを返す
  2. コメント等の動的な情報は、軽量なリクエストを送る

gzip圧縮されたHTMLページを、エッジサーバーにキャッシュしておき、頻繁に変わる箇所は非同期で取得しているようです。



確認してみると、非同期で動的な箇所は取られていますね。何故か2回以上送られているようですが。

レンダリングをブロックするスタイルとスクリプトを削除する

レンダリングブロックや同期スクリプトに関しては、以下のように書かれています。

Once a page is delivered the next important detail is rendering it as quickly as possible. This, in my opinion, is where a lot of sites, even ones serving totally static content from the edge via a CDN, often fall short. The key to improving render times is to eliminate all render-blocking latency. That means no external CSS requests, no custom fonts, and no synchronous Javascript.


Yes, all the CSS relevant for the initial render come over the wire in a <style> tag, and no part of the page's structure is dependent on any Javascript execution. This ensures that even when a user comes to the site with a totally clear cache, they still see all the site's content virtually instantaneously. All the site's style logic is organized into stylesheets as per convention, and make use of SCSS for convenience and cleanliness, but relevant CSS is printed to the page at runtime, and everything is, of course, cached on subsequent requests.


Images are automatically optimized for compression and served from the most efficient format depending on the browser (webp for Chrome, jpeg for Safari, etc.). This is a service provided by Cloudinary. Cloudinary also fully leverages HTTP2 where possible so we do not have to think about it.

  1. レンダリング時間の改善は、レンダリングブロッキングレイテンシを排除する事
  2. その為、外部CSSリクエストやカスタムフォント、同期JSは一切ない
  3. 初期レンダリングの全ては<style>タグ内に全て記載されている
  4. ページ構造の一部はJSの実行に依存しない
  5. これによりクリアなキャッシュのユーザが閲覧しても瞬時に表示がされる
  6. 画像はブラウザにより効率的な形式で配布をしている。Chromeの場合はwebp、Safariの場合はjpegなど
  7. 画像圧縮、配信はCloudinaryを利用している
  8. 上記対応の結果、素早くレンダリングが行われる
  9. この対応はCDNを利用して静的コンテンツを配信しているサイトでさえ、対応が不十分に思われる箇所

長くなってしまいましたが、このようなことが書かれているようです。すごい意訳なので粗い部分がありますがご容赦ください。


レンダリングブロックの排除、画像の最適化を行なっているとのことですが、実際にソースをみるとその意味が分かるかと思います。


今では外部CSSやカスタムフォントを多用し、リッチなサイトを構築するのはよく目にしますが、その弊害としてレンダリング時の遅延にも繋がっていました。
dev.to ではそれらを一切排除しパフォーマンスに当てているようです。


他にもServiceWorkerも利用しての速度改善も行なっているようですね。

結論

Performance on the web is the most important user experience consideration. When people click a link to this site, I don't want them to habitually go to another tab while the page loads.

I want our readers all over the world to have the same lightning-quick page request times regardless of their devices, networks, and distance from our main region. I want developers who put their blog posts up on our site to trust that we are continuously drilling to improve the important parts of user experience.

  1. Webでの表示速度は最も重要なUXの考慮事項だ
  2. ユーザーがこのページを読み込み中に、他のタブに行かないようにしたい
  3. 世界中の人が、地域、デバイス、ネットワークに関わらず、雷のような速度で表示できることを願っている

まとめ

初めてdev.toを見た時、何か未知の技術を使っているかと思ったのですが、
Ben Halpernさんの記事を読むとそうではない事がわかりました。

It makes me smile when someone raves about how fast this website loads, because that's no accident. We put a lot of effort into making it so.

一番最初に彼はこのように書いております。
私たちはこのようにするために多大な努力をしてきたと。
CDN、画像最適化、レンダリングブロックの排除などを地道に行いここまでの速度を実現できたのです。


当社でもそのような感動を届けられるようなサービスを作るために努力を惜しまないようにしていきたいです。



×

非ログインユーザーとして返信する

あと 2000文字

※は必須項目です。