新人SEの学習記録

14年度入社SEの学習記録用に始めたブログです。もう新人じゃないかも…

学習記録:Webフロントエンド

[学習記録] Webフロントエンド

内容:11章 パフォーマンス入門

パフォーマンスの重要性
  • パフォーマンスはサービス価値の一角
    • プロダクトの品質そのものといえる
    • Google, Microsoft, Amazonなど各社ではパフォーマンスの向上が売上に直結する指標として有益なことが示されている
  • パフォーマンスを重要視するGoogle
    • 検索順位のアルゴリズムにWebページの表示速度を取り入れている
    • 一般的なSEO(Search EngineOptimization)ではコンテンツが重要だが、パフォーマンスが低いと順位に悪影響
    • Google Analyticsにはサイトの速度項目があり、表示速度や改善のためのアドバイスが表示
    • PageSpeed Insightsというサービスでも同様のアドバイスを受けることができる
  • クライアント環境の多様化
    • あらゆる環境で快適な表示速度・快適性を保証
    • 接続の不安定なモバイル環境、PCより低スペックなスマートフォンなど
    • 高度なチューニングは導入コストやその後の運用コストを跳ね上げる
    • コストパフォーマンスの落とし所を見つける必要
フロントエンド・パフォーマンス
  • レスポンスタイムのうち8〜9割をフロントエンドが占める
    • HTMLから始まるフロントエンド処理
      • ブラウザでページを開くとき、指定URLからHTMLを取得するためにサーバにリクエストを行う
      • リクエストが成功するとブラウザはサーバからHTMLを受け取り、フロントエンドの処理が開始
      • どのようなサブリソースを追加で取得してどのように表示すべきか、などがHTMLには記載
    • サーバサイド・レスポンス
      • サーバ再度によるHTMLの動的な生成処理は、最初のHTMLを受け取るまで
      • あるコンテンツが重大なボトルネックを抱えているのであれば、それをフロントエンドで読み込まないようにするのも選択肢
      • サーバサイド開発では、同時多発的なリクエストでも全てのクライアントに対して迅速にレスポンスを返すことを前提
      • フロントエンドにおけるロード時間の多くは、リクエストが繰り返されることでトータルとして十数秒掛かってしまう
      • フロントエンドが多量のリクエストを行い、パフォーマンスを損ねるケースの方が圧倒的に多い
  • 初期化のパフォーマンス
    • HTMLをレンダリングする過程で、サブリソースに対するリクエストが発生
    • 昨今のビジュアル表現・UIを支えるには、50〜100のリクエストが必要
    • パフォーマンス向上には、これらのリクエストを減らす・サブリソースのファイルサイズを小さくするなどの最適化が必要
    • ロードをはじめてから、実際にユーザがページを見られるようになるまでをイニシャライズのパフォーマンスとする
  • 実行時のパフォーマンス
    • Ajax処理など、ユーザ操作で何らかの処理が発生するケースが増える
    • スクロールやインタラクションが快適なレベルで応答できている状態が望ましい
    • ブラウザのレンダリング処理に対する負荷や、JavaScriptの処理内容・速度が大きく関わってくる
    • これをランタイムのパフォーマンスとする
パフォーマンスに影響する因子
要因 イニシャライズ ランタイム
ネットワーク
描画
スクリプト処理
イニシャライズ
  • 目標にすべき表示速度
    • 0.1sec:速度の応答があるように感じられる速度
    • 1sec:遅延を感じるが、連続的なタスクへの集中力は妨げられない速度
    • 10sec:処理中のアプリケーションに関心を向けていられる速度
  • イニシャライズ処理の流れ
    • 1) WebページへのHTTPリクエスト
      • DNSルックアップが発生
      • IPアドレスを取得できると、TCP接続の確立(3ウェイ・ハンドシェイク)
      • HTTPリクエストの送信
    • 2) サーバからのHTTPレスポンス
      • 静的なHTMLであれば、サーバ上に保存されているデータをそのまま返す
      • もしくはサーバサイドアプリケーションが生成した動的なHTMLを返す
      • データベースに問い合わせたり、テンプレート処理をしたり…
    • 3) 取得されたHTMLの評価
      • ブラウザによってHTMLのパースと評価
      • DOMの構築
      • HTMLを取得して即座にページが表示される訳ではなく、CSSのスタイル情報やjavaScriptによる要素の操作が必要
    • 4) サブリソースのロードと評価
    • 5) レンダーツリーの構築と描画
      • 実際にはサブリソースのロードと描画は細かい単位で繰り返し実行される
      • DOMツリーとCSSのスタイル情報をもとに、描画すべき要素の関係などを決定=レンダーツリーの構築
  • 非同期処理とロード完了のタイミング
    • window.onload()が発生したころに、すべてのDOM構築とサブリソースのロードが完了
    • 一般的にはこの時点でページ全体の初期化は終了
    • Ajaxのような非同期処理ではこの限りではない
表示を早くするポイント
  • CSSJavaScriptの適切な配置
    • サブリソースのロードと評価によるブロッキングをふまえて、HTML内での読み込み位置を調整
    • スタイルに過度な影響を与えないJSの読み込みをbody閉じタグの直前に配置
    • テキストの表示はJSのロードと評価を待たなくて済むようになる
  • リクエスト数を絞る
    • JQueryプラグイン複数利用する場合、複数のJSの読み込み指定が並ぶ
    • ファイルを結合し、読む込むファイルを一つにする(CSSも同様)
    • Gruntではgrunt-contrib-concatを利用してテキストファイルの結合を行うことができる
  • CSS Sprites
    • 複数画像を連結し、background-positionなどのCSSプロパティで表示を調整して利用する手法
    • 小さいサイズで種類がたくさんあるようなアイコン画像などをひとめとめにするときに有効
    • 複数画像を1つの画像とし、使用する画像ごとにbackground-positionで表示位置を調整
    • 手作業では面倒なので、Compassなどを用いて自動生成
  • Data URI Scheme
    • 画像などのバイナリデータを、文字列にエンコードしてテキストデータ中に埋め込む仕様
    • src属性やCSSのbackground-imageにURLを指定する代わりに、エンコード文字列を指定
    • Compassのinline-imageヘルパーを用いると、自動でCSSに画像データを文字列変換したbackground-imageが生成される
    • 埋め込みすぎるとCSSファイル自体が肥大化してしまうので、1K Byte未満の画像のみをターゲットにするなどのルールを設けて運用する必要
  • リソースのファイルサイズ減量
    • テキストリソースの最小化
      • 実行時にコードのインデントや改行などを除去
      • JSであればローカルスコープ内の変数名を短くするなど
    • 画像ファイルの最適化
    • 配信時のキャッシュコントロール
      • サーバからブラウザにリソースを返すとき、HTTPレスポンスで適切なキャッシュ指定を行う
      • リソースの取得時のネットワークコストは非常に大きいため、確実に適用したい
      • Apacheであればmod_expires、nginxであればHttpHeadersModuleを導入すれば、設定ファイルを変更するだけで適用可能
    • 配信時のGziip圧縮
      • サーバからリソースを返すときのGzip圧縮
      • テキストファイルに限られるが、元ファイルサイズの30〜40%まで削減可能
      • 圧縮レベル3〜5程度が良い
      • Apacheならmod_deflateとmod_filter、nginxならHttpGzipModule
  • WebPagetestの活用
    • [title:http://www.webpagetest.org/]
    • アクセス元や回線速度などを常に同じ条件でテスト可能
    • 多彩な結果の詳細レポートがあるので、次に解決すべきボトルネックを見つけ出す助けとなる