SE_BOKUのまとめノート的ブログ

SE_BOKUが知ってること・勉強したこと・考えたことetc

Webフロントエンドとサーバーサイドの技術動向をざっくり整理する/JavaScript

f:id:arakan_no_boku:20190412202924j:plain  

目次

はじめに

Web開発で「フロントエンドはモダンな感じでやりましょう。jQueryではなしに。」ということになったのですが、その時の僕は「モダンな感じ」なるものが示す「最新の技術動向」に疎くて話についていけませんでした、。

反省し、WEBフロントエンドとサーバーサイドあたりの技術動向のアウトラインをざっくりと整理してみることにしました。

よくよく話を聞いてみると、Webフロントエンド周りのHOTな話題の中心は、「クライアントサイドレンダリング」とか「サーバーサイドレンダリング」とかのHTMLレンダリングの話題のようです。

まずは、HTMLレンダリングのそもそもからですね。

HTMLレンダリング 

HTMLレンダリングは「HTMLを解釈し、文字や画像などの配置を計算して画面に表示する」ことで、広義には以下の2通りの方法があります。

それぞれを見ていくと。 

HTMLレンダリング :ブラウザでHTMLを受け取り画面表示 

ブラウザに届いた時点では、既にHTMLが構成されているパターン。

昔からお馴染みの・・やり方です。

HTMLは生成の仕方でざっくり2通り。

  • 最初から書いてある「静的HTML」
  • レスポンスを返す都度プログラムでHTML生成する「動的HTML」

です。

ただ。

動的にHTMLを生成する場合も、サーバー側でHTMLを生成するわけなので、ブラウザ側から見れば、リクエストを送って、サーバーからHTMLをとってくるという点では同じことになります。

f:id:arakan_no_boku:20190413002537j:plain

HTMLレンダリングJavaScriptレンダリングして画面表示

ブラウザ・・つまりクライアント側でJavaScriptを動かして画面描画を動的に実行する方法です。

非同期通信でリクエストして、結果をHTMLではなく、JSON等のデータで結果を受けて画面の部分更新をする処理がそうで、ざっくり、図にするとこんな感じですかね。

f:id:arakan_no_boku:20190413003148j:plain

HTMLレンダリング :WEBページの初期表示の各段階

HTMLにせよ、JSON等データで受け取るにせよ、最終的にはブラウザで表示します。

当然、表示は速やかに(レスポンスよく)できることが必要です。

でも。

すべての画面が一瞬で表示できる・・なんてわけはありません。

初期表示するための段階(ステップ)があります。

その初期表示の各ステップの呼び方と意味を整理しときます。

f:id:arakan_no_boku:20190412224800j:plain

各ステップの意味はこんな感じ。

  • Navigation Start:サーバーへリクエストします。
  • First Contentful Paint:ロケーションインジケータがぐるぐる回る段階です。
  • First Meaningful Paint:意味のある情報が表示されます。(画像等はまだです)
  • Visually Ready:画像などが読み込まれてレイアウトされます。
  • Time to interactive:JavaScriptがロードされ実行可能になります。
  • Fully Loaded:すべてが読み込まれて操作可能になります。

WEBページが表示される時にいつも見ているアレです。

日本語で言いなおすと

  1. 真っ白な画面からインジケータがまわる
  2. 文章と枠が表示される
  3. 画像が表示される
  4. スクリプトがロードされて動的な部分が動くようになる
  5. すべてが読み込まれて操作できる

ですかね。

レスポンスの改善の話をするとき、どのステップまでを高速化するか・・なんて話題になることがあります。

その時にこの各ステップの名称をさらっと言えると、なんかカッコ良さげ(笑)です。

一般的に。

静的HTMLで読み込んでページを表示するなら「First Meaningful Paint」迄をいかに速くするか・・が焦点になるそうです。

対して。

動的にページを表示する方によせるならJavaScriptの実行速度命になるので「Time to interactive」まですっ飛ばして、JavaScriptのロード時間をいかに短くできるか・・なんてことが焦点になるみたいです。

こうなると、JavaScriptの外部ライブラリとかのファイルサイズなんかもロードの時間にきいてくるので、jQueryが最近肥大化してきて・・うんぬん・・の話がでてくるわけですね。

サーバーサイド側の処理

クライアントサイドとかサーバーサイドとかの話を整理する時、避けて通れない話題がもうひとつあります。

Webアプリケーションであるかぎり、どこでレンダリングしようと、レスポンスの返し方が違おうと、サーバーサイドで処理を行い、レスポンスを返すプログラムが必要なんだということです。

この、サーバーサイドで使うプログラム言語の主流は、長らく、JavaScript以外の言語・・例えば、PHPJAVAPythonDjango)、RubyRails)なんか・・でした。

f:id:arakan_no_boku:20190420141236j:plain

でも。

クライアントサイド(つまりブラウザ)では、HTML・CSSJavaScriptなわけですから、クライアントサイドとサーバーサイドで別のプログラム言語やフレームワークを覚えないといけなかったわけです。

これだけ覚えることが多いと、学習も大変です。

なので。

クライアント側とサーバー側の言語を統一できるようサーバーサイドでJavaScriptを動かせる環境が登場し定着し、クライアントもサーバーサイドも「JavaScript」一本で書くことが可能になりました。

その代表格が「Node.js」です。

f:id:arakan_no_boku:20190413004026j:plain

サーバーサイド側:Node.jsという実行環境&開発環境

この「Node.js」ってのが、最近のWebフロントエンドやサーバーサイドの話題を理解しようとしたときの肝みたいなんですね。

Node.jsを一言でいうと「Google V8 JavaScript Engineで動作するJavaScriptの実行環境」なわけです。

Node.jsがあれば、ブラウザを使わなくても、JavaScriptが実行できるので、サーバーサイドの処理もJavaScriptで書けるようになったわけです。

とはいえ、JavaScriptは基本シングルスレッドのはずです。

それを、PHPとかJAVAみたいに複数のリクエストをマルチスレッドで受けられるようにしてるのかと思うと・・そうではなく。

データベースの問い合わせなどの待ちが発生する場合、待たずに次の処理に移るノンブロッキングI/Oを使い、結果の受け取りはコールバックで実現するという技を使ってます。

それで、シングルスレッドのままでサーバー処理を実現させるだけではなく、ノンブロッキングI/Oによって、Node.jsを使用するだけでC10K問題(サーバーへの接続数10000を超えると遅くなる問題)が解決できるなどの大きなメリットまで生み出してます。

かつ。

ローカルPCにインストールすればJavaScriptの開発環境・テスト実行環境としても使えるわけです。

高機能なパッケージ管理ツール「npm」など周辺ツールも充実しているので、JavaScriptの開発環境としても、Node.jsはかなり強力です。

おかげで。

Node.jsをベースにしたライブラリやツール・アプリが一気に増え、今では、最近のJavaScript周りの話題では特に書いてなくても、Node.jsがインストールされていることが前提・・みたいになってますね。

このあたりが、jQuery位でとまってて、Node.jsのことを理解していない人間にとって、最近のJavaScript関連の記事を読んでもピンとこない原因になったりしてたのだな(ちょっと前の自分のことです・・笑)と、なんか納得です。

クライアントサイトレンダリング

さて。

やっとこさで「クライアントサイドレンダリング」です。

これが「ブラウザ側でJavaScriptで都度画面描画する方法に比重を置くやり方」であるのは、字を見ればわかります。

非同期処理が簡単にJavaScriptでプログラムできるようになりました。

ブラウザのスクリプト実行エンジンが進化して、JavaScriptの実行もものすごく速くなりました。

だから。

毎回、サーバーで処理した結果をHTMLで受け取って全体を再描画するのではなく、JSON等でデータだけ受け取り、クライアント側のJavaScriptで差分描画させる割合を大きくすることでユーザが体感するレスポンスが向上させよう。

そういう考え方がでてくるのは・・当然といえば当然です。

たとえば。

デスクトップアプリのような快適な操作性が提供できるという売り文句の「SPA(Single Page Application)」は、その代表格です。

SPAは、最初にページの枠を表示してからは、非同期通信でデータだけ受取り、JavaScriptで画面の差分だけを更新するやり方です

画面全体のHTMLの解析・表示処理せず、初期表示のステップを一気に「Time to interactive」まですっ飛ばすことで、高速化をはかる感じですね。

クライアントサイトレンダリング:リアルDOMと仮想DOM 

クライアントサイドレンダリングに重点を置くということは、JavaScriptで沢山の画面要素をガリガリと描画することになります。

ここで避けて通れないのが、DOM(Document Object Model)です。

DOMは、HTMLの各タグ(要素)をノードとみなして、入れ子構造を階層構造で表現するモデルに変換することで、HTMLをJavaScript等で扱えるようにした素晴らしい技術です。

なんですけど・・。

この「DOM」は結構複雑です。

素のJavaScriptjQueryとかで、ガシガシやるには、プログラマがDOM構造を意識する必要があって、正直、面倒くさいし、ソースコードもごちゃごちゃと長くなってメンテナンス性も悪い・・ということになりがちでした。

実際、自分らがjQuery等をピンポイントでしか使ってなかった理由もそれです。

そこで。

それを解決するための「仮想DOM」という技術をとりいれたJavaScriptフレームワークが今の主流です。

超有名な「Angular」「React」「Vue.js」あたりがそうです。

(実際はもっといろんな機能がついてますけど、一旦、整理の都合上「仮想DOM」の部分だけに絞ります。)

仮想DOMは、実際のDOMを構築する前に、バーチャルなDOMを構築するワンクッションを入れることで、プログラマがDOMを意識ないで済むようします。

さらに、バーチャルなDOMを構築する際に差分更新する仕組みをとることで画面更新を高速化できたりします。

これは、非常に有益な技術とみなされていて、最近では「仮想DOM」という名前もすっかり定着し、仮想DOMと区別するため、今までのDOMが「リアルDOM」と呼ばれることも多くなってます。

サーバーサイドレンダリング

仮想DOMの技術と優れたJavaScriptフレームワーク(「Angular」「React」「Vue.js」など)で、クライアントサイドレンダリングの可能性が、一気に広がりました。

でも。

ここでちょっと考えないといけないことがでてきてしまったわけです。

それは、SEO面で不利になる可能性がある点です。

Googleのクロールは進化してて、JavaScriptも実行できるので、クライアントサイドでJavaScriptでHTMLを生成するようなページでも、ちゃんとインデックスできる。

そんな話のはずでした。

ところが、必ずしも、そうではないみたいなのですね。

www.suzukikenichi.com

Googleの人が「SEO的にはサーバーサイドレンダリング(この記事で言う「プリレンダリング」は「サーバー サイド レンダリング」のことを指します・・と記事に書いてあるので)を推奨する」って言っちゃってますから。

じゃあ。

昔みたいに、サーバー側でHTMLを組み立てて返す方法に戻せってことか・・?と、思うとそうではなくて。

ここでいうサーバーサイドレンダリングSSR)というのは、クライアントサイドレンダリングでやっているアルゴリズムをサーバーサイドでやる感じみたいです。

その辺の説明は、この記事がわかりやすかったのでリンクのせときます。

ssr.vuejs.org  

ざっと、Webフロントエンドとサーバーサイドの技術動向についてアウトラインだけですけど・・駆け足で整理してみました。

整理してみて、つくづく思うのは、何がベストプラクティスなのか?の見極めが難しい時代になってるなあ・・ということです。

何でもかんでも「これ一択」みたいなものはなくて、開発するWebアプリケーションの機能要件や性能要件によって、フロントエンドとサーバーサイドにどの技術を適用するのが最適なのか・・っていうのを、十分検討する必要があって・・とにかく、引き出しの多さが求められます。

もっと勉強しないといけないですね。

ではでは。 

おまけ:参考にしたリンクなど 

初期表示時の各ステップの英語名は、以下を参考にしました。

medium.com

あと、記事内で名前をだした、各JavaScriptフレームワークのリンクです。 

Anglular

angular.jp 

React

ja.reactjs.org 

Vue.js

jp.vuejs.org 

関連記事として、モダンなJavaScript関連に絞って、整理してみました。

arakan-pgm-ai.hatenablog.com