読書録

分類/書籍名 ページ数
設計(オブジェクト指向など) 2806
『実践ドメイン駆動設計』 618
『増補改訂版 Java言語で学ぶデザインパターン入門』 528
ユースケース駆動開発実践ガイド』 514
『実践テスト駆動開発 400
アンチパターン―ソフトウェア危篤患者の救出』 394
『新装版 達人プログラマー 職人から名匠への道』 383
データ構造とアルゴリズム 2379
『世界で闘うプログラミング力を鍛える本 コーディング面接189問とその解法』 772
数学ガール/乱択アルゴリズム 485
『問題解決力を鍛える!アルゴリズムとデータ構造』 461
数学ガール/ポアンカレ予想 421
Pythonによるプログラミング入門 東京大学教養学部テキスト: アルゴリズム情報科学の基礎を学ぶ』 240
Web 2033
『パーフェクト Ruby on Rails 【増補改訂版】』 528
『Webを支える技術 ―― HTTP,URI,HTML,そしてREST』 400
『Webフロントエンド ハイパフォーマンス チューニング』 337
『フロントエンド開発入門: プロフェッショナルな開発ツールと設計・実装』 285
『入門React: コンポーネントベースのWebフロントエンド開発』 259
『Web API: The Good Parts』 224
言語 1368
『プログラミングRust』 608
『Kotlinイン・アクション』 468
『メタプログラミングRuby 第2版』 292
ネットワーク 1114
『コンピュータネットワーク 第5版』 1114
バージョン管理,CI・CD 848
『継続的デリバリー 信頼できるソフトウェアリリースのためのビルド・テスト・デプロイメントの自動化』 544(大型本)
GitHub実践入門──Pull Requestによる開発の変革』 304
DB, SQL 660
『データ指向アプリケーションデザイン ―信頼性、拡張性、保守性の高い分散システム設計の原理』 660
ソフトウェア工学 450
『エッセンシャル スクラム: アジャイル開発に関わるすべての人のための完全攻略ガイド』 450
Linux 440
『新しいLinuxの教科書』 440
エディタ 428
『実践Vim 思考のスピードで編集しよう』 428
コンピュータシステムの基礎,低レイヤ 416
『コンピュータシステムの理論と実装 ―モダンなコンピュータの作り方』 416
コンテナ 384
『Kubernetesで実践するクラウドネイティブDevOps』 384
機械学習 320
『ゼロから作るDeep LearningPythonで学ぶディープラーニングの理論と実装』 320
プログラミング基礎 260
『リーダブルコード ―より良いコードを書くためのシンプルで実践的なテクニック』 260
クラウド基盤 216
Amazon Web Services 基礎からのネットワーク&サーバー構築』 216
会計 752
『新・現代会計入門 第4版』 752
業務改善 1208
『独学大全 絶対に「学ぶこと」をあきらめたくない人のための55の技法』 788
『問題解決の全体観』 上下巻 420
ソフトウェアビジネス 284
ハッカーと画家 コンピュータ時代の創造者たち』 284
チーム運用 228
『Team Geek ――Googleのギークたちはいかにしてチームを作るのか』 228

『Ruby on Rails チュートリアル』学習メモ(作成中)

Ch01 0からdeployまで

  • お手軽すぎるscaffold
    • 自動生成されたcodeは無駄に量が多く複雑 → 初学者には向かない
  • rails 5.1.6 new hello_app ← バージョン指定
  • direcroty 構成 → 表1.2
  • Gemfileのバージョン指定
    • ~>では,メジャーバージョンのアップデートはしない
  • list 1.5でGemfileの内容
  • root 'controller_name#action_name'
  • Git
    • git config --global user.name "自分の名前"
    • git config --global user.email your.email@example.com
    • git config --global alias.co checkout
    • git config --global credential.helper "cache --timeout=86400"
    • git init
    • git add -A
      • .gitignoreで指定していないすべてのファイルをバージョン管理に追加
    • git commit -m "Initialize repository"
    • git log
    • git checkout -f
      • 以前のcommitに復元できる
    • git remote add origin https://github.com/<あなたのGitHubアカウント名>/hello_app.git
    • git push -u origin master
    • git checkout -b modify-README
    • git branch
    • github.com/settings/repositoriesをブラウザで開いて「Repository default branch」をmainからmasterに変更
    • 編集後に,git statusで確認
    • git commit -a -m "Improve the README file"
      • -a: 変更を一括でcommit
        • 慎重に使う
      • 新しいファイルはaddが必要
    • commit message: 現在形かつ命令形
    • git checkout master
    • git merge modify-README
    • git branch -d modify-README
    • git branch -D
      • topic branch上の変更を破棄
      • 変更をマージしていなくても削除できる
    • git push
  • deploy
  • まとめ
    • Ruby on Rails: Web developmentのためのframework, Rubyによる
    • rails new, rails server
    • controller_actionの追加やroot routingの変更だけで,hello, world applicationを作成できる
    • Herokuへのdeploy

Ch02 Toy application

  • application plan
    • 下準備: Ch01と同じところまで
    • 最初に,applicationの構造を表すためのdata_modelを作成する
    • userのdata_model design
      • minimum 表現
        • id, name, email
    • micro_postのdata_model design
      • id, content, user_id(associate)
  • Users resource
    • resource: data_modelとWeb_interfaceの組み合わさり
      • CRUDできるobjectとみなせるようになる
    • rails generate scaffold User name:string email:string
    • rails db:migrate
    • かつてはRake
    • ユーザーページを探検する
      • /users: index
      • /users/1: show
      • /users/new: new
      • /users/1/edit: edit
    • MVCの挙動
      • config/routes.rb
        • URL, actionの組み合わせを効率よく設定
        • resources :users
          • :usersはRubyのsymbol
      • app/controllers/users_controller.rb
        • 各ページは、Usersコントローラ内のアクションにそれぞれ対応
        • ページの数よりもアクションの数の方が多い
          • create、update、destroyアクションがあります。通常、これらのアクションは、ページを出力せずにデータベース上のユーザー情報を操作
        • URLには重複しているものがある
          • これらのアクション同士の違いは、それらのアクションに対応するHTTP requestメソッドの違い
        • REST
          • RailsアプリケーションにおけるRESTとは、アプリケーションを構成するコンポーネント (ユーザーやマイクロポストなど) を「リソース」としてモデル化することを指す
            • これらのリソースは、リレーショナルデータベースの作成/取得/更新/削除 (Create/Read/Update/Delete: CRUD) 操作と、4つの基本的なHTTP requestメソッド (POST/GET/PATCH/DELETE) の両方に対応
            • RESTfulなスタイルを採用することで、作成すべきコントローラやアクションの決定が楽になる。作成(C)・取得(R)・更新(U)・削除(D)を行うリソースだけでアプリケーション全体を構成してしまうことも可能
        • @記号で始まる変数をRubyではインスタンス変数と呼び、Railsのコントローラ内で宣言したインスタンス変数はビューでも使えるようになる
      • app/models/user.rb
        • 継承 (2.3.4および4.4) によって多くの機能が備わっています。特に、Active RecordというRubyライブラリのおかげで、リスト 2.9のUserモデルはUser.allというリクエストに対して、DB上のすべてのユーザーを返すことができます
      • ビューはその内容をHTMLに変換し (⑦)、コントローラがブラウザにHTMLを送信して、ブラウザでHTMLが表示
    • Usersリソースの欠点
      • データの検証が行われていない
      • ユーザー認証が行われていない
      • テストが書かれていない
      • レイアウトやスタイルが整っていない
      • 理解が困難
  • Micropostsリソース
    • マイクロポストを探検する
    • マイクロポストをマイクロにする
      • app/models/micropost.rb
        • validates :content, length: { maximum: 140 }
    • ユーザーはたくさんマイクロポストを持っている
      • 異なるデータモデル同士の関連付けは、Railsの強力な機能
      • app/models/user.rb
        • has_many :microposts
      • app/models/micropost.rb
        • belongs_to :user
      • 演習
        • <%= @user.microposts.first.content %>
        • app/models/micropost.rb
          • presence: true
        • app/models/user.rb
          • validates :name, presence: true
    • 継承の階層
      • ActiveRecord::Baseという基本クラスを継承したことによって、作成したモデルオブジェクトはデータベースにアクセスできるようになり、データベースのカラムをあたかもRubyの属性のように扱えるようになる
      • ActionController::Base
        • RailsのAction Packというライブラリが提供しているコントローラの基本クラス
        • モデルオブジェクトの操作や、送られてくるHTTP requestのフィルタリング、ビューをHTMLとして出力などの多彩な機能を実行できる
        • Railsのコントローラは必ずApplicationControllerを継承しているので、Applicationコントローラで定義したルールは、アプリケーションのすべてのアクションに反映
    • アプリケーションをデプロイする
  • 最後に
    • 良い
      • Rails全体を高度なレベルで概観できた
      • MVCモデル
      • RESTアーキテクチャに初めて触れた
      • データモデルの作成を初めて行った
      • データベースを背後に持つWebアプリケーションを本番環境で動かした
    • 弱点
      • レイアウトもスタイルも設定されていない
      • “Home” や “About” のような定番の静的なページがない
      • ユーザーがパスワードを設定できない
      • ユーザーが画像を置けない
      • ログインの仕組みがない
      • セキュリティのための仕組みがまったくない
      • ユーザーとマイクロポストの自動関連付けが行われていない
      • Twitterのような「フォロワー (following)機能」や「フォロー中 (followed)機能」がない
      • マイクロポストをフィードできない
      • まともなテストがない
      • 理解が困難
    • 本章のまとめ
      • Scaffold機能でコードを自動生成すると、Webのあらゆる部分からモデルデータにアクセスしてやりとりできるようになる
      • Scaffoldは何よりも手っ取り早いのがとりえだが、これを元にRailsを理解するには向いていない
      • RailsではWebアプリケーションの構成にMVC (Model-View-Controller) というモデルを採用している
      • Railsが解釈するRESTには、標準的なURLセットと、データモデルとやりとりするためのコントローラアクションが含まれている
      • Railsではデータのバリデーション (validation) がサポートされており、データモデルの属性の値に制限をかけることができる
      • Railsには、さまざまなデータモデル同士を関連付けを定義するための組み込み関数が多数用意されている
      • Railsコンソールを使うと、コマンドラインからRailsアプリケーションとやりとりすることができる

Ch03 ほぼ静的なページの作成

  • 静的なページを自分の手で作成することは良い経験になり、多くの示唆も得られる
  • セットアップ
    • RailsのデフォルトのページはHeroku上ではうまく表示されない仕様になっています。このため、hello worldのような変更を加えないとデプロイが成功したかどうかが分かりづらい、というのが本当の理由
    • heroku logsでerrorの確認
  • 静的ページ
    • コントローラとは (基本的に動的な) Webページの集合を束ねるコンテナのこと
    • git checkout -b static-pages
    • 静的なページの生成
      • rails generate controller StaticPages home help
      • git push -u origin static-pages
      • 元に戻す方法
        • rails destroy controller StaticPages home help
        • rails db:rollback
        • rails db:migrate VERSION=0
      • GETやその他のHTTPメソッドについて
        • クライアント (例えばFirefoxSafariなどのWebブラウザ) とサーバー (ApacheやNginxなどのWebサーバー) は、4つの基本操作(GET、POST、PATCH、DELETE)を互いに認識できるようになっています
        • ブラウザがこれらの操作のリクエストを送信しているかのように見せかける技術 (偽装) を駆使して、PATCHとDELETEという操作を実現
      • StaticPagesコントローラは一般的なRESTアクションに対応していないことに注意してください。これは、静的なページの集合に対しては、適切なアクション
      • ApplicationControllerクラスを継承しているため、StaticPagesControllerのメソッドは (たとえ何も書かれていなくても) Rails特有の振る舞い
        • /static_pages/homeというURLにアクセスすると、RailsはStaticPagesコントローラを参照し、homeアクションに記述されているコードを実行
          • 今回の場合、homeアクションが空になっているので、/static_pages/homeにアクセスしても、単に対応するビューが出力されるだけ
    • 静的なページの調整
      • 重要なのは「Railsのビューの中には静的なHTMLがある」という点
        • Railsの知識が無くてもHomeページやHelpページを修正できる
  • テストから始める
    • 何らかの変更を行う際には、常に「自動化テスト」を作成して、機能が正しく実装されたことを確認する習慣をぜひ身に付けましょう
    • 結局テストはいつ行えばよいのか
      • テストを行う目的
        • 機能停止に陥るような回帰バグ (Regression Bug: 以前のバグが再発したり機能の追加/変更に副作用が生じたりすること) を防止
        • 安全にリファクタリング
        • テストコードは、アプリケーションコードから見ればクライアントとして動作するので、アプリケーションの設計やシステムの他の部分とのインターフェイスを決めるときにも役に立つ
      • テストの手法やタイミングは、ある意味テストをどのぐらいすらすら書けるかで決まると言ってよい
      • 「テスト駆動」にするか「一括テスト」にするかを決める目安となるガイドライン
        • アプリケーションのコードよりも明らかにテストコードの方が短くシンプルになる (=簡単に書ける) のであれば、「先に」書く
        • 動作の仕様がまだ固まりきっていない場合、アプリケーションのコードを先に書き、期待する動作を「後で」書く
        • セキュリティが重要な課題またはセキュリティ周りのエラーが発生した場合、テストを「先に」書く
        • バグを見つけたら、そのバグを再現するテストを「先に」書き、回帰バグを防ぐ体制を整えてから修正に取りかかる
        • すぐにまた変更しそうなコード (HTML構造の細部など) に対するテストは「後で」書く
        • リファクタリングするときは「先に」テストを書く
          • 特に、エラーを起こしそうなコードや止まってしまいそうなコードを集中的にテスト
      • 不安定な要素が特に見当たらないアプリケーションや、(主にビューが) 頻繁に改定される可能性の高いアプリケーションのコードを書くときには、思い切ってテストを省略してしまうこともある
    • 本書における主要なテストは、コントローラテスト (この節より)、モデルテスト (第6章より)、統合テスト (第7章より) の3つ
      • 統合テストでは、ユーザーがWebブラウザでアプリケーションとやりとりする操作をシミュレートできるので特に強力
      • まずは取っ付きやすいコントローラテストから
    • 最初のテスト
      • test/controllers/static_pages_controller_test.rbの確認
      • rails test
      • テストの実行にはある程度時間がかかる
        • (1) Springサーバーを起動してRails環境を事前読み込みするのに時間がかかる
          • 最初の1回だけ
        • (2) Rubyそのものの起動に時間がかかる
          • 3.6.2で紹介するGuardを導入することで改善
    • Red
    • Green
      • get 'static_pages/about'
        • /static_pages/aboutというURLに対してGETリクエストが来たら、StaticPagesコントローラのaboutアクションに渡すようRailsに指示しています。この結果、自動的に次のようなヘルパーが使えるようになります
          • static_pages_about_url
      • Railsでは、テンプレートとはすなわち「ビュー」
      • touch app/views/static_pages/about.html.erb
        • touchコマンドは本来、ファイルやディレクトリのタイムスタンプだけを更新するためのコマンドなのですが、ファイルが存在しない場合には空ファイルを作成するという一種の副作用
    • Refactor
  • 少しだけ動的なページ
    • ページの内容に応じて、ページのタイトルを自ら書き換えて表示
    • タイトルをテストする (Red)
      • 典型的なWebページは、リスト 3.23のようなHTMLの構造
        • 1) document type (doctype)は使用するHTMLのバージョン (ここではHTML5) をブラウザに対して宣言
        • 2) headセクション。ここではtitleタグに囲まれた「Greeting」(=あいさつ) という文字
        • 3) bodyセクション。ここには「Hello, world!」という文字列
      • セレクタ
        • assert_select "title", "Home | Ruby on Rails Tutorial Sample App"
    • タイトルを追加する (Green)
    • レイアウトと埋め込みRuby (Refactor)
      • 重複を取り除くテクニックの1つとして、ビューで「埋め込みRuby」(Embedded Ruby) が使えます
      • Railsのprovideメソッドを使ってタイトルをページごとに変更
      • ERBと呼ばれている、Rubyの埋め込みコード
        • ERBはWebページに動的な要素を加えるときに使うテンプレートシステム
        • <% provide(:title, "Home") %>
          • <% ... %>という記法が使われており、その中からRailsのprovideメソッドを呼び出し
          • "Home"という文字列と:titleというラベルを関連付け
        • <% ... %>と書くと、中に書かれたコードを単に実行するだけで何も出力しません。<%= ... %>のように等号を追加すると、中のコードの実行結果がテンプレートのその部分に挿入
      • HTMLの重複した構造をDRYにする
        • Railsにはそのためにapplication.html.erbという名前のレイアウトファイルがあります
        • <%= yield %>
          • レイアウトを使う際に、/static_pages/homeにアクセスするとhome.html.erbの内容がHTMLに変換され、<%= yield %>の位置に挿入
        • スタイルシートJavaScriptは、Asset Pipeline (5.2.1) の一部
        • csrf_meta_tagsは、Web攻撃手法の1つであるクロスサイトリクエストフォージェリー (Cross-Site Request Forgery: CSRF)を防ぐために使われるRailsのメソッド
        • レイアウトと重複するHTMLがまだ残っているので、それらを削除して、内部のコンテンツだけ残します
      • 演習
        • まずはテストを追加
          • urlを変えるのも必要
        • routesを追加
        • controller_actionを追加
        • erbを追加
    • ルーティングの設定
      • 演習
        • root_url
  • 最後に
    • 本章のまとめ
      • 新しいRailsアプリケーションをゼロから作成したのはこれで3度目。今回も必要なgemのインストール、リモートリポジトリへのプッシュ、production環境まで行った
      • コントローラを新規作成するためのrailsコマンドはrails generate controller ControllerName アクション名 (省略可)
      • 新しいルーティングはconfig/routes.rbファイルで定義
      • Railsのビューでは、静的HTMLの他にERB (埋め込みRuby: Embedded RuBy) が使える
      • 常に自動化テストを使って新機能開発を進めることで、自信を持ってリファクタリングできるようになり、回帰バグも素早くキャッチ
      • テスト駆動開発では「red ・ green ・REFACTOR」サイクルを繰り返す
      • Railsのレイアウトでは、アプリケーションのページの共通部分をテンプレートに置くことでコードの重複を解決
  • 高度なセットアップ
    • minitest reporters
      • minitest-reporters gemを利用
        • test/test_helper.rb
          • require "minitest/reporters"
          • Minitest::Reporters.use!
    • Guardによるテストの自動化
      • テストをしようとする度にエディタからコマンドラインに移動して、手動でコマンドを打ち込み、実行しなければならないという点が面倒
      • Guardは、ファイルシステムの変更を監視
        • 具体的には、「home.html.erbファイルが変更されたらstatic_pages_controller_test.rbを自動的に実行する」
      • bundle exec guard init
      • guard :minitest, spring: "bin/rails test", all_on_start: false do
        • GuardからSpringサーバーを使って読み込み時間を短縮しています (SpringはRailsの機能の1つです)
        • 開始時にテストスイートをフルで実行しないようGuardに指示
      • .gitignoreファイルにspring/ディレクトリを追加
      • Springのプロセスが起動したまま多数残留すると、テストのパフォーマンスが低下
        • テストの実行が異常に遅くなってきたと感じたら、プロセスをチェックし、必要に応じてSpringをkill
        • Unixのプロセス
          • ps aux
          • ps aux | grep spring
          • killコマンドでpidを指定し、Unixのkillコード(Cloud9の場合、シグナル番号は15) を発行
            • kill -15 12241
          • 特定の名前を持つプロセスをまとめてkill
            • spring stop
            • pkill -15 -f spring
      • bundle exec guard
      • テストを変更ファイルだけではなく、フルで実行したい場合は、guard>プロンプトでReturnキーを押します
        • (このとき、Springサーバーに接続できないなどのエラーが表示されることがあります。問題を修正するには、もう一度Returnキーを押します)
      • Guardを終了するにはCtrl-Dキー

Ch04 Rails風味のRuby

  • Railsにおいて重要となるRubyのさまざまな要素について探っていく
  • Rails開発者にとって必要な知識は比較的少なくて済みます
  • この章の目的は、「Rails風味のRuby」というものについての確固たる基盤を、皆さんのこれまでの言語経験に関わらず提供すること
  • 動機
    • 初歩的な作業をいつまでも続けるわけにはいきません
    • Rubyに関する知識と経験の限界に真正面から挑み、これを乗り越えるためにこの章を割り当てる
    • 組み込みヘルパー
      • <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
        • Railsの組み込み関数stylesheet_link_tag (詳細はRails API参照) を使って、application.cssをすべてのメディアタイプで使えるようにしています
        • 少なくとも混乱を生じる可能性のあるRubyの概念が4つあります。Railsの組み込み関数、カッコを使わないメソッド呼び出し、シンボル、そしてハッシュ
    • カスタムヘルパー
      • app/helpers/application_helper.rb
  • 文字列とメソッド
    • Railsコンソールはirb (IRB: Interactive RuBy) を拡張して作られているため、Rubyの機能をすべて使うことができます
    • rails console
    • Railsコンソールは素晴しい学習ツールであり、その中を自由に探索できます
    • コンソールの中で何をしようとも、何かを壊すことは (まず) ありえないので、ご安心ください
      • Railsコンソールが何かおかしな挙動になったら、Ctrl-Cを押してコンソールから強制的に抜け出すことができます。もしくは、Ctrl-Dを押して正常にコンソールを終了させることもできます
    • Rubyリファレンスマニュアル (通称: るりま) やるりまサーチが大変便利
    • コメント
      • Rubyのコメントはナンバー記号# (「ハッシュマーク」や「オクトソープ」とも呼ばれます) から始まり、その行の終わりまでがコメント
    • 文字列
      • 文字列 (string) は、Webアプリケーションにおいておそらく最も重要なデータ構造
        • Webページというものが究極的にはサーバーからブラウザに送信された文字列にすぎないため
      • 文字列リテラルと呼ばれ (面白いことにリテラル文字列とも呼ばれます)ダブルクォート " で囲むことで作成
      • 文字列を組み立てる他の方法として式展開 (interpolation) というものがあり、#{}という特殊な構文を使います
        • PerlPHPに精通した開発者であれば、"foo $bar"のようなドル記号による自動的な挿入を連想して比較することでしょう
        • first_name = "Michael"
        • "#{first_name} Hartl"
      • 出力
        • puts (putの三人称単数現在形ではなく「put string」の略なので、本来は「put ess」と発音しますが、最近は「puts」と発音されることも多くなってきました)
        • putsを使って出力すると、改行文字である\nが自動的に出力の末尾に追加されます (これはターミナルのechoコマンドと同じ振る舞いになります)
          • printメソッドも同様の出力を行いますが、次のように、改行文字を追加しない点が異なります
      • シングルクォート内の文字列
        • ほとんどの場合、ダブルクォートとシングルクォートのどちらを使っても実質的に同じ
        • Rubyはシングルクォート文字列の中では式展開を行いません
        • ダブルクォート文字列を用いた文字列で#のような特殊な文字を使いたい場合は、この文字をバックスラッシュでエスケープ (escape) する必要があります
        • シングルクォートは、入力した文字をエスケープせずに「そのまま」保持するときに便利
      • 演習
        • tab: \t
    • オブジェクトとメッセージ受け渡し
      • オブジェクトとは (いついかなる場合にも) メッセージに応答するもの
        • オブジェクトに渡されるメッセージは、一般にはメソッドと呼ばれます。メソッドの実体は、そのオブジェクト内で定義されたメソッド
      • メソッドがtrueまたはfalseという論理値 (boolean) を返すことを、末尾の疑問符で示す慣習
        • 論理値は、特に処理の流れを変更するときに有用
      • Rubyでは、あらゆるものがオブジェクトです。したがって、nilもオブジェクト
        • ほぼあらゆるオブジェクトを文字列に変換するto_sメソッドを使って、nilがメソッドに応答する例
        • nilに対してメソッドをチェーン (chain) して渡せることを確認
          • nil.to_s.empty?
      • puts "x is not empty" if !x.empty?
        • Rubyではこのように、後続するifでの条件式が真のときにだけ実行される式 (後続if) を書くことができ、コードが非常に簡潔になります。なお、unlessキーワードも同様に使えます
      • Rubyにおいてnilは特別なオブジェクト
        • Rubyのオブジェクトのうち、オブジェクトそのものの論理値がfalseになるのは、false自身とnilの2つしかありません
          • 「!!」(「バンバン (bang bang)」と読みます) という演算子を使うと、そのオブジェクトを2回否定することになるので、どんなオブジェクトも強制的に論理値に変換できます
          • その他のあらゆるRubyのオブジェクトは、ゼロですらtrue
    • メソッドの定義
      • メソッドの引数を省略することも可能です (カッコですら省略可能です)
        • 引数にデフォルト値を含めているから
      • Rubyのメソッドには「暗黙の戻り値がある」ことにご注意ください。これは、メソッド内で最後に評価された式の値が自動的に返される
    • titleヘルパー、再び
      • module ApplicationHelperという要素について
        • モジュールは、関連したメソッドをまとめる方法の1つで、includeメソッドを使ってモジュールを読み込むことができます (ミックスイン (mixed in) とも呼びます)
        • Railsでは自動的にヘルパーモジュールを読み込んでくれるので、include行をわざわざ書く必要がありません
  • ほかのdata_structure
    • 配列と範囲演算子
      • "fooxbarxbaz".split('x')
      • Rubyでは、角カッコ以外にも配列の要素にアクセスする方法が提供されています
        • first, second, last
        • a.last == a[-1]
          • true
      • 配列の内容を変更したい場合は、そのメソッドに対応する「破壊的」メソッドを使います。破壊的メソッドの名前には、元のメソッドの末尾に「!」を追加したものを使うのがRubyの慣習です
      • pushメソッド (または同等の<<演算子) を使って配列に要素を追加することもできます
      • 他の多くの言語の配列と異なり、Rubyでは異なる型が配列の中で共存できます
      • 文字列を配列に変換するのにsplitを使いました。joinメソッドはこれと逆の動作
        • a.join(', ')
      • 範囲 (range) は、配列と密接に関係しています。to_aメソッドを使って配列に変換すると理解しやすい
        • (0..9).to_a
      • 範囲は、配列の要素を取り出すのに便利
        • a[0..2]
        • インデックスに-1という値を指定できるのは極めて便利です。-1を使うと、配列の長さを知らなくても配列の最後の要素を指定することができ、これにより配列を特定の開始位置の要素から最後の要素までを一度に選択することができます
        • a[2..-1]
      • 文字列に対しても範囲オブジェクトが使えます
        • ('a'..'e').to_a
    • ブロック
      • 配列と範囲はいずれも、ブロックを伴うさまざまなメソッドに対して応答することができます
        • (1..5).each { |i| puts 2 * i }
          • メソッドに渡されている{ |i| puts 2 * i }が、ブロックと呼ばれる部分
          • |i|では変数名が縦棒「|」に囲まれていますが、これはブロック変数に対して使うRubyの構文で、ブロックを操作するときに使う変数を指定
          • ブロックであることを示すには波カッコ で囲みますが、次のようにdoとendで囲んで示すこともできます
            • 短い1行のブロックには波カッコを使い、長い1行や複数行のブロックにはdo..end記法
          • ブロックは見た目に反して奥が深く、ブロックを十分に理解するためには相当なプログラミング経験が必要
      • mapメソッドなどを使ったブロックの使用例
        • 3.times { puts "Betelgeuse!" }
        • (1..5).map { |i| i**2 }
        • %w[a b c].map { |char| char.upcase }
          • mapのブロック内で宣言した引数 (char) に対してメソッドを呼び出しています。こういったケースでは省略記法が一般的で、次のように書くこともできます (この記法を“symbol-to-proc”と呼びます)
          • %w[A B C].map(&:downcase)
            • 元々Ruby on Rails独自の記法でした。しかし多くの人がこの記法を好むようになったので、今ではRubyのコア機能として導入
        • mapメソッドは、渡されたブロックを配列や範囲オブジェクトの各要素に対して適用し、その結果を返します
      • 最後のブロックの例として、単体テスト
      • ('a'..'z').to_a.shuffle[0..7].join
      • 演習
        • (0..16).map {|i| i**2}
        • str.map {|s| s.upcase}.join
        • s.split('').shuffle.join
    • ハッシュとシンボル
      • ハッシュは本質的には配列と同じですが、インデックスとして整数値以外のものも使える点が配列と異なります (この理由から、Perlなどのいくつかの言語ではハッシュを連想配列と呼ぶこともあります)
        • ハッシュのインデックス (キーと呼ぶのが普通です) は、通常何らかのオブジェクト
      • ハッシュの波カッコは、ブロックの波カッコとはまったく別物
      • ハッシュでは要素の「並び順」が保証されない
      • ハッシュの1要素を角カッコを使って定義する代わりに、次のようにキーと値をハッシュロケットと呼ばれる=> によってリテラル表現するほうが簡単
        • user = { "first_name" => "Michael", "last_name" => "Hartl" }
      • key: Railsでは文字列よりもシンボルを使う方が普通
        • シンボルは文字列と似ていますが、クォートで囲む代わりにコロンが前に置かれている
        • 余計なことを一切考えずに、シンボルを単なる文字列とみなしても構いません
          • 余計なものを削ぎ落した結果、シンボル同士の比較を容易に行えます。文字列は1文字ずつ比較する必要がありますが、シンボルは一度に全体を比較できます。これはハッシュのキーとして理想的な性質です。
        • シンボルは、Ruby以外ではごく一部の言語にしか採用されていない特殊なデータ形式
        • 文字列と違って、全ての文字が使えるわけではない
        • 未定義のハッシュ値は単純にnil
        • ハッシュではシンボルをキーとして使うことが一般的なので、Ruby 1.9からこのような特殊な場合のための新しい記法がサポート
          • h2 = { name: "Michael Hartl", email: "michael@example.com" }
          • :name =>とname:は、ハッシュとしてのデータ構造は全く同じ
      • ハッシュの値にはほぼ何でも使うことができ、他のハッシュを使うことすらできます → ネストされたハッシュ
      • 配列や範囲オブジェクトと同様、ハッシュもeachメソッドに応答します
      • 便利なinspectメソッドを紹介します。これは要求されたオブジェクトを表現する文字列を返します
        • オブジェクトを表示するためにinspectを使うことは非常によくあることなので、 pメソッドというショートカットがあります
        • p :name # 'puts :name.inspect' と同じ
      • 演習
    • CSS、再び
      • <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' %>
        • Ruby では丸カッコは使用してもしなくても構いません
        • ハッシュがメソッド呼び出しの最後の引数である場合は、波カッコを省略できます
        • Rubyは改行と空白を区別していません
        • 最初の引数である文字列は、スタイルシートへのパスを示しています
        • 次の引数であるハッシュには2つの要素があり、最初の要素はメディアタイプを示し、次の要素はRails 4.0で追加されたturbolinksという機能をオンにしています
      • CSSファイル名の後に、?body=1のような行が余分に表示されていることがあります。これらはRailsによって挿入されているもので、サーバー上で変更があった場合にブラウザがCSSを再読み込みするのに使います
  • Rubyにおけるクラス
    • 参照
    • コンストラク
      • s = "foobar" # ダブルクォートは実は文字列のコンストラク
      • 暗黙のリテラルコンストラクタを使う代わりに、明示的に同等の名前付きコンストラクタを使うことができます。名前付きコンストラクタは、クラス名に対してnewメソッドを呼び出します
      • 配列のコンストラクタであるArray.new は配列の初期値を引数に取りますが、 Hash.new はハッシュのデフォルト 値を引数に取ります
    • クラス継承
      • クラスについて学ぶとき、superclassメソッドを使ってクラス階層を調べてみるとよくわかります
      • 文字列を引数に取るメソッドを作るためだけに、わざわざ新しいクラスを作るのは変です。単語は文字列なので、リスト 4.15のようにWordクラスは Stringクラスを継承するのが自然です
      • Stringクラスの内部では、メソッドや属性を呼び出すときのself.も省略可能
        • self == reverse
    • 組み込みクラスの変更
      • Ruby のクラスはオープンで変更可能であり、クラス設計者でない開発者でもこれらのクラスにメソッドを自由に追加することが許されています
      • 真に正当な理由がない限り、組み込みクラスにメソッドを追加することは無作法であると考えられています
      • Railsの場合、組み込みクラスの変更を正当化できる理由がいくつもあります
        • Railsはblank?メソッドをRuby に追加しています
          • スペースが集まってできた文字列は空 (empty) とは認識されませんが、空白 (blank) であると認識されている
    • コントローラクラス
      • class StaticPagesController < ApplicationController
      • Railsのアクションには戻り値がありません。少なくとも、返される値は重要ではありません
        • home アクションはWebページを表示するためのものであり、値を返すためのものではありませんでした
      • 第3章では一度もStaticPagesController.newを実行しませんでした
        • Railsは確かにRubyで書かれていますが、既にRubyとは別物
    • ユーザークラス
      • Railsでは、インスタンス変数をコントローラ内で宣言するだけでビューで使えるようになる、といった点に主な利用価値があります
      • インスタンス変数は常に@記号で始まり、まだ定義されていなければ値がnil
      • initializeは、Rubyの特殊なメソッドです。これは User.newを実行すると自動的に呼び出されるメソッド
      • マスアサインメント (mass assignment)
        • initializeメソッドにハッシュを渡すことで、属性が定義済みの他のユーザを作成
  • 最後に
    • 本章のまとめ
      • Rubyは文字列を扱うためのメソッドを多数持っている
      • Rubyの世界では、すべてがオブジェクトである
      • Rubyではdefというキーワードを使ってメソッドを定義する
      • Rubyではclassというキーワードを使ってクラスを定義する
      • Railsのビューでは、静的HTMLの他にERB (埋め込みRuby: Embedded RuBy) も使える
      • Rubyの組み込みクラスには配列、範囲、ハッシュなどがある
      • Rubyのブロックは (他の似た機能と比べ) 柔軟な機能で、添え字を使ったデータ構造よりも自然にイテレーションができる
      • シンボルとはラベルである。追加的な構造を持たない (代入などができない) 文字列みたいなもの
      • Rubyではクラスを継承できる
      • Rubyでは組み込みクラスですら内部を見たり修正したりできる

Ch05 レイアウトを作成する

  • この章では、アプリケーションにBootstrapフレームワークを組み込み、そして、カスタムスタイルを追加します
  • 構造を追加する
    • カスタムCSSルールの他に、Twitter社によるオープンソースのWebデザインフレームワークとして公開しているBootstrapも利用します
    • コードそのものにもスタイルを与えます。つまり、散らかり始めたレイアウトのコードを、パーシャル (Partial) 機能を使って整えていくということ
    • Webアプリケーションを作成するときに、ユーザーインターフェイスの概要をできるだけ早いうちに把握しておくことがしばしば有用
    • ナビゲーション
      • RailsはデフォルトでHTML5を使います
        • 一部のブラウザ (特に旧式のInternet Explorer) ではHTML5のサポートが不完全である場合があります。そのため、次のようなJavaScriptのコード (通称: HTML5 shim (or shiv))3 を使ってこの問題を回避
      • headerタグは、ページの上部に来るべき要素を表します
      • すべてのHTML要素には、クラスとidの両方を指定することができます
        • これらは単なるラベルで、CSSでスタイルを指定するときに便利
        • クラスとidの主な違いは、クラスはページ内で何度でも使えるのに対し、idは一度しか使えない点
      • divタグは一般的な表示領域を表し、要素を別々のパーツに分けるときに使われます。特に古いスタイルのHTMLでは、divタグはサイト内のほぼすべての領域で使われていました
        • HTML5からはよく使われる領域ごとに細分化できるようになり、具体的にはheader要素、nav要素、section要素が新たに使えるようになりました
      • リンクを生成するために、Railsヘルパーのlink_to
        • link_toの第1引数はリンクテキスト、第2引数はURL
        • このURLは5.3.3で名前付きルート (Named Routes) に置き換えますが、今はWebデザインで一般に使われるスタブ用の (とりあえずのダミーとして使われる) URL「'#'」を置いておきます
        • 第3引数はオプションハッシュ
          • Railsヘルパーは、このようにオプションのハッシュを取ることがよくあり、これによりRailsのコードから離れることなく任意のHTMLオプションを柔軟に追加することができます
      • リストアイテムタグliと順不同リストタグulによって作られた、ナビゲーションリンクのリスト
        • navタグには「その内側がナビゲーションリンクである」という意図を明示的に伝える役割
      • yieldメソッドはWebサイトのレイアウトにページごとの内容を挿入
      • 今後のスタイル要素を利用するために、home.html.erbビューに特別な要素をいくつか追加
        • 第7章でサイトにユーザーを追加するときに備えて、最初のlink_toで次のような仮のリンクを生成
        • divタグのCSSクラスjumbotronや、signupボタンのbtnクラス、btn-lgクラス、btn-primaryクラスはすべて、Bootstrapにおいて特別な意味
        • image_tagヘルパーの能力が示されています。このヘルパーでは、シンボルを使ってalt属性などを設定できます
          • rails.pngというRailsのロゴ画像ファイルを加える必要
          • app/assets/images/ディレクトリにおいてください
          • image_tagヘルパーを使っているので、Railsは該当する画像ファイルを、アセットパイプラインを通してapp/assets/images/ディレクトリの中から探してくれます
          • src属性には "images" というディレクトリ名が含まれていない
            • 高速化のための仕組みで、Railsはassetsディレクトリ直下の画像をapp/assets/imagesディレクトリにある画像と紐付け
            • ブラウザから見るとすべてのファイルが同じディレクトリにあるように見えるようになります。そして、このようなフラットなディレクトリ構成を採っていると、ファイルをより高速にブラウザに渡すことができるようになります
          • alt属性は、画像がない場合に代わりに表示される文字列です。例えば視覚障害のあるユーザーが使うスクリーンリーダーでは、ここの属性が読み上げられて、そこに画像があることが示されます
      • BootstrapとカスタムCSS
        • 多くのHTML要素にCSSクラスを関連付けました。こうしておくことで、CSSベースでレイアウトを構成する際に高い柔軟性
        • Bootstrapを使うことでアプリケーションをレスポンシブデザイン (Responsive Design) にできるということです。これにより、どの端末でアプリケーションを閲覧しても、ある程度見栄えをよくすることができます
        • bootstrap-sass gemを使ってRailsアプリケーションに導入できます
          • Bootstrapフレームワークでは、動的なスタイルシートを生成するためにLESS CSS言語を使っていますが、RailsのAsset Pipelineはデフォルトでは (LESSと非常によく似た) Sass言語をサポート
          • bootstrap-sassは、LESSをSassへ変換し、必要なBootstrapファイルを現在のアプリケーションですべて利用できるようにします
          • gem 'bootstrap-sass', '3.3.7'
        • カスタムCSSを動かすための最初の一歩は、カスタムCSSファイルを作ること
          • touch app/assets/stylesheets/custom.scss
            • app/assets/stylesheets/は,Asset Pipeline (5.2)の一部
            • ファイル名のcustom.scssには.scssという拡張子も含まれています
              • この拡張子は「Sass (Sassy CSS)」と呼ばれるCSSを拡張した言語で、アセットパイプラインはこのファイルの拡張子を見て、Sassを処理できるようにしています
        • Bootstrap CSSを追加する
          • app/assets/stylesheets/custom.scss
            • @import "bootstrap-sprockets";
            • @import "bootstrap";
        • すべてのページに適用される共通のスタイルをCSSに追加する
          • app/assets/stylesheets/custom.scss
          • CSSでは // でコメントアウトできるので、調べてみたいコードをこれで囲い、表示がどのように変わるかを確認
        • CSSルールでは一般に、クラス、id、HTMLタグ、またはそれらの組み合わせ、のいずれかを指定します。そしてその後ろにスタイリングコマンドのリストを記述します。
        • .center冒頭のドット.は、このルールがクラスに対してスタイルを適用することを示しています
          • centerクラスに属している (divなどの) タグの内側にある要素が、すべて中央揃えになることを意味
        • 冒頭がポンド記号#で始まる場合は、そのルールがCSSのidに対してスタイルを適用することを示します
        • Bootstrapには洗練されたタイポグラフィーを利用できるCSSルールがあります
          • テキストの見栄えを変えてみましょう
        • いくつかのルールをサイトロゴに追加
          • テキストを大文字に変換し、サイズ、色、配置を変更
        • 演習
          • comment out
            • <%#= image_tag("kitten.jpg", alt: "Kitten") %>
          • すべての画像を非表示
            • img {
              • display: none;
    • パーシャル (partial)
      • app/views/layouts/application.html.erb
        • renderと呼ばれるRailsヘルパー呼び出しだけを使って、HTML shimのスタイルシート行を置換
        • app/views/layouts/_shim.html.erbというファイルを探してその内容を評価し、結果をビューに挿入
          • アンダースコアは、パーシャルで使う普遍的な命名規約であり、また、一目見ただけでディレクトリ中のすべてのパーシャルを識別することが可能になります
        • footerの追加
          • styleも追加
  • Sassとアセットパイプライン
    • CSSJavaScript、画像などの静的コンテンツの生産性と管理を大幅に強化する「アセットパイプライン (Asset Pipeline)」
    • アセットパイプラインの概要と、素晴らしいCSS生成ツールである「Sass」の使い方について
    • アセットパイプライン
      • Rails開発者の視点からは、アセットディレクトリ、マニフェストファイル、プリプロセッサエンジンという、3つの主要な機能が理解の対象
      • アセットディレクト
        • 静的ファイルを目的別に分類する、標準的な3つのディレクト
          • app/assets: 現在のアプリケーション固有のアセット
          • lib/assets: あなたの開発チームによって作成されたライブラリ用のアセット
          • vendor/assets: サードパーティのアセット
          • これらのディレクトリには、それぞれのアセットクラス用のサブディレクトリがあります。例えばapp/assetsの場合、次のような画像用、JavaScript用、CSS用のサブディレクトリがあります
      • マニフェストファイル
        • 静的ファイル (アセット) を上記の場所へそれぞれ配置すれば、マニフェストファイルを使って、それらをどのように1つのファイルにまとめるのかをRailsに指示することができます
        • 実際にアセットをまとめる処理を行うのはSprocketsというgem
        • マニフェストファイルはCSSJavaScriptには適用されますが、画像ファイルには適用されません
        • Railsには実用的なデフォルトのマニフェストファイルが付属している
      • プリプロセッサエンジン
      • 本番環境での効率性
        • Asset Pipelineの最大のメリットの1つは、本番のアプリケーションで効率的になるように最適化されたアセットも自動的に生成されること
        • 具体的には、Asset Pipelineがすべてのスタイルシートを1つのCSSファイル (application.css) にまとめ、すべてのJavaScriptファイルを1つのJSファイル (javascripts.js) にまとめてくれます。さらに、それらのファイルすべてに対して 不要な空白やインデントを取り除く処理を行い、ファイルサイズを最小化してくれます。
          • 結果として、開発環境と本番環境という、2つの異なった状況に対してそれぞれ最高の環境を提供
    • 素晴らしい構文を備えたスタイルシート
      • Sass は、スタイルシートを記述するための言語であり、CSSに比べて多くの点が強化
      • SCSSは厳密な意味で、CSS本体を抽象化したフォーマットです。つまり、SCSSはCSSに新しい機能を追加しただけで、全く新しい構文を定義したようなものではない
      • Railsのアセットパイプラインは、.scssという拡張子を持つファイルをSassを使って自動的に処理
      • ネスト
        • Sassは、SCSSをCSSに変換する際に、&:hoverを#logo:hoverに置き換え
      • 変数
        • $light-gray: #777;
        • 定義されている変数はBootstrapページの「LESS変数一覧」で参照
          • このWebサイトでは、SassではなくLESSを使って変数が定義されていますが、bootstrap-sassというgemを使えば、Sassでも同様の変数が使えるようになります
  • レイアウトのリンク
    • 名前付きルート
    • サイトリンクのルーティングとURLのマッピング
      • ページ名 URL 名前付きルート
    • Contactページ
      • 第3章の演習のとおり,Contactページについて追加
    • RailsのルートURL
      • 名前付きルートをサンプルアプリケーションの静的ページで使うために、ルーティング用のファイル (config/routes.rb) を編集
      • ルートURLのようなルーティングを定義することの効果
        • ブラウザからアクセスしやすくする
        • 生のURLではなく、名前付きルートを使ってURLを参照することができる
          • root_path: ルートURL以下の文字列
          • root_url: 完全なURLの文字列を返します
      • Railsチュートリアルでは一般的な規約に従い、基本的にはpath書式を使い、リダイレクトの場合のみurl書式を使う
        • HTTPの標準としては、リダイレクトのときに完全なURLが要求されるため
        • ほとんどのブラウザでは、どちらの方法でも動作します
      • get '/help', to: 'static_pages#help'
      • 演習
        • 名前付きルートは、as:オプションを使って変更することができます
          • get '/help', to: 'static_pages#help', as: 'helf'
    • 名前付きルート
      • link_toメソッドの2番目の引数で、適切な名前付きルートを使ってみましょう
    • リンクのテスト
      • 「統合テスト (Integration Test)」を使って一連の作業を自動化
      • rails generate integration_test site_layout
        • Railsは渡されたファイル名の末尾に _test という文字列を追加する
      • assert_selectメソッドの高度なオプション
        • 特定のリンクが存在するかどうかを、aタグとhref属性をオプションで指定して調べています
        • assert_select "a[href=?]", about_path
        • assert_select "a[href=?]", root_path, count: 2
          • リンクの個数も調べる
        • assert_selectは柔軟でパワフルな機能で、ここでは紹介し切れないほど他にも多くのオプションがあります
          • 経験的には、このメソッドで複雑なテストはしない方が賢明
          • 今回のようなレイアウト内で頻繁に変更されるHTML要素 (リンクなど) をテストするぐらいに抑えておくとよい
      • rails test:integration
      • 演習
        • test環境でもApplicationヘルパーを使えるようにする
  • ユーザー登録: 最初のステップ
    • Usersコントローラ
      • 2番目のコントローラであるUsersコントローラを作成
      • generateを実行して、現時点での要求である新規ユーザー用のユーザー登録ページ (スタブ) を持つ、最も簡単なコントローラを作成
      • Railsで好まれているRESTアーキテクチャの規約に従い、新規ユーザー用のアクションをnewとします。したがって、generate controllerの引数にnewを渡して、自動的にアクションを作成
        • rails generate controller Users new
    • ユーザー登録用URL
      • ユーザー登録URL用にget '/signup'のルートを追加
        • get '/signup', to: 'users#new'
      • Usersコントローラのテストで名前付きルートを使うようにする
      • ボタンにユーザー登録ページへのリンクを追加する
      • 最初のユーザー登録ページ (スタブ)
      • 演習
        • get signup_path
        • assert_select "title", full_title("Sign up")
  • 最後に
    • この章では、アプリケーションのレイアウトを形にし、ルーティングを洗練させました
    • 本章のまとめ
      • HTML5を使ってheaderやfooter、logoやbodyといったコンテンツのレイアウトを定義
      • Railsのパーシャルは効率化のために使われ、別ファイルにマークアップを切り出すことができます
      • CSSは、CSSクラスとidを使ってレイアウトやデザインを調整します
      • Bootstrapフレームワークを使うと、いい感じのデザインを素早く実装できる
      • SassとAsset Pipelineは、(開発効率のために切り分けられた) CSSの冗長な部分を圧縮し、本番環境に最適化した結果を出力する
      • Railsのルーティングでは自由にルールを定義することができ、また、その際に名前付きルートも使えるようになる
      • 統合テストは、ブラウザによるページ間の遷移を効率的にシミュレートする

Ch06 ユーザーのモデルを作成する

  • 一番重要なステップであるユーザー用のデータモデルの作成と、データを保存する手段の確保について
  • 第6章から第12章を通して、Railsのログインと認証システムをひととおり開発
  • コラム 6.1. 自分で認証システムを作ってみる
    • ある実践的な実験によると、多くのサイトの認証システムは膨大なカスタマイズを必要とするため、サードパーティ製品を変更して導入する場合にはシステムをゼロから作成するよりも多くの仕事を要するという結果
    • 既成品のシステムは内部がわかりづらいことが多く、ブラックボックス
    • 最近のRailsへの変更 (6.3) により、カスタム認証システムを容易に作成できるようになりました
    • あえて最終的にサードパーティの認証システムを導入することになったとしても、自分自身で認証システムを構築した経験があれば、サードパーティ製品を理解して変更することがずっと容易になる
  • Userモデル
    • ユーザー登録でまず初めにやることは、それらの情報を保存するためのデータ構造を作成すること
    • Railsでは、データモデルとして扱うデフォルトのデータ構造のことをモデル (Model)
    • Railsでは、データを永続化するデフォルトの解決策として、データベースを使ってデータを長期間保存
    • データベースとやりとりをするデフォルトのRailsライブラリはActive Record
      • Active Recordは、データオブジェクトの作成/保存/検索のためのメソッドを持っています
        • これらのメソッドを使うのに、リレーショナルデータベースで使うSQL (Structured Query Language)2 を意識する必要はありません
    • Railsにはマイグレーション (Migration) という機能
      • データの定義をRubyで記述することができ、SQLDDL (Data Definition Language) を新たに学ぶ必要がありません
    • Railsは、データベースの細部をほぼ完全に隠蔽し、切り離してくれます
      • 実際、本書ではSQLiteを開発 (development) 環境で使い、また、PostgreSQLを (Herokuでの) 本番環境 (production) で使います (1.5) が、本番環境のデータの保存方法の詳細について考える必要はほとんどありません
    • データベースの移行
      • Railsでユーザーをモデリングするときは、属性を明示的に識別する必要がありません
      • nameやemailといったカラム名を今のうちに考えておくことで、後ほどUserオブジェクトの各属性をActiveRecordに伝えるときに楽になります
      • rails generate model User name:string email:string
        • データベースで使いたい2つの属性をRailsに伝えます。このときに、これらの属性の型情報も一緒に渡します
        • generateコマンドの結果のひとつとして、マイグレーションと呼ばれる新しいファイルが生成
          • マイグレーションは、データベースの構造をインクリメンタルに変更する手段を提供
          • マイグレーション自体は、データベースに与える変更を定義したchangeメソッドの集まり
            • リスト 6.2の場合、changeメソッドはcreate_tableというRailsのメソッドを呼び、ユーザーを保存するためのテーブルをデータベースに作成
            • create_tableメソッドはブロック変数を1つ持つブロック (4.3.2) を受け取ります
              • そのブロックの中でcreate_tableメソッドはtオブジェクトを使って、nameとemailカラムをデータベースに作ります
            • モデル名は単数形 (User) ですが、テーブル名は複数形 (users) です
              • モデルはひとりのユーザーを表すのに対し、データベースのテーブルは複数のユーザーから構成
            • t.timestampsは特別なコマンドで、created_atとupdated_atという2つの「マジックカラム (Magic Columns)」を作成
            • rails db:migrate
              • 初めてdb:migrateが実行されると、db/development.sqlite3という名前のファイルが生成
                • SQLite データベースの実体
                • development.sqlite3ファイルを開くためのDB Browser for SQLiteという素晴らしいツールを使うと、データベースの構造を見ることができます
      • 演習
        • ほぼすべてのマイグレーションは、元に戻すことが可能
          • rails db:rollback
            • drop_tableとcreate_tableがそれぞれ対応していることをchangeメソッドが知っている
            • あるカラムを削除するような不可逆なマイグレーションの場合は、changeメソッドの代わりに、upとdownのメソッドを別々に定義する必要があります
    • modelファイル
      • class User < ApplicationRecord
    • ユーザーオブジェクトを作成する
      • rails console --sandbox
      • 初期化ハッシュ (hash) を引数に取る
        • 同様の方法でオブジェクトを初期化するActive Recordの設計
      • Active Recordを理解する上で、「有効性 (Validity)」という概念も重要
        • user.valid?
          • ただオブジェクトが有効かどうかを確認しただけ
        • データベースにUserオブジェクトを保存するためには、userオブジェクトからsaveメソッドを呼び出す必要
          • モデルの生成と保存を2つのステップに分けておくと何かと便利
            • しかし、Active RecordではUser.createでモデルの生成と保存を同時におこなう方法も提供されています
              • User.create(name: "A Nother", email: "another@example.org")
              • User.createは、trueかfalseを返す代わりに、ユーザーオブジェクト自身を返すことに注目
            • destroyはcreateの逆
              • 削除されたオブジェクトは次のようにまだメモリ上に残っています
    • ユーザーオブジェクトを検索する
      • User.find(1)
      • recordなし → findメソッドは例外 (exception) を発生
        • 存在しないActive Recordのidによって、findでActiveRecord::RecordNotFoundという例外が発生
      • User.find_by(email: "mhartl@example.com")
        • find関連メソッドは、ユーザーをサイトにログインさせる方法を学ぶときに役に立ちます
      • User.first
      • User.all
      • 演習
        • User.allで生成されるオブジェクトを調べ、ArrayクラスではなくUser::ActiveRecord_Relationクラスであることを確認
        • User.allに対してlengthメソッドを呼び出すと、その長さを求められることを確認
          • ダックタイピング (duck typing)
    • ユーザーオブジェクトを更新する
      • user.email = "mhartl@example.net"
      • 変更をデータベースに保存するために最後にsaveを実行
      • 保存を行わずにreloadを実行すると、データベースの情報を元にオブジェクトを再読み込みするので、変更が取り消されます
      • user.update_attributes(name: "The Dude", email: "dude@abides.org")
      • 特定の属性のみを更新したい場合は、次のようにupdate_attribute
        • user.update_attribute(:name, "El Duderino")
        • 検証を回避
      • 演習
        • created_atも直接更新
          • 更新するときは「1.year.ago」を使うと便利です。これはRails流の時間指定の1つで、現在の時刻から1年前の時間を算出してくれます
  • ユーザーを検証する
    • Active Record では検証 (Validation) という機能を通して、こういった制約を課すことができる
      • 存在性 (presence)の検証、長さ (length)の検証、フォーマット (format)の検証、一意性 (uniqueness)の検証
      • 最終検証として確認 (confirmation)
    • 有効性を検証する
      • 具体的なテスト方法についてですが、まず有効なモデルのオブジェクトを作成し、その属性のうちの1つを有効でない属性に意図的に変更します。そして、バリデーションで失敗するかどうかをテストする、といった方針で進めてい
      • test/models/user_test.rb
      • setup
      • rails test:models
    • 存在性を検証する
      • @user.name = " "
      • assert_not @user.valid?
      • name属性の存在を検査する方法は、リスト 6.9に示したとおり、validates メソッドにpresence: trueという引数を与えて使うこと
      • validates :name, presence: true
        • validatesは単なるメソッド
          • presence: trueという引数は、要素が1つのオプションハッシュです。4.3.4のようにメソッドの最後の引数としてハッシュを渡す場合、波カッコを付けなくても問題ありません
      • user.errors.full_messages
      • 演習
        • u.errors.messagesを実行すると、ハッシュ形式でエラーが取得
        • u.errors.messages[:email]

『フロントエンド開発入門: プロフェッショナルな開発ツールと設計・実装』学習メモ

Part 1 導入編 何故使うかを知る

Ch01 frontend history

  • static UI → dynamic UI
    • DOM utilityを提供したjQuery
      • cross browserや下位互換性を吸収したAPI
      • Ajax
        • XMLHttpRequest objectを隠蔽し冗長な通信記述を簡略化できる
      • Shorthand
        • 簡易的なanimationの活用
      • pluggable API
        • 自身のobjectを拡張できる
          • → 周辺のlibraryやpluginを充実させるecosystemを築く
    • browserで動作する画面を取り扱う技術者にとって,JavaScriptはinteractionや機能実現のための手段として重要な言語となってきた
    • SassといったCSS meta language
      • browserの互換性を意識することなくvendor prefixを補完できたり,構文blockをネストしてmulti selectorをcodeで実現することが可能になったり,扱いづらかったCSSにprogrammingの概念が導入されることでmodule化が可能になってきた
      • 変数化,mixin → CSS設計手法が登場
  • frontend_engineerという専門職
    • single_page_applicationの誕生
      • 内部では,applicationの状態管理やroutingのみならず,routingごとのcontrollerやdata_modelingなどが盛り込まれるようになる
      • → AngularJSやBackbone.jsなどのsingle_page_applicationを実現するためのall_in_one frameworkが使われだす
      • client MVCやrouting, data_modelingにはsoftwareのdesign_patternへの理解が求められる
      • → frontend engineer
  • Node.jsによる開発基盤の構築
    • server_side JavaScriptとしてNode.jsが発表
    • → bundled package managerであるnpmによって開発におけるecosystemが急速に充実する
      • → frontendでのlibraryのversion_controlや開発におけるさまざまなタスクの自動化が可能になる
    • CommonJS: module system
  • ECMAScript規格更新に伴う周辺事情の活性化
    • ES6からES5への変換tool: 6to5 → Babelに名称変更
    • 新しい仕様をcompileするためのpluginを開発することで,健全にcodebaseに最新仕様を持ち込むことができる
      • 現時点でfrontendが誇るすばらしいecosystem
  • 止まらないfrontend
    • focus
      • 昨今の技術要素が何のために必要なのか,何を解決するのか
      • 実践的な内容で技術要素を取り扱い必要なことを必要なタイミングで学ぶ

Ch02 frontend_engineerに求められるskill

  • frontend_engineerが取り組む実務
  • JavaScriptの成長と要求の変化
  • 変容する中で維持すべきdeveloperの姿勢
    • Webは止まらない,求められる技術要素も止まらない
      • 1次情報
        • WHATWGがもつWeb APIの草案が格納されたrepository内のIssueや,browser engineの次期versionに搭載される新しいAPIについて議論されるforum
        • 判断が必要
      • 感度の高い技術者やcommunityから得られる情報に価値があるといえる
      • 必要なときに,正しい場所から,必要な情報を,深く調べて身につける
    • publicな存在

Ch03 frontendにおける一般的なtools

  • Node.jsとその周辺のecosystem
    • Node.js: asyncのevent_driven_modelを採用したserver_side向けのJavaScript
      • server_sideのscript_languageであることに加えて,開発環境において必要なtoolやlibraryを動作させるために必要不可欠
      • core
        • V8と,libuvというasync I/OをsupportするC言語libraryなどから構成され,binary化されて配信される
        • libuv → async event_driven JavaScript runtimeを実現
    • package_manager
      • npm: JavaScript用のpackage_managerのCLI
        • packageを格納するregistryを提供・開発する会社名でもある
      • Yarn: npmと同類.Facebookが開発.
        • version lock file
        • workspace
          • 別applicationどうしの依存関係を単一にするarchitectureであるmonorepoを実現する仕組みを提供する
    • Node.jsがもたらす恩恵
      • Node.js: frontendのtool_chain, 開発環境構築を支える根幹そのもの
        • server_side languageとしても有能
        • event_loopやnon_blockingという特性を活かして,高traffic requestをさばいてもperformanceが低下するcaseが少ない
      • Backends_For_Frontends layerとbrowserとで同じ言語であるJavaScriptを扱うこともできる
        • 共通言語 → 一気通貫のcontextをdevelopment_memberに提供し,言語別に切り替えるストレスなく,継続的なdevelopment processを可能にする
      • 技術選定の主軸となるcaseもいくつか存在し,組織的な戦略として候補になりえる言語
        • Node.jsにより,JavaScriptが戦術・戦略として価値のある言語になるまで発展
  • compiler, module_bundler
    • 言語仕様を吸収し,解釈可能な状態で展開・連結する変換器
      • Babel
      • webpack
        • file間のmodule解決を行い1ファイルに連結させる機能を提供
    • compiler: Babel
      • 新しいJavaScript構文を環境に合わせて解釈可能な下位構文へとdown_compileするRole
      • ECMAScriptが年次策定していく新しい仕様と大きく関係
        • T39という団体により策定
      • 構成
        • 構文解析のためのparserやcompilerとしてのcore機能,それらを補うhelperや変換のためのpluginなど細かなpackage群による
      • babel/preset-envという主要な変換用pluginがpreinstallされたpresetを使うcaseが多い
    • module_bundler: webpack
      • 言語仕様の一部であるmodule機構を実装していない下位環境においての再現(emulate)を担当
      • 設定ファイルの柔軟性やloader, pluginというAPIを提供し強力な結合・連結機能を提供することで,周辺のecosystemも充実し,activeに開発が続けられている
      • ParcelやRollup.jsなども同じ役割
      • module仕様であるES Modulesの実装がすべてのbrowser環境で整うには時間がかかることも,module_bundlerが利用される理由の1つ
      • JavaScript module_system
        • Node.jsが採用したCommonJSとES2015で採択承認されたES Modulesの2つがあるが,Node.jsはES Modulesへの移行を試験的に実装している
        • Can I use: browserでの実装状況を調べるためのDBのdefacto standard
          • cross browserの課題解決を目的としたJavaScript toolが利用していることも多い
      • Babelは,webpackにおいてbabel-loaderとして変換のRoleを担う
        • → ほとんどはwebpackをfrontend code compile環境として選択する
    • Babel, webpackが解決すること
      • Babelには正式な仕様以外のpluginが作成・使用されてしまったという経緯があることに注意
        • → babel/preset-envは,ECMAScriptと歩みを合わせ,developerが実際に取り組むようなcross platformやbrowser要件の問題に対して最適な機能を提供
          • optionで互換性をどこまで保って変換するかのtargetを指定可能にする
      • まとめ
        • 開発において,年次策定される言語仕様の進化と並行しながら開発できる環境を提供できる
        • JavaScriptにおけるnative module仕様をemulateし現実的に課題を解決できる
      • → 開発において変更可用性,scalingの担保をもたらす恩恵となる
      • Babel, webpackを使う場面がなくなっても,codebaseが外的環境の変化に柔軟である点が重要
  • JavaScript代替言語: TypeScript
    • AltJSと呼ばれる
    • TypeScript: あくまでJavaScriptの構文を維持し,型annotationなどで拡張された静的型付言語
      • 自身が持つ型systemを省いた記述も可能
      • JavaScriptにとってのsuper_setとなる存在
    • TypeScriptの特徴
      • 静的型付言語で,型checkとJavaScriptへのcompileを担う
      • 型定義の場所
        • TypeScript自身がcoreに抱えているもの
          • DOM APIをはじめとしたbrowser向けのnative APIの型
        • communityによって提供されているもの
          • Node.js APIをフォローする型定義は@types/node packageで定義され多く利用される
        • development_teamがcodebaseで抱えるもの
          • productやapplicationのdomainに紐づくような型定義やprivate packageの型定義
      • interface.typeと呼ばれる型宣言
        • inlineの型annotationで収まらない引数や戻り値の型が必要なときや,共通化すべきobject shapeが必要なときなどに使う
        • merit
          • IDEによる型補完の恩恵
            • browserのFetch APIを使った構文での説明
          • 後続処理でのミスの防止
      • 型checkとcompile errorによって,applicationの堅牢性とcodebaseの健全性に恩恵がある
    • compilerとしてのTypeScript
      • JavaScriptへの出力
      • Babelのecosystemとは違った,独自の形でECMAScriptの新しい構文をfollowする
      • decoratorsは技術的負債になりうる
      • ECMAScriptとRoleが重複するものもある
    • TypeScriptによって解決できること
      • 3 points
        • compile errorによって,JavaScriptではfollowできない.script実行前の未然検知を可能にする
        • IDEと組み合わせることで型補完やerrorを表示させ開発体験を向上させられる
        • ECMAScriptとの歩みの中でBabelとは別のecosystemを築いている.早期的に取り込まれた構文利用には注意する
      • applicationの堅牢性を高めたり,team developmentを行う上でcodebaseの健全性を維持することに役立つ
      • 意図しない記述を許容しないという強力な安全策になる
  • framework/view library: Vue.js, Angular, React
    • 中規模以上のapplication開発においてbackend_APIとの連携を主体に据えたviewの構築が必要であったり,user_experienceを高めるためにstressない画面遷移が求められたり,開発序盤における技術選定の中でframeworkやview libraryの選択が求められることがある
      • 中長期的な運用や保守の中でproduct, applicationの特性を踏まえながら技術選定をすることは開発の現場では特に重要
    • 混とんとしていた変化の時期と比べ,背後を支えるecosystemが盤石となったことも開発者の学習コストを下げている
      • frameworkのbuild機構にはおよそwebpackが存在する
        • 過渡期はRequireJS, SystemJSをruntimeで実現する手法もあれば,CommonJSの記法を使いながらBrowserifyがWebのためにバンドルを行う手法もあった
        • → 今はapplicationと無関係なことに頭を使う必要がない
        • ECMAScriptによって規格化されたES Modulesの記法で,webpackがそれをemulateするようbundleすれば十分
    • Vue.js
      • PHPのbackend frameworkであるLaravelの作者が気に入って,LaravelのCLIによって新規applicationが作成される際,file setにVue.jsが内包されるようになった
      • 公式サイトの説明
        • UIを構築するためのprogressive framework
        • monolithic frameworkと異なり,Vueは少しずつ適用していけるように設計されている
      • Single_File_Componentという単一のcomponentにDOM template, style, scriptをまとめて記述しcompileする仕組みを持つことで,すべてJavaScriptのcontextに載せ替えることも可能になる
      • 少しずつ適用し,小さなcomponent群を集約させながらscaleできるframework
      • HTML template: \<template>
      • script template: \<script>
      • CSS: \<style>
        • scoped
          • CSSのscopeをcomponent単位で閉じるapproachは,JavaScriptのcontextで完結するlibraryにはよく見られる
      • まとめ
        • communityの支えるlibraryが数多く存在し実績も多くあるので手に取りやすい
        • 状態管理libraryとしてのVuexや,SSRやroutingなどを網羅したNuxt.jsなどもある
        • component単位で責務をまとめSingle_File_Componentというファイルに集約することで,視覚的・機能的にcomponentが果たすべき領域を捉えられるようになっている
        • 別々に分離されたlayer・責務をcomponentという単位で1つのlayerに統合している点が大きな特徴
    • Angular
      • by Google
      • HTMLとTypeScriptでsingle_page_client_applicationを開発するためのplatform, framework
      • version 1.xとして開発されたAngularJSとは互換がない
      • 開発におけるひととおりのものがそろっている
        • SPAのためのclient routingからfetchしresourceを取得するHttpClientなどapplication開発に必要となるものをmoduleとして最初から持っている
        • command line toolによる開発一式も完備し,codebaseの足場を作るscaffoldやtest runner/unit testの仕組みまで網羅
      • frameworkの概念やarchitectureは盤石 → file 構成や管理方法,細かなtool chainを組み合わせ選定し調査するといった考慮はほとんど不要
      • 公式documentにより指南されたfile構成,style guideが一番参考になる
      • software designやarchitectureの文脈で多少前提知識が必要
        • decoratorによるDependency Injection
        • RxJSでの外部通信など非同期の扱い Observablesといったarchitectureやstreamというsequenceについての理解も求められる
      • webpackとの組み合わせで起点となるfile: entry fileと呼ぶ
        • 例ではmain.ts
        • 起点として階層別にcomponent群を集約する
      • NgModule: app.modules.ts
        • applicationに必要な外部moduleを整理・集約し,下層layerに分配するRole
        • applicationには少なくとも1つのroot moduleが必要になる
      • Component: app.component.ts
        • Angular componentのinstanceを作成しそれが扱う変数やmethodが指定されるほかdecoratorによる記述がある
        • Vueにおけるdata modelやevent handlerなどをobjectとして定義した形と似ている
      • HTML: app.component.html
        • 一部にMustache構文
      • CSS: app.component.css
        • 明示なしでstyle定義がcomponent内にとどまる
      • まとめ
        • Vue.jsと同じく,component baseのUI構築といった構成
        • style guideで理想となる構造を示している
        • 初手から学習領域が広くなる
          • DI, HttpClientなど
    • React
      • by Facebook
      • UI構築のためのJavaScript library
        • UI構築にのみ関心
        • simple view library
          • minimum
      • JSX: JavaScriptの拡張としての表現
        • babel/preset-reactによりruntimeにおいて実行可能なコードにcompile
        • frontend friendlyなcode上の可読性
        • 宣言的なprogramming手法
        • if文による分岐やswitchによる処理フローを記述せずJSXを使用
          • DSLのような表現力を持たせられる
        • markupとlogicを別々のファイルに書いて人為的に技術を分離するのではなく,Reactはmarkupとlogic両方を含む疎結合のcomponentという単位を用いて関心を分離している
      • virtual_DOMという考え方
        • 宣言的な記述がlogicによってのみ更新される
      • Vue.js, Angularとの違い・共通点
        • ReactはあくまでJavaScriptの文脈上ですべてを成立
        • 木構造という概念を意識することなく宣言的なUI表現であるJSXを記述
          • 実際にbrowserで表現される際のUIの一貫性を保てる
        • 3 points
          • all_in_one frameworkではなくUI表現にのみ関心を寄せたlibrary
          • HTML templateではなくJavaScript構文で記述
          • JavaScript context内で完結し変更差分を意識せずにUIに集中できる
    • component指向のframework/libraryであること
      • framework/libraryによりfrontend developmentはcodebaseの一貫性を保てる
      • frameworkの選定には,user数,communityがactiveであることも重要だが,teamの学習状況やmember のskillにあったlibraryを選定することも考慮が必要
      • 捨てやすさ
        • 疎結合,依存性が低い状態で,堅牢かつ柔軟
        • component 1つ1つが疎結合
        • 変更が容易,代替可能
      • 技術的な潮流に求められる柔軟性
        • componentを疎結合に構成しいつでも変更できる状態に保つ → 技術的な環境の変化に耐えうる
      • frontend developmentに求められる要件
        • speed感をもって継続的に変更に対応しながらも,障害やバグを生みにくい堅牢性の高い状態を保つ
        • 変更につぐ変更への耐久性のある,捨てやすさ・変更容易性が強く求められる
      • component指向であることで解決できること
        • framework/view libraryを利用することでteam_developmentにおけるcodebaseの一貫性や保守性を持つことができる
        • 疎結合なcomponentであることで技術的な変更に耐えうる,時間とともに古びたり腐ったりしても変更可能な状態を保てる
        • speed感あるrelease cycleを求められるfrontend developmentにおいて十分な堅牢性と持続性を発揮できる
  • state_management/data_layer: Redux
    • componentをまたぐような横断的な関心ごとは不可欠
    • browserにおけるstate_managementは煩雑
      • browserの状況・動作を考慮しながらbrowserで画面遷移を完結させる動的な実装で考慮するcase
      • user面で起きうることはなかなか網羅しづらい
      • 主たる目的以外に考慮すべき項目が多い
      • user event以外にも,deviceや周辺環境の考慮が必要
      • user actionのlifecycleが長くなるほど,扱うデータもUIの状態も多岐にわたる → solution必要
    • client_MVC
      • 極端に抽象化すると,Model: application data model, View: output, Controller: input
      • contextごとにRoleが多少異なる
        • GUI application
          • Model: 監視しViewに通知
          • View: Modelの値をuserに適切に表示するdisplay interface
          • Controller: user actionを受けてmodelへ変更を伝える
        • server_side framework
          • Model: data structure(DB entityと同義), data操作method
          • View: browserに流すためにModelの値を埋め込んだHTML
          • Controller: requestを受けて処理を振り分けデータ操作methodを呼び出す
    • 簡易的なclient_MVC
      • objectから構成され,singleton instanceが変更される,object_orientedのcode構成
      • event_driven, broadcastを利用したapproach
        • observer pattern
      • View, Controllerがほとんど同義になることも多い
    • frontendで抽象化されるModel, 扱う上での課題
      • Model: GUI applicationがもつ画面に表示・plotするdata modelであることが多い
        • 特にSPAなどでは,一意のendpointから得られるdata source(JSON object)を指したり,それを加工しfrontend用のobjectに整形したりするのが一般的
        • client, frontend固有の表現を実現しなくてはならないdata modelも含まれる
        • server_side frameworkにおけるMVCと違ってDBのentityだけでなく,UIを表現・操作するための抽象化された固有のdata modelもfrontendには必要になる
          • ModelとViewは強く紐づく
        • frontendに転写されるModelと対をなすようなserver_sideのDB entityやAPI endpointの改修がapplicationの基幹的なRoleを担うことが多いため,frontendに課題解決がシフトしがち
        • 双方向のdata_flow
          • 各layerが単一責務を果たすための制約
      • 以上の制約は,複雑になったときにどこでどんな変更があったのか・なぜViewが影響を受けたのか認知の範囲を超える危険性がある
        • 規模が大きくなった際に抽象化されたdataがlayerをまたいで双方向に行ったり来たりすることは懸念が増える要因の1つ
    • RoleがあいまいになるController
      • frontendにおいてはRoleがserver_side以上のものになりうる
      • Controller ≒ Viewのようになり責務があいまいになって,制御しづらく複雑化しがち
    • client_MVCの課題
      • Modelにはserver_sideのdata_modelをAPIを通して投射したmodel, frontend固有のUIを抽象化したmodelが含まれ,Viewにおける関心がModelをまたいで複雑に絡み合っている
      • ModelとViewの変更において密に相互利用しているため,変更起点が不明瞭になりdata_flowが制御しづらくなる
      • ModelとViewは関連性が強い一方で変更が望まれやすく,可用性や変更可能性が求められる
      • Controllerの担う責務が多くRoleがあいまいで,管理や制御が困難
    • → Flux pattern → Redux
    • Fluxというapplication architecture pattern
      • by Facebook
      • frontendに主軸を置くapplication architecture
      • 単一のdata_flowを採用した,MVCとはまったく考え方が異なるarchitecture
      • Action → Dispatcher → Store → View → Action
      • Actionを起点にして一方向にdata_flow
      • 各layer
        • Action: Storeに存在するデータを更新するうえで必要な識別子.合わせて関連するデータも送出.
        • Dispatcher: データを伴って発行されたActionを補足しStoreに送り出すためのAction hub
        • Store: applicationが扱うdata/state. Storeの変更はAction → Dispatcherにおいてのみ変更される.基本的にはJavaScriptにおけるobject
        • View: UIそのもの.Storeの変更通知を受けるための接合点が必要.ViewからもActionを発行する.
    • Redux: dataの一極管理
      • Fluxはarchitecture patternのため,多くの実装が存在する
      • Fluxは複数のStoreを許容するが,Reduxは1つのStoreのみ許容する
        • single source of truth
        • 複数のdata_modelやstateを扱うStoreこそがapplicationが唯一依存すべきtree状のobject
        • DispatcherがStoreに大きく紐づいている
        • Reducerがいる
      • Reducer: 実際にStoreの変更を受け持つ
        • 発行されたActionと現State=今のapplication stateを引数にした関数
        • Reduxの2つの重要な原理を持つ
          • 状態を読み取りのみとして,更新する場合は新しい状態を作成して送出
            • : immutable
            • debug, test容易
          • Reducerは純粋な関数
            • 引数によって新しいStateを返却する冪等な処理の関数
            • Storeを1つのReducerで管理させるところからスタートしても,applicationの成長とともに適切に切り出すことでscaling〇
      • ReducerからapplicationのStoreを作成
        • Reducer 1つがState 1つとなる対の構成となるケースがほとんど
          • combineReducersという複数のReducerを束ねるhelper functionがある
      • ViewがどのModelと紐づくかより,application全体における状態の一部を参照し,変更によって再実行されるという構成
        • Viewと紐づくrender functionがStoreの値を監視し反映する
        • button click時の挙動もModelの直接的な変更ではない
          • 識別されるuniqueなActionを発行しStoreに送り出しているだけ
        • Storeの変更は監視するrender functionの再呼び出しにより順次Viewに反映していく
      • MVC patternのModel/Controllerというlayerの責務・Roleは,Flux/ReduxにおいてはStoreに内包されている
        • Reduxは,messageによるbroadcastをより強固にしたevent_driven architecture
    • Reduxが解決できること
      • 3 points
        • ViewをまたがるModelの変更検知という煩わしさはStoreという唯一のstateをViewにbindすることで解決
        • Storeの変更は,Actionからしか変更できないという制約により状態変更の見通しが立ちやすい
        • Model/Viewの密結合を避けることが可能であるため,可用性や変更容易性に優れている
      • ViewであるcomponentはStoreの値にのみ集中できる点から,疎結合で構成されるcomponent指向のlibraryとの親和性が高い
        • Redux周辺のecosystemを支えている
      • 採用を検討するケース
        • 複数のUI componentをまたぐdata_model, stateの共有が増えてきた
        • release後に変更が多く発生するにもかかわらず開発コストが大きく感じる
  • CSS: CSS meta_language, design手法, CSS-in-JS
    • CSSを取り巻く現状
      • W3Cがまとめている
      • 1~2年単位でmoduleの使用状況をsnapshotとして文書化している
      • browser vendorや開発者communityとどう関わりあっているかがECMAScriptよりも追いかけづらい
    • 各browserの対応状況について
      • Can I use
        • 全体として大きな機能を扱う
          • CSS Grid Layout Moduleなど機能レベル
      • MDN
        • 仕様や詳細なproperty levelを扱う
          • grid-column, grid-templateなど
      • npmにlibraryとして公開されている
    • CSSの表現力を高めたSass,CSS meta_language
      • CSSはsimpleだが表現力が乏しい
      • Sass
        • pre-processorとして変数化やnest構造への対応,style ruleの拡張などさまざまな機能をall_in_oneで備える
        • CSS meta_languageであるSASS構文かSCSS構文を指す
          • SASS
            • indent構文base
              • Rubyとともに発展していたため
          • SCSS
            • CSSのsuper setとして好まれる
      • npx sass test.scss test.css
    • JavaScriptで作成されたPostCSS
      • 構文をparseしAST(Abstract Syntax Tree)を操作するAPIを提供し最終的にCSSを出力するtool
      • pre-processだけでなく最適化などを行える
      • plugin群で,変数化やネスト構造の実現などの機能をそれぞれ単体で提供
        • pluggable, 拡張性が高い
      • Sassの一部の機能だけを取り出し個別に組み合わせたいといったケース,CSS module levelがfixしてbrowser実装を完了したが対応していない下位browserに対してfall backしながら変換したいケースなどに有効
      • e.g.
        • Sassにおける@extendを利用してstyleの継承を行いたい
          • postcss-extend-rule
        • Sassにおけるnest構造によって親selectorの疑似クラスを記述したい
          • postcss-nested
        • 新しい仕様を後方互換性をもって下位browserへfall backしながら実装
          • postcss-preset-env
            • babel/preset-envと名前も役割も似ている
            • vendor prefixの問題も解決する
              • Autoprefixerというlibraryで,通常のstyle propertyに合わせて,vendor prefixのついたpropertyを追加する変換を担当する
                • libraryはCan I useのDBを利用している
            • 具体的に対応させたいbrowser, OS versionはBrowserlistのqueryを書く
    • CSS design手法
      • CSSの大きな特徴であり弱点
        • styleをいつでも(後方から)上書きできること
          • cascadingと詳細度により意図しないstyle崩れが起きる
      • BEM
        • componentという概念とselectorの命名規則を組み合わせたCSS design手法
        • uniqueな名前空間とuniqueなselectorによるstyling
        • Block
          • 独立した構成要素の粒度で1番大きいもの
        • Element
          • Blockを構成する粒度の細かい構成要素1つ1つ
        • Modifier
          • Elementを拡張・装飾するvaliation
        • 厳格なrule
          • Block/ElementはCSS rule内でuniqueな名前空間を持つ
          • cascading selectorを避けてuniqueなselectorを使用する
          • CSS selector内には特定のHTML要素は出現しない
        • styleにはclass selectorを使うことがほとんど
          • ID selectorを使わない
        • uniqueなsingle selectorを要素のclassに付与しstyleを組み上げる
        • HTMLが冗長という負担はあるものの,無記名のHTML要素を廃しそれぞれの要素がuniqueな名前空間を持つことでBlockでまとめたcomponentのscope管理を実現可能にする
        • JavaScript framework/libraryとの組み合わせで解決する手法もある
          • VueのSFCやAngularがもつcomponentへのstyleの適用
          • CSS-in-JSと呼ばれるstyled-componentsなどのReact向けのlibraryは,scope managementによる弱点の補強だけでなく,PostCSSで紹介したvendor prefixの追加や未使用styleの削除も備えている
            • Propsを受け取ってのdynamic style changeなどReactに特化した機能もある
    • CSSの弱点を補うためには
      • postcss-preset-envで利用できるoption: stage
        • ECMAScriptの策定におけるステージ制と類似したもの
  • static_analysis_tool
    • 不整合をsource code実行前に検出し問題を提案するtool
    • 実行せずにcodeの欠陥を予測する
    • あらかじめrule/coding規約をteamに持つ
      • → 無駄な指摘を減らし機械的な指摘ができる
      • → source codeに一貫性をもたらし可読性が上がる
    • JavaScriptはruntimeでのみerrorを検出するため事前に検出が必要
    • Prettier
      • 多言語をfollowするJavaScript製のformatter
      • EditorConfigでformatする場合もある
      • trailingComma, printWidthなど個人のcoding styleによるところが大きい部分をformat
        • printWidthは多言語・記述をフォローしている
        • この強力な機能がPrettierを選択する理由になる
      • codebaseにおける規約やstyleは,teamで合意・納得している状態が,開発を進める中で健全
    • ESLint
      • codebaseにおける細やかなruleをpluggableに追加可能なlinter
        • Lint: 潜在的なerrorを未然に検知し警告すること
      • no-cond-assign
        • より強力
          • .eqeqeq
          • prefer-const
      • no-fallthrough
      • typescript-eslint, eslint-plugin-reactなどの追加ができる
      • 実行前に警告できる + team ruleを投射
      • teamとcodeの成長に合わせて追加できることが重要
    • ほかのlinter/checker
      • npx htmlhint https://example.com
        • HTMLの規格への準拠や規格とは別のruleのチェックもできる
        • 厳密にはlinterというよりvalidator
      • stylelint
        • CSSにおけるlinter
      • BEMの設計手法に頼らず,cascading/詳細度による意図しないstyleの上書きを防ぐために,stylelintのselector-max-specificityといったruleで詳細度を制御することもできる
    • static_analysis_toolが可能にすること
      • 構文のformatをrule化
      • bugの未然検知に役立つような記述ruleやcode styleのrule化が可能になる
      • 3 points
        • 人間による指摘以前に機械的にcode styleやteamのcoding styleを指摘できる
        • code styleの衝突はいつでも起こるもの,事前にteamで取り決めておくことで不要な議論を避けられる
        • static_analysisによってscript実行前にbugの芽を摘み取れる
      • 本質的な作業に集中することを助ける
  • unit_test: Mocha, Jest, Karma
    • テストの種類
      • unit_test
        • programの正常性をmodule単位で検証する
        • 多くは言語に合わせてprogrammable toolやtest frameworkを使う
        • by developer
      • integration_test
        • module同士を結合し動作させ,usecaseからtest項目を作成し実施,正常動作を担保する
        • by developer, test engineer
      • acceptance_test
        • Web frontendのGUIからの操作におけるテスト項目を作成し実施し,正常動作を担保する
        • by QA, test engineer, tester
    • unit_testとfrontend development
      • unit_testは品質の担保という側面より,developerが心理的負担のない状態で安全に開発するために存在しているという考え
        • 安全に変更できることがメインで,おまけで品質がついてくる
    • Mocha, Jest, Karmaそれぞれの特性
      • range
        • Mocha
          • test environmentの提供
          • test framework
          • 監視機能
        • Jest
          • test environmentの提供
          • test framework
          • assertionの提供
          • snapshot test
          • test double
          • 監視機能
          • coverage計測
        • Karma
          • test environmentの提供
          • 監視機能
      • Mocha
        • 別にassertion libraryが必要
          • assertion: testの合否を確認するためのmethod
          • Chaiなど
        • describe: test grouping
        • it: testcase
        • Node.jsのassertion libraryを使った例
        • test frameworkは出力結果にテストが通ったことを表示する仕組みや関数を持つ
      • Jest
        • Jestを使うと,実行環境はNode.jsだがbrowser側のWeb APIをfollowすることができる
          • 必ずしもこれがJestを選択する目的ではない
          • jsdomを利用してWeb APIをfollowしbrowserでの実行をemulateしているため
        • expect
          • matcherの引数に期待する値を設定したり,引数なしのmatcherで期待する値を表現したりするassertionが一般的
            • matcher: chainするmethod
          • mock
          • spy
            • 呼び出された際の引数や結果,呼び出し回数などの情報を格納している
        • 小回りが利きやすくNode.jsのみで実行しやすい
        • 便利なall_in_one test framework
      • Karma
        • unit_testでbrowserを変えたい,browserのJavaScript engineで実行したいという需要のため
        • Angularが提供するcommand line tool
          • AngularはKarma + jasmine
        • test frameworkではなく,unit_testの実行環境を起動するためのrunnerのRoleのみ果たす
        • test frameworkの変更や実行環境の変更が設定により柔軟
    • unit_testやtest frameworkが解決できること
      • release後に変更可用性やspeedを求められるのがfrontend
      • 変更に耐えうるcodebaseや環境を作るためにunit_testのtest frameworkが必要になってくる
      • 必要な部分から必要なだけ始めてみるのもfrontendにおけるunit_test導入のための戦略の1つ
        • 変更が頻出する部分など

Ch04 開発の現場における仕事の進め方

  • agileといった考え方
    • technologyやlifestyleが刻々と変容していくなかで,柔軟な対応が必要になっている
    • source codeやapplicationを変更に耐えうる状態にすること,変更容易性を保った状態にすることが重要
    • agile
  • scrumという開発手法
    • ほかと協調しsoftwareを変更しながら提供し続けることに価値を置くためのagile_development 手法の1つ
    • 学習メモ参照
    • goalに向かって進み続けるproductにおいて,変更要求を受けやすいのがfrontend/client_side
    • application/softwareに寄与するために何を解決するかが重要
    • 個人との対話と他者との協調を繰り返し,動くproduct=applicationを速いサイクルで変化に対応しながらuserに届ける
  • 個人との対話と他者との協調
    • 学習メモ参照
    • communication hubとして
      • 誰もが触れることができるbrowserを主務としているengineerであり,操作や機能要望を一手に担うことが多い
      • frontend_engineerの責務
        • 画面デザインをbrowserで具現化するために実装する
        • server_sideから渡ったdataを使ってbrowserにGUIを組み上げる
        • browser上で正常にapplicationが動作するようにする
      • → team_memberとの合意を経て,browserという職種に依存しないfieldの上で形にしていく必要がある
      • → publicに情報を明確にしてteam_memberと相談しながら開発を前に進める,communication hubのような責務を持つ
  • 変化に対応しながら提供するサイクルを速くする
    • ここまでのまとめ
    • 動くproductを速いサイクルで変化に対応しながら提供するために必要な解決策を持っていることがimportant

Part 2 どう使うかを学ぶ

Ch05 development_environment

  • 既存applicationのdevelopment_environment構築
    • Dockerのinstall
    • Node.jsのinstall
    • Yarnのinstall
    • API serverの起動
      • docker-compose build
      • docker-compose up -d
        • -d: backgroundで実行
    • clientの起動
  • 既存機能の把握
    • どんなapplicationなのかを知る
      • まずdata_structureを見る
      • 機能を見る
    • applicationが抱える課題を探る
      • jQueryのcode
        • DOMへの影響を常に考慮する必要がある
        • すべてのcodeがbrowser event紐づき複雑に絡み合っていく
          • → React, Fluxで解決できる
        • 文字列内に変数を挿入することで書きづらいcodeになっている
      • communityがどれだけ活動しているかやrelease頻度なども技術選定において重要な指標になる

Ch06 設計と実装

  • branchの切り替え: git checkout \<branch>
  • frontend環境の構築
    • Yarnの利用準備
      • yarn init -y
        • package.json, yarn.lockが作られる
    • webpackのinstall
      • yarn add webpack webpack-cli --dev
    • Babelのinstall
      • yarn add @babel/core @babel/preset-env babel-loader --dev
        • babel-loader: webpackでのビルド実行時にBabelのcompileも同時に処理してもらうため
  • TypeScriptの導入
    • TypeScriptのinstall
      • yarn add typescript --dev
      • yarn run tsc --init
        • 公式referenceで必要な設定を選択していく
    • Babel経由でTypeScriptのcompile
      • yarn add @babel/preset-typescript --dev
    • 既存コードをTypeScriptで書き換える
      • yarn add jquery
        • 既存コードが依存しているpackageをinstall
      • yarn add @types/jquery --dev
        • TypeScriptで実装する場合は各packageが提供するAPIがどのような値を返すのかをcompilerが知っておく必要がある
        • Definitely Typedから取得する
      • git mv app.js app.ts
    • compile errorを解消する
      • yarn run lint:ts
        • lint:tsはtsc --noEmitをpackage.jsonに定義
      • 必ず文字列が入っていてほしいものについて明示的に型を宣言する
  • codeの分割
    • 処理を別のファイルに切り出す
      • export, import
  • Jestを利用したunit_test
    • Jestのinstall
      • yarn add jest @types/jest ts-jest --dev
    • jest.configの設定
      • yarn run jest --init
    • 描画されたDOMの検査
      • id, classで判別か,それができなければselectorでDOMをたどる
    • 仕様をテストコードに入れておく → 改修時の確認コストが大きく下がる
  • Reactの導入
    • Reactのinstall
      • yarn add react react-dom
      • yarn add @types/react @types/react-dom --dev
    • JSXのためのcompile設定
      • yarn add @babel/preset-react --dev
    • JSXで要素を表示
    • webpack-dev-serverのinstallと設定
      • yarn add webpack-dev-server --dev
      • fileに変更を加えた際に自動でbrowserに反映
    • jQueryで書いたcodeをReactに置き換える
      • APIとの通信 → stateに保存 → 画面が再描画
    • event_handlerの記述
      • yarn add react-transition-group
      • yarn add @types/react-transition-group
      • react-transition-groupはReact Componentでanimationを実装するためのpackage
      • useState(), useEffect()などのHookを使うことで,大量のコードを書かずに動的な画面を構築できる
        • 独自のHookの作成もできる → 複数のComponentで再利用したい処理の切り出しもできる
  • Enzymeを使ったcomponentのtest
    • Enzyme: React_Componentのテストを補助するためのutility
    • Enzymeのinstall
      • yarn add --dev enzyme @types/enzyme enzyme-adapter-react-16 @types/enzyme-adapter-react-16
    • Jestの設定
      • jest.config.jsにEnzymeの設定を追加
        • setupEnzyme.tsをJestが読み込むように設定
      • Jest実行時にJSXのcompileができるよう修正
        • yarn add babel-jest --dev
        • yarn remove ts-jest
        • babel-jestはbabel.config.jsを見にいく
    • React_Componentをテストする
      • Enzymeのrendering方法
        • shallow(): child componentは描画せず,引数に与えたcomponentのみを描画する
        • mount(): jsdomなどのDOM emulatorを利用してchild componentを含んだ状態でDOMにmount.React lifecycle methodも呼ぶ
        • render(): child componentを含んだ状態で描画するがlifecycle methodは実行されない
      • → 表示結果の確認だけならshallow()/render(), lifecycle内で処理した結果をもとにDOMを構築しているようなcomponentではmount()
      • mock機能
        • mocks/(filename)にmock用のfileを置く
        • APIとの通信などにmockを用意する
        • act()でEnzymeの描画実行をラップ
          • Hookをテスト対象のcomponentが利用していた場合にテストが実行できなくなる問題の回避方法
  • styled-componentsの導入
    • componentとstyleをセットで扱う
      • styleがcomponent内に閉じ込められる → CSSのscopeや命名の重複などを気にしなくてよくなる
    • styled-componentのinstall
      • yarn add styled-components
      • yarn add @types/styled-components babel-plugin-styled-components --dev
      • babel.config.jsに追加
    • CSSからstyled-componentsへの移行
      • styled.(要素名)という指定でcomponentを生成できる
      • CSSの記法がそのまま利用できる → 移行が容易
      • animationの実装ではkeyframesというhelperを使う
        • 変数に格納しておくと使いまわせる
      • animationのようにstyleの定義も使いまわす → cssというhelperを使ってstyleだけを変数に格納し,複数のcomponentに反映することもできる
      • 大規模なapplicationでより重宝される
  • 目的
    • 開発効率を上げてreleaseまでのlead timeを短くするために開発基盤を整備し,開発者が安全にコードを変更し運用していくために型の導入やunit_testを作成している
      • まずは足場を固めて自由度の高いcodebaseを作る

Ch07 CI/CDによって受けられるmerit

  • workflowに自動検出を導入し安定したapplicationを提供しながらどのようなmeritを受けられるか
  • CI/CDによって受けられるmerit
    • lint, test, compileなどを自動化
      • 理由
        • developerの手動負担を抑える
        • development_processのあり方の変化
          • agile
            • 安定した定期的なreleaseのためには自動化された安全性の確認が非常に重要
    • CI/CDについて
      • 各tools
    • GitHub Actionsを始める
      • YAML
        • indentと文字列といくつかの構文によってobjectやdata_structureを表現できるファイル形式
        • JSONXMLと違い構造表現のための修飾語句がindentによる構造化で代替され,一覧しやすく視認性が高い
      • .github/workflows/xxxx.yml
      • compile可能か,unit_testがすべて通るかをrepositoryのactionに合わせて動作させていく
      • workflowごとに設定ファイルを持つ
      • branchやgit上のファイルの変更検知の指定もできる
      • OSによって実行時料金に倍数がかけられる
    • ESLintを導入し動作させる
      • yarn add -D eslint eslint-plugin-react eslint-plugin-react-hooks @typescript-eslint/eslint-plugin @typescript-eslint/parser prettier eslint-config-prettier eslint-plugin-prettier
      • 都度思い出すよりも,作ったものを自分のrepositoryにおいて参照したり,template化したりしておくのが〇
      • package.jsonにaliasを追加
      • YAMLファイルへ追加
    • CIで自動化するmerit
      • 手動操作やreviewでの疲弊を回避
      • development_processが健全になる
      • product code自身も健全性を維持できる
      • 安心感
    • CI: 安定したapplicationを効率よくuserに届ける仕組みであるとともに,本質的なdevelopmentに集中できる
  • performanceと改善
    • backendでHTML documentのresponseを返すlatencyが大きい
      • ↑ Performance/Network tabで確認
    • frontendでJavaScriptファイルのサイズ肥大化やscriptがUI構築のblock要素になっている
      • Performance tabで計測後Long taskの警告数が多いかどうか確かめる
      • 50ms以上で警告
    • performanceの問題とは
      • 新規開発
        • developerの関心の薄さや非機能要件の認識不足に起因する
      • release済
        • userの問い合わせで発覚することが多い
        • 定期的な計測が必要
      • performanceだけを意識する必要はない
    • 基礎的なperformance知識: critical_rendering_path
      • 早い段階での画面描画のspeedが重視されている
        • conversion rate, 直帰率の低下, 滞在時間の長さ, 同セッションでのpage viewの多さにつながる
      • critical_rendering_path: 初期描画に必要なresource/step
        • Reactを使ったclient_side renderingの実践では,loading中のUI提供をする限り初期描画が問題になることはあまりない
      • critical_rendering_path: CSS
        • 初期描画に必要なCSSだけ切り出す
          • CriticalというNode.jsのtoolを使う
        • 膨大なCSSであればcoverageを計測して不要な部分を削除する
          • Developer_Toolで計測できる
      • critical_rendering_path: JavaScript
        • 初回画面構築に不要なら,headではなくbody tagを閉じる手前に移す
          • async: download後のscript実行時はblock
          • defer: 画面構築に影響がないときに〇
      • Lighthouseを利用した定期的なperformance計測
        • 根本原因を探ることが難しくなることがある
        • → 定期的な計測・検知の仕組みを整えて計測結果を得ることが重要
          • CIで定期的な計測を実行する
        • Core Web Vitals
          • Largest Contentful Paint(LCP)
          • First Input Delay(FID)
          • Cumulative Layout Shift(CLS)
        • 指標の判断は各々
      • Lighthouseを利用する
        • npx lighthouse ...
        • goal: outputを知り目標とする数値を超えていないかを検知して知らせること
          • lighthouse-ciを使ったaction: treosh/lighthouse-ci-action
      • 新しいworkflowを追加する
        • GitHub Actionsではworkflowを物理ファイルで分けられる
          • .github/workflows/lighthouse.ymlを作成
        • 特定のmetricsや閾値の設定
          • .github/workflows/lighthouserc.jsonを作成
          • total-blocking-time
            • audits -> total-blocking-timetotal-blocking-time -> numericValue
          • Interactive
            • 操作性のため
            • 値はある程度サンプルを取って閾値の参考にする
        • uploadArtifacts: true
          • 結果reportをdownloadできる
        • Developer_Toolからtrace可能なreportがほしいときは,lighthouseを使うのも〇
          • --save-assets optionが必要
        • puppeteerというChroniumをheadlessで動かすtoolとlighthouseを使って簡単にscriptの実装ができる
        • Datalogという監視やmonitoringのためのSaaSで数値をplotして可視化もできる
    • 強力な武器はない,人には人のperformance
      • performanceは1つの指標に過ぎない

Ch08 analysis, monitoring

  • serviceの成長とともに開発する
    • 保守・運用: product, serviceを成長させていくphase
    • 数字として可視化して目標と比較するために,計測する仕組みとしてanalysis_toolやAB_testが導入されることが多い
    • 計測のための実装やAB_testの実施もfrontend_engineerの責務
    • 仮説検証,AB_testの目的
      • 仮説検証
        • personaを使って施策の議論や価値提供の優先度を考えることも多い
        • analysis_toolの導入により,目標値に向かうためのuser actionをある程度可視化できる
      • AB_test
        • personaから推察される行動を考え仮説を立てて,短いiterationで立証するため
        • marketingにおける調査・試験の一種
        • GUIにおけるpatternや組み合わせで立証することが多い
      • UIや使い勝手,操作性などclient接点における価値をすばやくuserに届け仮説検証を行うことが,analysis, AB_testの目的になる
    • toolの導入: Google_analytics
      • 計測のためのsnippetを導入するだけでデータの可視化や計測がいちはやく手に入れられる
      • Google_marketing_platformの1 product
      • analyticsの利用登録
      • 計測のためのtracking code
      • eventの計測,属性の追加
        • ラップしたようなevent送信用の関数を作る
        • service 1つに対してproperty 1つ
      • 重要
        • action nameやcategory, label nameなどをteamで設計し,memberが共通理解を得ること
    • toolの導入: Google_optimize
      • AB_test用のtool
      • html code → p.211
      • 振り分けの完了は,Cookieの_gaexpの値の末尾を見るとわかる
    • product codeに組み合わせる
      • ReactのHooks APIを利用した実装方法
      • UIと振り分けを宣言的にする
      • Reactが実行される段階ではtest patternは決定している
    • third_party scriptとの兼ね合い
      • client performanceにはいくらか影響が出ることに注意する
      • AA_testで導入によって数値に影響が出ないことや実際に振り分けが行われることを確認する
      • toolの導入における懸念事項の洗い出しや組み込んだ場合の結果の提供もfrontend_engineerの責務
  • user_monitoring, error_event_monitoring
    • 障害や問題をrealtimeで検知する仕組みが必要
    • userを取り巻く環境を知る
      • Developer_Tool
        • network状況をemulate
        • specをemulate
      • analysis_toolでまずuserの環境・状況を知ることがimportant
    • browserで起きるerror_eventなどからuserを知る
      • runtime error
      • network error
        • 不通時のfeedbackが必要なusecase
          • UIからmessaging
          • onlineかどうかのstatusを取得するためのAPIがある
      • Cookieが利用可能かどうか
    • error_event_monitoringのため,Sentryを導入
      • yarn add @sentry/react
      • 設定できること
        • error_eventへの緊急度levelの設定
        • error_eventの閾値超えによるalert(各種tool連携)
        • release versionやuser definitionのmeta information付与
        • sourcemapを利用した影響のあったsource codeの表示
      • documentが豊富
      • team全体で導入する
    • Sentryの動作とcodeへの組込
      • global scopeにおける例外handler
        • top levelに繰り上がった例外をさばいている
      • 事前に用意できるものは個別に準備しておく
    • React Error Boundaryを使う
      • fallback UIをuserに提供できる
      • error_eventのlogも取れる
      • 昨今のReactでの開発は関数としてcomponentを実装するが,Error Boundary componentはclass baseの componentである必要がある
    • 収集したerror_eventを役立てる
      • errorとして収集して対応したものも,情報として収集を続ける必要があることもある
        • Cookieの使用状況など
        • error_eventのlevelづけ
      • error_eventの発生ログは,大きな判断材料になる
        • この数字がteamでの対応優先度を決めるのに一番良い判断材料になる
        • product_backlogに追加も〇

Part 3 応用編 より深く学ぶために知る

Ch09 team_developmentとWebへの貢献

  • teamで働く
    • Scrumという開発手法について(あらためて)
    • Scrumを採用したteamに入ったら
    • story: sprint_planning
    • story: sprintの開始
    • story: sprintの終わり
    • team_developmentとはtechnical skillではない
  • communityへの貢献活動
    • OSSへの貢献はcode_commitだけではない
      • bug report, document修正, 簡単なpull_requestから始めてもよい
      • communityをのぞいてみる,issueを立てる
        • CONTRIBUTION.mdのようなdocumentに,貢献の方法や何から始めるのが良いかが書いてある
        • CODE_OF_CONDUCT.mdで行動規範を掲げているものもある
      • 機能報告・bug報告の方法
        • まずは,OSSのrepositoryにあるissueを検索し,類似した内容の有無を確認
        • bugの再現状況の追記なども〇
        • templateを使う
    • できることからOSSへcommitする
      • 各issueにはlabelがある
    • 寄付する,翻訳するといった違ったapproach
    • Webというplatformに貢献する
      • Webというplatform: Web site/applicationを開発するためのHTML,CSSJavaScriptの標準化されたtechnology群
      • Webは維持し続けることがimportant
      • product_codeを健全に保ち周知していくことも,小さな規模だがteamへの貢献になる
  • Web platformにかかわるfrontend_engineerとして
    • 仕様を知るには
      • W3C, WHATWG, WICG, Ecma_international, IETF
      • IETF
        • internet technologyに所属する様々なworking groupを持つらしい
        • RFC
      • 仕様は複合的に見る
        • それぞれにRoleがある → p.259
      • 重要な点は,どの仕様についても標準化前に実験的にbrowserへ導入され改善が繰り返されることが多い
    • lightにcatch_upする
      • 何かを知るきっかけを作る
        • twitter
          • W3C: twitter.com/w3cなど,各種フォローできるアカウントがある
          • 客観的な視点がないため,何にfocusするか判断が難しい
        • curationを行い配信しているnews letterを購読してcatch_upも〇
          • できれば複数のnews letter
      • 必要かどうかはさておきとりあえず目に入れておく,程度の軽いstanceで〇
  • frontend technologyを楽しむために
    • 動くproductを早いcycleで変化に対応しながらuserへ届けるために,必要な解決策を持ち実現できることがより重要
    • 実現できることよりさらにproductに反映できることが重要
    • Webへの興味関心を持ち続ける
    • 変化が早く感じるときは,情報を見過ぎている可能性を考える
      • enduserはdeveloperではない
    • userの課題を解決するために,userへの価値提供のためにWeb platformを使ってdevelopmentを進めていく・課題を解決するということに,意識的であることや楽しむことがfrontend開発において大切

『入門React: コンポーネントベースのWebフロントエンド開発』学習メモ

Part 1 基礎

Ch01 Introduction

  • 背景
    • React: XHPというPHPのframeworkのJavaScriptへの移植
      • 毎回ページ全体を書き換えるというPHPのstyleが備わっている
      • 本質的にstate machine
      • 責任: MVCのうちViewのみを見る
        • DOMの更新
        • eventへの反応
      • Virtual DOMという強力なRendering system ←→ 一般的にDOMへのaccessは低速
      • 描画の手順を細かく管理する必要がなくなる
      • 単一のevent handlerで,application内で発生するすべてのeventを監視

Ch02 JSX

  • Separation of concernsのために,Componentを使う ←→ templateと表示logicといった分離
    • Component: Markupとそれを生成するcodeが強く結びついたもの.Reactの中心的な概念.
  • What's JSX
    • JSX: JavaScript XML
    • ReactのComponent内でMarkup言語を記述するためのXML風のsyntax
    • 特徴
      • JSXはsyntax拡張.(あとでJavaScriptの関数呼び出しに変換される)
      • JSXはruntime libraryが不要
      • JSXはただの関数呼び出し
  • JSXのmerit
    • 既知の構文
    • 意味的な分かりやすさ
      • JavaScriptのcodeをよりsemanticで意味のあるMarkup言語で記述できる
      • Componentの構造と情報のflowはHTML風なsyntaxで宣言的に記述
      • applicationで定義されたcustom Componentをタグ名として使用〇
    • 構造の可視化
    • 抽象化
      • projectの進展に伴うcodeの変更を減らす
    • Separation of concerns
      • Component内のMarkupとBusiness Logicを分離
  • Component合成
    • custom Componentの定義
    • dynamic value
    • child node
      • this.props.children: start-end tag内の全子nodes
  • JSXとHTMLの違い
    • JSX: ECMA Sctiptの1機能
      • XMLとの類似: 単に親しみやすさのため
    • attribute
    • conditional branch
    • DOMに存在しないattribute
      • key
        • reuse/破棄を賢く行う
          • → 描画performance〇
      • ref
        • 親Componentが子Componentのrefにaccess
        • hacking instance
      • dangelouslySetInnerHTML
        • できれば使わない
      • event
        • explicitなbindは不要
      • comment
        • 子node
        • inline
      • class, for
        • → className, htmlFor
      • style
  • JSXなしでReactを使用したい場合
    • ReactElementの作成
    • 簡略化
  • 参考文献

Ch03 Componentのlifecycle

  • Component: state machine → inputに対して常に同じoutput
  • Component作成時に呼ばれるmethod
    • Componentのinstance作成~初回描画
      • Componentを利用可能にするための設定
    • getDefaultProps
      • Componentにつき1回のみ
      • 非scalar値は共有
    • getInitialState
      • instance作成事
      • ここからthis.propsが利用できる
    • componentWillMount
      • 初回の描画前
      • renderの前にComponentのstateを変える最後の機会
    • render
      • Virtual DOM(Componentのoutput)を作成
      • ReactのComponent中で唯一省略できないlifecycle method
      • rules
    • componentDidMount
      • React.findDOMNode(this)でDOMにaccess
      • raw DOM nodeにaccess
        • 要素の高さ,timer, jQuery, pluginなど
          • e.g. ReactのinputとjQuery UIのauto complete
  • Component作成後に呼ばれるmethod
    • componentWillReceiveProps
      • 親Componentがpropを変更したとき
    • shouldComponentUpdate
      • optimezeのためにある
      • develop時には使わない.tuningで使う.
      • PureRenderMixinでperformance tuneも〇
    • componentWillUpdate
      • state, propsの更新は×
    • componentDidUpdate
      • 変更されたDOMのreferenceへのaccess
  • Component破棄時に呼ばれるmethod
    • 不要になったらReact DOMから切り離してdelete
    • componentWillUnMount
      • deleteの直前
      • 後処理できる
        • timer, event listenerなど
  • anti pattern: 加工された値をstateに保存する
    • a single source of truthの原則 @React
      • → 単一のinformationのcopyが可能になる
    • e.g.
    • initialValueはOK
  • まとめ
    • lifecycle method: applicationがComponentのeventにeffectiveに反応できるようdesign
    • 各Component: state machine.一貫して安定した予測可能なmarkupをoutput

Ch04 data flow

  • 基本は親から子への一方通行
  • Component: 親からのpropを描画
    • propの変更 → propを参照する全Componentが再描画
  • 内部state: Componentの内部でのみ変更可能
  • Component: propsとstateをinput, Virtual DOMをoutputする一種のfunction
  • props
    • props: Componentに渡される任意のdata
    • setProps: 子Componentに対して呼ぶか,Component treeの外側で呼ぶのみ
    • Componentは自身のpropsを変えない
    • JSXでのpropsの指定
      • ...: 後に続くObjectをその場に展開
    • event handlerの格納も〇
    • propTypes: propsとして渡された値をvalidate
      • Componentの仕様が明確になるため,使用推奨
    • getDefaultProps
      • React.createClass時にキャッシュ
  • state
    • Componentの内部でのみ使用
    • 要素の表示内容の決定に使う
    • getInitialStateっでinitialize
    • setState
      • 必ずrender()を伴う
      • directにthis.stateの変更は絶対×
    • なるべく一部のComponentのみ
      • 複雑になるため
  • stateとpropsの使い分け
    • stateはComponentの機能にdirectに必要な単純なdataのみに〇
    • propsの値をstateにcopy×
  • まとめ
    • prop経由でCompにdataを渡し,tree全体に伝播
    • propsはimmutableとして扱う(Component内)
    • 子Componentとのやりとりのために,event handlerをpropsに指定
    • 表示内容を決定するためのsimpleなdataのみstateに保存可能
    • this.setStateを必ず使う

Ch05 event_processing

  • UIの半分は表示,残りの半分はuserのinputに反応すること
    • JavaScriptで,userのinput eventに応じたevent_handlerを記述する
    • Reactでのevent_processing
      • まずevent_handlerを登録
      • handlerが呼び出されたときにcomponentのstateを変更する処理を記述
        • render method内でstateを参照しさえすれば,変更は自動的に描画に反映される
      • 追加の情報は,event_handlerに引数として渡されるevent objectが追加の情報を含んでいるので,それをもとにstateを適切に更新できる
  • techniqueとReactの高性能なRenderingの仕組みにより,容易にuser inputに反応してUIを更新できる
  • event_handlerの登録
    • onClick
  • eventとstate
    • たいていはsetStateで既存のObjectにマージする
    • Object変更時は必ずsetState/replaceState
  • event_object
    • event.target.valueからformのinputを取得
      • 特にonChangeでよく使われる
  • まとめ
    • Reactでuser inputをUIに反映させる手順
      • React componentにevent_handlerを登録する
      • event_handler内でcomponentのstateを変更する.stateを変更するとcomponentは再描画される.
      • componentのrender method内でthis.stateを参照するように変更する

Ch06 componentの合成

  • HTMLではpageは要素から構成されるが,Reactではcomponentから構成される
    • ReactのcomponentはHTMLの要素にJavaScriptの表現力が追加されたもの
  • component: propsとstateをinputとして受け取り,HTMLを出力として返す一種の関数のようなもの
    • 各componentはapplication内のデータの一部を表示するために設計されている → React componentはHTMLの拡張といえる
  • HTMLの拡張
    • lifetimeを通じて,React_componentは振る舞いをcontrolできる
    • React.createClass
    • 継承より合成
      • 小さくて単純なcomponentを組み合わせて,より大きくて複雑なapplicationを構築する
  • 合成の例
    • has aで表現できる
    • 汎用的なinput要素から初めて,radiobuttonにcustomizeし,多肢選択の機能を提供する例
      • original form controlのcomponentの作成
  • 親子間の関係
    • 親child_componentでの通信の最も簡単な方法: propsを使う.親がcallback functionをpropsとして渡して,子がそれを呼び出す
      • child_componentの変更に対する振る舞いを定義
  • まとめ
    • Reactにおいて合成のpatternを使用する手法
      • HTMLの要素や自信のcustom componentをwrapして,必要に応じてそれらの機能をcustomizeすることで,componentを作成する
      • 汎用的なcomponentは,合成のたびに特化され意味を持ったものになる
    • Mixin: 合成以外の方法 → 次章

Ch07 Mixin

  • Mixin: 複数のcomponent間で共有可能なmethodを定義できる
  • Mixinとは
    • Mixinを使ったTimer componentの実装
    • componentにmixinsというpropertyを定義する
    • 制限
      • 複数のタイマーは持てない
      • Timer eventのhandler methodの名前はonTickに固定
      • タイマーを止めるには内部の__interval propertyにアクセスする必要がある
    • → コードは増えるが修正できる
    • 適用例
      • eventを監視してstateを更新するMixin(e.g. FluxのStore Mixin)
      • XHRのuploadを行いprogressをstateに反映するMixin
      • child_componentをの末尾に表示するためのlayer Mixin(e.g. modal dialog)
  • まとめ
    • Mixin: codeの重複を避けるために有効な手段
      • componentは自身に固有の責務に集中できる
      • 強力な抽象化の手段を提供
      • ある特別なふるまいや役割をcomponentと切り離して記述できるので,codeはより理解しやすいものになる
        • Mixinとして定義できないか常に検討する

Part 2 応用

Ch08 DOM操作

  • 通常はReactの提供するAPIだけでUIを構築できるので,実際のDOMに直接アクセスすることはほとんどない
    • componentを合成することで,複雑なUIをまとまった全体としてuserに提示できる
  • Reactとともに使用することを想定していないthird partyのlibraryを導入する場合や,Reactで非supportのDOM操作を行いたいときがは,DOMへのアクセスが必要になる
    • componentのlifecycleの特定の局面でしか利用できないという制限あり
  • DOM_nodeへのaccess
    • まずそのnodeを表現するcomponentにアクセス
      • componentにref属性を設定して実現する
        • ref属性はcomponentのすべての子nodeの中でuniqueである必要あり
          • ほかの子nodeのref属性と重複は×
      • → componentDidMountの中で,React.findDOMNode()を使って実際のDOM_nodeにアクセス
        • event_handler中でも〇
    • どうしても必要な場合以外は使わない
      • Reactが内部で行う最適化の妨げになるうえ,applicationが複雑化する要因になる
  • React friendlyでないlibraryの使用例
    • オートコンプリートlibraryの例
  • 行儀の悪いlibrary
    • 自身がアタッチされた要素の内容を,カスタムイベント経由で変更してしまうpluginの例
      • 親の要素まで変更する場合は対応できないので,Reactとの併用はできない
      • Reactを守るために,pluginの使用するDOM_nodeを完全にcontrolする必要がある
        • componentDidMountの中で独自に要素を作成し,renderで作成された要素の子nodeとして追加する
        • 不要になった際は自分自身で削除が必要 @componentWillUnMount
          • pluginのdocumentをみて,ほかに必要な手順がないか確認する
            • global event_listenerやtimerやAJAX requestなど
        • Reactに管理されていないdivの描画の更新
          • 確実: componentを疑似的にpageから削除して追加する
          • 簡潔でperformance〇: pluginの更新用のAPIを呼び出す
        • ごく単純なpluginの場合は,同じ機能を提供するReact componentを作ってしまった方が早いこともある
  • まとめ
    • Reactが提供するAPIだけでは不十分で,どうしても実際のDOMにアクセスしなければいけない場合がある
      • ref属性を設定して,特定のcomponentにアクセスし,そのcomponentの実際のDOM_nodeへの参照をReact.findDOMNode()経由で取得する
        • componentDidMountが呼び出されてからでないとアクセスできない
      • → ReactがサポートしていないDOM操作や,Reactとともに使われることを考慮されていないthird partyのlibraryの使用が可能になる

Ch09 form

  • single_page_applicationでは,formを正しく扱うのは至難
    • user inputにより扱うべき状態が一気に増えるため
    • formの複雑な状態の管理のために,Reactを使える
  • React_componentの主要な側面
    • 動作が予測可能であること
    • testの容易さ
    • ↑ 同じ内容のpropsとstateで描画を行った場合,常に同じ描画結果を出力するというReact_componentの特徴のため
  • Reactのformのcomponentには,管理された/されていないcomponentの2種類がある
  • 複雑なformを扱う場合などは,DOMにアクセスが必要になる
  • 管理されていないcomponent
    • 複雑なformに向いている
    • 直接DOM_nodeにアクセス
    • formはほかのReact_componentと異なる動作
      • 値は要素が管理し,formは管理しない
      • DOM_nodeに直接アクセスが必要
        • ref: React独自の特性
    • validationや入力制御を行う必要がないformに向いている
  • 管理されたcomponent
    • 通常のReact_component patternを踏襲する
    • valueをcomponentのstateとして保持することで,React_component自身がform stateを管理する
    • formを完全にcontrolしたい場合
    • dataflowが明確になる
    • codeは増えるが,データが入力されるたびにstateが変化するため,dataflowを完全にcontrol〇
    • data input中にほかのcomponentの値の参照も可能
  • form event
    • event: form stateのcontrolに欠かせない
    • HTMLで発生するすべてのeventに対応
    • target property経由で,発生元のDOM_nodeにアクセスできる
      • targetを参照することで,管理されたcomponentにおいて,user inputにアクセスできる
  • label
    • radiobuttonやcheckboxの意味をuserに伝える
    • htmlFor @JSXがHTMLのfor属性
      • classをclassNameと扱うのと同じ理由(予約語)
  • textareaとselect
    • 統一性と使いやすさのために,original HTMLの仕様から変更されている
    • select
      • 複数選択が有効だと,child_componentのoption要素のselected propertyのみ変更される
  • checkboxとradiobutton
    • checked属性をcontrolする
  • form要素のname属性
    • 基本はあまり重要ではない
    • 欠かせない場面
      • formをseriarizeするthird_partyのpluginをReactとともに使うとき
      • submit eventを横取りせずにbrowserに処理を任せるとき
      • browserのauto complete機能はuserのmail addressなどを提示するためにname attributeを使う
      • 管理されていないradiobuttonの場合,同じname属性を持つ要素同士は同時に1つしか選べないのがdefault動作
        • 管理されたradiobuttonでは,event_handlerで処理を行い同様の動作を実現
  • 複数のform要素とchange event_handler
    • change event_handlerの再利用の方法・例
      • bind経由でevent_handlerに追加の引数を渡す
      • event_handler内でDOM_nodeのname attributeを参照する
      • React.addons.LinkedStateMixinも異なる方法で解決する
        • linkState method
        • form input valueを親componentのstateとして保持する場合は,とてもsimpleになる
        • dataflowを細かく制御したい場合は,かえって複雑になる
  • custom form component
    • checkbox, radiobuttonなどの複雑なcomponentのinterfaceを改善するためにも使われる
    • ほかのform componentとinterfaceを合わせる
      • 可読性のため
  • focus
    • formへのfocus設定: userが次に取るべき行動を明確に伝える良い方法
      • 使いやすさも〇
    • autoFocus attribute
    • focus()
  • usability
    • 要求を明確に伝える
      • label: formの要素が何を期待しているのか伝えるRole
        • radiobutton, checkbox
        • placeholderよりも,labelやpopupが〇
    • inputに即座に反応する
      • validation
        • 最善のtiming: input要素のblur event発生時
      • 処理中であることを示す
      • transition, animation
    • performance
      • transition, network delayなどによる動作の遅延について
      • 速度は相対的かつ体感的
        • 速いように見せることがimportant
    • predictable
      • platformのdefault 動作に準拠するか,userの操作をまったく異なったものにする
      • 一貫性
        • platformの標準動作に準拠
    • accessibility
      • 試しに単一のinput deviceでapplicationを操作してみる
      • Accessible Rich Internet Applications(ARIA)
      • Accessibility Developer Tools
    • input項目数の削減
      • usability〇
      • 実際の項目数よりも,userがどう感じるか
        • input項目を複数の小さいformに分割
        • autocomplete
        • autoFocus
  • まとめ
    • Reactでは,form state managementはDOMではなくcomponentで行う
      • form要素の動作を完全に制御
      • application固有の複雑なcomponentを作成できる
    • formはapplication内で最も複雑な操作を必要とする
      • form design時にはusabilityに配慮が重要

Ch10 animation

  • applicationを洗練されたものにするための方法
  • animation: user_experienceを滑らかで自然なものにする効果がある
  • CSSTransitionGroupというアドオンをCSS3とともに使用する → 簡単にanimationを追加
  • 初期はimperative(命令的)だった
    • DOM要素に直接accessして座標値などのstyleを絶え間なく更新
  • → ReactではCSS animationを利用した,よりdeclarativeな手法
  • CSSTransitionGroup
    • CSS animationを使ったtransitionを簡単に行うためのアドオン
      • transition: 表示物をある状態から別の状態に継ぎ目なく遷移させるUI effect
    • 内部的には,render method呼び出しの中で適切にCSSのclassを追加したり削除したりすることでanimationを実現している
      • developerは,それらのclassごとにCSSのstyleを定義するだけ
  • CSSを使わずにJavaScriptのtimerを使ってanimationを行うこともできる
    • CSSよりさらに柔軟だが,負荷は高くなる
    • 再描画の負荷が高くなるが,scrollのanimationやCanvas描画など,CSSでは実現できないようなanimationを実現できる
  • CSSを用いたanimation
    • CSSTransitionGroup
      • transitionの適用対象となるcomponentのgroupを表し,componentが追加/削除されるたびに自動的にCSS_styleを切り替えてanimationを実現する
    • transitionのclassごとにstyleを記述する
      • componentのtransitionName attributeの値に基づいて,4つのCSS class名が作成される
        • -enter, -enter-active, -leave, -leave-active
    • transitionのlifecycle
      • -enter classがchild_componentが追加されたときに適用され,すぐに(次のanimation frameで) -enter-active classが適用される
        • transitionの開始時と終了時のstyleおよびそれらの間をどのように遷移するか定義できる
      • transitionEnter={false}とすると無効にできる(transitionLeaveも同じ)
        • 上位のcomponentからprop経由で設定もok
    • よくある過ち
      • leaveのanimationが完了するまでchild_componentは削除されない
      • child_componentのkey attributeはtransition group内でunique要
  • timerを用いたanimation
    • 古いbrowserに対応したり,ScrollのanimationやCanvas描画などを扱いたい場合
    • CSS3のanimationよりperformance ×
    • componentのstateが定期的に更新される
      • stateはanimationのtimelineの中での現在位置を保持する
      • render method中でこのstateの値を参照することで,applicationは適切なanimationのframeを描画できる
    • 頻繁な再描画を行うので,timerのAPIとして一般的に効率的とされているrequestAnimationFrameを使う
      • 代替: 効率で劣るsetTimeoutを使うしかない
    • requestAnimationFrameを使ったanimation
      • position: absolute
        • 要素のstyleのleftとtopの値を時間の経過とともに更新する
      • componentWillUpdate handler内で呼び出す例
    • setTimeoutを使ったanimation
      • これらのときはsetTimeout
        • requestAnimationFrameは少ないoverheadで滑らかなanimationの効果が得られるが,古いbrowserでは非support
        • 絶え間なく呼び出されるのが煩わしいときもある
      • React Tween State
        • Open Source Library
        • 汎用的なanimationのAPIを提供
  • まとめ
    • Reactを使った以下のanimationを見た
      • CSSTransitionGroup addon
      • requestAnimationFrame
      • setTimeout

Ch11 performance_tuning

  • Reactの差分描画のalgorithmは優れているので,UI全体を入れ替えたとしても実際のDOMの描画は最小限に抑えられる
  • 深くnestしたcomponentなど,delicate tuneが必要な場面では,virtual_DOMの不要な入れ替えを避けることでperformance改善〇
  • React componentの簡単な設定により,applicationのperformanceを改善する方法を見る
  • shouldComponentUpdate
    • shouldComponentUpdateで,Reactにcomponentのlifecycle methodを呼び出す必要があるか教える
      • falseならrender methodを呼び出さず,描画済みのvirtual_DOM objectをそのまま使う
      • defaultはtrue
      • 初回描画時は呼び出されない
      • 新しいpropsとstateを受け取るので,それをもとに決定できる
    • componentがpure(同一のpropsとstateに対して常に同じ内容のDOMを描画する)であれば,React.addons.PureRenderMixinを使える
      • shouldComponentUpdateを上書きする
      • Mixinを定義するだけでいい
    • propsやstateが複雑なobjectである場合は,比較そのものが重くなりうる
    • → immutable data_structureを使うか,helper_functionを使う
  • immutablility helper_function
    • React.addons.updateというhelper_functionにより,簡単にimmutableなdata_structureを使用できる
    • first argument: object/array, second argument(option): hash object
  • bottleneckを調べる方法
    • React.addons.Perfを使うとわかる
      • Developer Toolsのconsoleから,React.addons.Perf.start(); (終わるときは~.stop();)
      • → ~.printWasted();でprofile結果を表示
      • Wasted time: renderが呼び出されたにもかかわらず,実際のDOM内容が変わらなかった処理にかかった時間をcomponentごとに集計したもの
  • key attribute
    • componentのclassよりさらに細かくinstanceを識別できる
    • 不要な処理を避けるために使う
      • key attributeの値が変更された場合,差分計算を行わずに即座にchild_componentを含めたすべてのvirtual_DOM objectを破棄し,一から再描画する
      • listの要素の順番が変わったことをReactに伝える
        • → 移動だけで済むようになる
        • こちらの目的で使われることが多い
    • 制限事項
      • 同一階層のcomponent, 同一の親を持つcomponent間でunique要
        • 要素が現在のparent_componentのlistと別のlistに移動したときは,同一性の追跡不可能
      • component内部からpropsの値として参照できない
  • まとめ
    • shouldComponentUpdateを使用してperformanceを改善
    • React.addons.Perfを使用して不要なrender呼び出しを特定
    • key attributeを使用してReactの処理を最小化

Ch12 server_side_rendering

  • 以下の問題への解決策
    • search_engineのindexの対象にならない
    • JavaScriptのロードを完了してからページを作成するので,初回のページ表示が遅い
  • virtual_DOMのため,server_side_renderingが可能
    • virtual_DOM: 単なるmemory上のdata_structure
  • server_sideでvirtual_DOMを実際のDOMに反映する代わりにHTML文字列として出力する
    • → 同じReact_componentをclient_serverで共用できる
  • React.renderToString/React.renderToStaticMarkupの2関数
  • server_sideにおける描画関数
    • renderToString
      • ほとんどはこっち
      • 第2引数のtarget DOMが不要で,戻り値としてHTML文字列を返す
      • sync_callで,非常に速く動作
      • data-reactid
        • browserでDOM_nodeを特定するために使う
      • data-react-checksum
        • server_side_renderingの場合にのみ追加される
        • server_sideで作成されたDOMが再利用できるかどうかを判断する
          • DOMの作成処理とそれをdocumentに挿入する処理を省略
          • → 特に複雑なサイトではページの初期表示までの応答時間が著しく改善
        • 作成するReact_componentの内容がserver_clientの間でまったく同じであることが特に重要
        • root要素のみ
    • renderToStaticMarkup
      • 独自のdata attributeなし
      • server_sideで描画したReact_componentをbrowserで再描画しない場合のみ
        • HTML mailの作成
        • 作成したHTMLを後でPDFに変換する
        • componentのテスト
  • server_sideにおけるcomponentのlifecycle
    • renderより後のlifecycle methodは呼び出されない
      • 特に,componentDidMount, componentはserver_sideでは呼び出されない
      • → event_listenerの定義において,componentの終了を通知するlifecycle methodは存在しない前提で設計する
      • → event_listenerやtimerは常にcomponentDidMountで登録して,componentWillUnMountで解除する
    • componentWillMountはserver_clientいずれでも呼び出される
  • client_server両方で使えるcomponentの設計
    • 同一のpropsとstateが与えられた場合,常に同じ内容を出力するようにcomponentを設計する
      • → テストしやすく,server_clientで同じoutputを保証できる
      • randomな値は外部からpropsとして受け取るようにする
    • applicationの初期値をどのようにしてclient側に渡すか
      • 最も簡単: JavaScriptのobjectとして初期値を渡す
  • async_data
    • まずdataを取得して,そのcallback_functionでcomponentを描画する
    • e.g.
      • async_dataを取得する処理をstatics methodとして定義する
        • props.initialStateとしてclientに渡す
        • lifecycle method経由でasync_dataの変更を監視し,変更があった場合statics methodを使ってdataを再取得
  • Isomorphic(同型の) routing
    • react-router
      • Isomorphic JavaScript(: client_server両方のcodeをJavaScriptで記述することでコードを共有すること)を可能にする
    • server_clientで同じAPIを提供するrouterを使ってroutingすること
    • 既存のrouterでserver_sideでReact_componentを描画する場合,そのrouterはDOMのAPIに依存していないことが重要
    • SEOの観点から重要なデータを取得するときは,routerのhandlerで非同期に取得して,top levelのcomponentから末端のcomponentへ順番に渡す必要がある
    • 重要でないdataは,componentのcomponentDidMount methodでAJAXでdataを取得すればよい
      • 常にclientでデータを取得
    • Reactと併用するrouterを選定するときは,routerのhandlerでasyncにデータを取得してrenderingできるか注意する
  • singleton_object
    • async_dataがsingleton_objectの状態に依存している場合,描画時にasync_dataが予期せぬ値になってしまう可能性がある
      • 描画のたびにsingleton_objectをresetではなく,applicationを隔離されたcontextで実行する
        • ContextifyのようなNodeのpackageなど
          • Web Workersによく似ている
          • 与えられたcodeをV8の異なるinstanceで実行する
          • performanceは犠牲になる
        • 実行contextをcomponent間で共有することは,非推奨
          • componentの移植性が低下するため
        • tradeoffがある
  • まとめ
    • server_side_renderingは,Web applicationのSEOとperformanceの観点から有効な手段になる
    • React_componentはserver_client両方でのrenderingが可能
    • application全体がserver_side動作するように設計されている必要がある

Ch13 React_family

  • Jest
    • test runner
    • Jasmineがベース
    • Nodeのrequire()関数を書き換えて,すべてのCommonJS style moduleをmockに置き換える
    • → すべてのcodeをテストできる
  • Immutable.js
    • React, Fluxと相性〇
    • applicationのperformanceとsimplicityが改善
    • 通常のJavaScript objectまたは配列を受け取り,独自のデータ構造に変換したものを返す
      • 戻すこともできる
    • object, arrayの比較が早くなる
      • ===を使える
  • Flux
    • design pattern
    • 厳密に単一のdataflowを規定
    • 何にも依存していないので,気に入った部分だけ取入れられる
  • まとめ
    • Jestにより,Unit test時に依存moduleをmockに置き換える方法
    • Immutable.jsを通常のデータ構造の代わりに使用する方法
    • FacebookのFlux patternの概要

Part 3 tool

Ch14 build, debug

  • Reactはcomponent単位の開発を容易にするため,いくつかの抽象的なlayerを設ける
    • debug, release作業は複雑になる
  • build_tool
    • Reactでのapplication developmentにおいて,最も繰り返し実行される処理はJSXのパース処理
      • そのほかに大部分を占める処理: 複数のmoduleをbrowserで実行するために単一もしくは少数のfileにまとめる(bundle)処理
    • Browserify
      • JavaScriptをpackagingするためのtool
      • Node.js styleのrequire()呼び出しをbrowserでも使えるようになる
      • requireされたすべてのmoduleを単一のJavaScript fileに連結(bundle)するのみ
        • 単一のfile → browserで簡単にloadできる
      • installと設定
      • React projectの作成
      • Watchify
        • 変更時に自動でbuild
      • buildの実行
    • Webpack
      • Browserifyと同じく,JavaScriptをpackaging + たくさんの機能
        • BrowserifyがGruntやGulpと併用して実現する機能を単体で実現できる
      • WebpackとReact
        • 自身が依存するassetを内包するcomponentを作成できる
        • assetがcomponentに紐づけられる → componentの移植性が高まる
        • あるcomponentが使われなくなったときにその依存assetも削除
          • どこからも参照されていないCSSや画像がなくなる
  • debug_tool
    • React Developer Tools
      • Chrome拡張機能
      • displayName
        • JSXがJavaScriptに変換されるときに,componentの定義に自動で追加される
        • そのほか多くの情報を見ることができる
      • JSBinとJSFiddle
        • online demo site
  • まとめ
    • React developmentにおいて,build, debug toolがいかに有用であるか

Ch15 test

  • TDDのworkflowでコードをmodule化し,変化に強くし,より安全にコードベースを変更できるようにする
  • はじめに
    • testにより,よりよいコードを書けるようになる
      • 単一責任の原則や,デメテルの法則にしたがうことになる
    • testの種類
      • unit_test
      • E2E_test
    • test_tool
      • unit_test(client_side): Jasmine, Karma
        • そのほか: Mocha, Chai, Sinon, Vows.js, QUnit
      • unit_test(server_side): Mocha, SuperTest
        • そのほか: client_sideと同じ( + jasmine-node)
      • E2E_test: CasperJS
        • そのほか: Nightwatch.js, Zombie.js, そのほかSelenium baseのもの(Capybara, Waitrなど)
  • 初めてのtest: render method
    • testでは,React.renderの代わりにReact.addons.TestUtils.renderIntoDocumentを使う
    • ReactにおけるHTMLの検査
      • Reactでは,componentのrender methodで指定したHTMLは,実際のDOMとは異なる
  • componentのmock
    • 対象のcomponentの機能だけをテストする
    • 前処理,後処理
      • beforeEach, afterEach
    • 要約
      • mock componentを定義する
      • componentのローカル変数の値を保存する
      • ローカル変数の値を書き換える
      • testを実行する
      • ローカル変数の値を元の値に戻す
    • Jasmineのhelper moduleでspec間の共通の処理を記述できる
      • (mockの内容はp.147の下段)
    • npmを使わないvanilla projectのcase
  • functionのstub化
    • stub化の目的
      • unit_testの対象範囲の限定
      • 関数内で使われているAPIやthird_partyのserviceなどの処理がテスト中に実行されるのを避ける
      • その関数が正しい呼び出し元から正しい引数で呼び出されていることをチェックしたい
    • jasmine-react-helpers
      • spyOnClass
    • stub化のmethod例
      • ランダム
      • serverからdataを取得
      • testで再現困難なstateを参照する
      • 副作用の範囲が大きい
      • 現在時刻やtimezoneを扱う
    • callback_functionのテスト
      • test→実装の流れ
  • event simulation
    • test→実装の流れ
  • testにおけるcomponentのselector API
    • TestUtilsのselector APIはDOM_nodeではなくReact_componentを返す
    • scry: skyのような発音.水晶占い
    • すべてのscryで始まる関数には,findで始まる対の関数がある
      • scryはcomponentの配列,findはひとつのcomponentを返す
    • componentの型で検索できるようにすることで,applicationを実装(CSS class, id)ではなくdomain(component)単位で検証できるため
  • Mixinのテスト
    • Mixinを直接テストする
      • Mixinの内部で呼ぶReactのmethodをすべてスタブ化必要
      • とても細かいテストになる
        • 機能が複雑な場合は利点もあるが,機能ではなく実装そのもののテストになってしまう状況になる
      • Object.createでテストごとにMixinを新たにcopyする方法
      • Reactの機能はスタブ化する
      • Reactのlifecycle methodの呼び出し順を忠実に再現が必要になる
    • dummy_component経由でMixinをテストする
      • 非常にsimpleなcomponentであり,テストの意図がより明確になる
      • 唯一の難点: Reactの制限によりrender methodを必ず実装する必要がある
      • componentが画面から削除されたときにclearIntervalが呼び出されることを保証したい
        • → componentWillUnMountを直接呼び出すのではなく,componentを画面から削除してReactに適切なcallbackを実行させることが重要
      • まずは直接の方式でテストを書いてみて,困難な場合はdummy_component経由に書き直すのが〇
    • 共有スペックを記述する
      • testの記述先がMixinのspec_fileではなくMixinを使用するcomponentのspec_fileになる
      • 複数のcomponentから使われるので,共通部分は共有スペックに記述する
      • Mixin内の呼び出しをテストするためであり,Mixinを使うcomponentからの呼び出しのテストではないので,idを分ける
      • ほかからの影響を受けやすく,より複雑になる
      • 適している場面
        • Mixinを使うときにcomponentが特別なmethodを実装する必要があるとき
          • componentがそれらのmethodを正しく実装しているか,共有スペックでテストできる
          • Mixinとcomponentの間のinterfaceをテストできる
        • Mixinの提供する機能がcomponent側で上書きされることで破壊される可能性がある場合,共有スペックによりそれを検出できる
  • \<body>に対する描画
    • renderIntoDocumentを使う意図: pageと切り離されたDOM_nodeに対して描画を行うため
      • 可能な限りこちらを使う
    • 実際にcomponentがpageに描画される必要があるときは,renderを使う
      • 親のDOM_nodeに対s手行った変更を注意深く元に戻す必要がある
      • jasmin-react-helpersを使うと,テスト終了時に自動でcomponentを削除してくれる
  • server_sideのテスト
    • Mochaを使う
      • Nodeのecosystem内でとても有名で,非同期処理をうまく扱える
    • spec_fileのtemplate
    • npm run test-server
    • doneでassertionの完了を知らせる必要
      • chain上で呼び出す
    • SuperTest
    • CheerioでHTMLとしてパースしてassertする
    • 404のテスト
  • browserを使ったテストの自動化
    • E2E_testについて
      • end_userの観点からapplicationの機能の正しさを検証するテスト
      • 基礎
        • browserを操作してWeb pageの内容が正しいか検査する
        • CasperJS
          • browserを簡単に操作するためのtool
          • 内部的にPhantomJSを使っている
        • PhantomJS
          • JavaScriptから操作可能なheadless browser
          • rendering engineとしてWebkitを使っている
        • headless browser
          • 画面に何も表示しない
          • terminalからcommand経由で操作できる
        • testで行うbrowser操作
          • linkのclick, formの記入, URLの入力, drag and dropなど,userが通常行うbrowser操作
        • Webkit
      • CasperJSでのテストがどのようなものか
        • end_userの視点でbrowserを操作 → Reactの文字は出てこない(Reactを使っているかどうか関知しない)
        • testが始まる前にnpm startでapplicationを起動する必要がある
        • リンクのクリック
        • thenのコールバック関数の中でテストを実行する
    • serverの起動
      • 自動的にserverを起動するためのscript
      • spec_fileのポート番号を変更する
  • まとめ
    • テストに関連するさまざまな概念について
      • 描画のテスト
      • 関数のスタブ
      • componentのmock
      • Mixinのテスト
      • componentの検索
      • server_sideでのテスト
      • E2E_test

Part 4 実践

Ch16 architecture pattern

  • Reactをほかのframeworkやarchitecture patternと併用してapplicationを構築する方法を見る
  • routing library
    • single_page_applicationにおいて,routerはURLをハンドラにマッピングするためのモジュール
    • Backbone.Router
      • Backbone: single_page_applicationを開発するためのlibrary
        • MVW(Model-View-Whatever)の形態
    • Aviator
      • router機能のみを持つstand alone library
      • 複数のtargetを指定できる
    • react-router
      • routerの定義自体がReact_componentで構成される
      • path属性に基づいてrouting, 該当するRouteのhandler属性に指定されたcomponentを描画
      • Link component
        • page navigationに使える
  • Om(ClojureScript)
    • 永続データ構造を提供
      • → Omはapplication全体を高速にrendering
      • snapshotを容易に取得
        • → undoのような機能を簡単に実装できる
  • Flux
    • Facebookにより考案されたarchitecture pattern
    • 単一方向のdataflowを強制
      • → Reactとともに使うことでapplicationの動作を推測しやすくなる
    • 大きな変更が不要.容易に導入
    • Store/Dispatcher/View(React_component_tree)で構成
      • Actionを4つ目のパーツとみなせる
        • Action: 補助的なmethodを提供しDispatcherのinterfaceとして機能する
    • 最上位のReact_componentはController-ViewとしてのRoleを担う
      • Storeとchild_componentとの仲介役として機能する
        • (iOSのViewControllerとは全く別物)
    • 各パーツは独立 → 関心の分離を強いられる → 個別テスト容易
    • dataflow
      • 情報が一方向に流れる
      • merit
        • applicationの動作が推測しやすい
        • application stateを1か所に集めて管理できるようになる
          • application stateはStoreに集約され,すべてのdataの取得/更新はStoreで管理
    • Fluxを構成するパーツ
      • Dispatcher
        • applicationの中心的なRole
        • すべてのデータがいったんDispatcherを通る
        • singleton_object
        • callback経由でStoreにイベントを通知
        • 複数のcallback_functionの依存関係の管理はDispatcherの責務
        • userやnetworkからの入力を登録しているすべてのStoreに通知し,各Storeがそれをチェックして自身に関係のあるinputのみを処理する
      • Action
        • user視点での入口
        • userがUIに対して行った操作はAction経由でDispatcherに届けられる
        • DSLとして機能する
          • 1段階高いレベルの言語へと翻訳され,Storeが意味を理解できるActionに変換される
        • userの操作はcomponent_treeをさかのぼってDispatcherに届けられる
          • その過程で,userの操作はapplication固有のActionに変換される
      • Store
        • applicationのデータのやりとりを一手に引き受け,developerはここにbusiness_logicを記述する
        • Dispatcherに登録したcallback_function経由でActionの通知を受け,自身の管理するデータに関係のあるActionの場合のみ応答する
        • dataが更新された場合,change eventを発行してReact_component_treeに更新を通知する
        • applicationのほかの部分からは厳密に分離
          • Storeはapplicationのすべてのデータを保存
          • applicationのほかの部分はデータの操作方法を知らない.Storeはapplicationで唯一データの変更が行われる場所になる
          • Storeはgetter methodのみサポートし,setter methodを持たない
            • dataの変更はすべてDispatcherからのcallback経由で行われる
      • Controller-View
        • Viewのtreeの最上位のcomponentがStoreとのやりとりを受け持つ
          • componentはController-Viewと呼ばれる
        • 規模が大きくなると複数のController-Viewとなることもある
    • 複数のStoreを管理する
      • 変更内容
        • DispatcherはActionをqueueに格納するように変更
        • DispatcherはActionの処理が完了するまで処理を停止できるように変更
        • Dispatcherにcallbackを登録する際に,どのActionに対して待ち受けるか指定できるようにする
      • Dispatcherの改善
        • Dispatcherの返すidに対してWaitFor
  • まとめ
    • Reactをほかのframework/architecture patternと併用してapplicationを構築する方法
      • MVC framework ~ Flux patternまで,Reactの高い順応性

Ch17 そのほかのusecase

  • React: interactiveなUIを構築するための非常に強力なrendering library
  • Web application以外の分野にも適用可能
    • Reactが提供するデータおよびuser inputを処理する方式や,再利用可能でテスト容易な小さいcomponentを複数組み合わせてapplicationを構築するやり方
  • desktop application
    • atom-chellやNW.jsなどによる
    • desktop上のinteractiveなapplicationを構築するためにReactを使える
  • game
    • gameは本質的にstate machineで,以下の基本的なRoleを持つ
      • 画面の更新
      • eventへの反応
    • Reactは以下の2点に対してのみ責任を果たす
      • DOMの更新
      • eventへの反応
    • Reactのvirtual_DOMの方式は,高性能のgame engineから着想を得たもの
    • 2048の例
      • immutable method
      • dataの共有
      • 不要な状態更新を避ける
      • 柔軟な構造 → undoを簡単に追加できる
      • ReactによりViewの動機を気にすることなくgame_logicとplayerとのやり取りに集中できる
  • HTML_mail
    • React.renderToStaticMarkupを使う
      • 与えられたcomponent_treeをHTML文字列に変換
      • 独自のデータ属性を出力しない ←→ renderToString
    • 実装例
      • CSSファイルの追加
    • 再利用・テスト可能なcomponentを組み合わせてinteractiveなUIを構築できるという利点をHTML_mailでも得られる
  • data_visualization
    • SVG tag
      • 実装例
        • feneratePathでSVGの描画コマンドを生成している
        • D3のようなlibraryを使うと格段に楽になる
  • まとめ
    • 以下を見た
      • Reactはbrowserで動作するWeb applicationだけでなく,desktop applicationやHTML_mailの作成にも使える
      • game developmentでReactを利用する方法
      • D3のようなlibraryと併用してdata_visualizationの用途で使用する方法

Appendix A 開発環境構築について

  • Reactは開発版と製品版がある
    • & アドオンありなし
  • Nodeの使用
    • Nodeのpackage management toolであるnpmを中心に,frontend developmentのための様々なtoolのecosystemが形成されているため
  • Nodeを使わない開発環境構築手順,react-tools
    • JSXTransformer/react-tools

Appendix B API reference

  • 3種類
    • top level API
    • component API
    • component仕様
  • 用語の整理
    • component仕様
      • React.createClass()に引数として渡すobject
      • render methodなどのlifecycle methodを定義する
    • component class
      • React.createClass()の戻り値として得られるobjectか,またはES6 class.
      • JSXにタグ名として直接記述するか,React.createElement()の引数として渡す
    • ReactElement
      • React.createElement()の戻り値として得られるobject
      • 内部的にはすべてのcomponent classはReactElementに変換される
      • React.render()の第一引数やrender methodの戻り値において使用される
    • component instance
      • ReactElementをもとにReactが生成するobject
      • component仕様で定義したmethod内で,this経由で参照できる
      • 外部からcomponent instanceにaccessするために,React.render()の戻り値もしくはref属性経由で参照を取得する
  • top level API
    • React
      • libraryとしてのentry point
    • React.createClass
    • React.createElement
    • React.createFactory
    • React.render
    • React.unmountComponentAtNode
    • React.renderToString
    • React.renderToStaticMarkup
    • React.isValidElement
    • React.findDOMNode
    • React.cloneElement
    • React.DOM
    • React.PropTypes
    • React.initializeTouchEvents
    • React.Children
    • React.Children.map
    • React.Children.forEach
    • React.Children.count
    • React.Children.only
  • component API
    • setState
    • replaceState
    • forceUpdate
    • getDOMNode
    • isMounted
    • setProps
    • replaceProps
  • component 仕様
    • object
      • propTypes
      • mixins
      • statics
      • displayName
    • lifecycle method
      • render
      • getInitialState
      • getDefaultProps
      • componentWillMount
      • componentDidMount
      • componentWillReceiveProps
      • shouldComponentUpdate
      • componentWillUpdate
      • componentDidUpdate
      • componentWillUnMount

『エッセンシャル スクラム: アジャイル開発に関わるすべての人のための完全攻略ガイド』学習メモ

まえがき

  • Essential Scrum
    • 基礎に,coreとなる価値,原則,practiceの小さなまとまりがある( → 集まってframeworkになる )
    • どのようなapproachを組み合わせるべきかわかるまでは,Scrum frameworkを忠実に守った方が良い

Ch01 Introduction

  • What's Scrum
    • Scrum: 革新的なProduct, Serviceを開発するためのapproach
    • Agile approach
      • product backlog
      • iteration
      • 機能横断型チーム
  • Scrumの起源
    • all-at-once product development(団結型product開発): scalable チーム based approach
      • Object Oriented developmentの概念・経験にもとづくprocess control
      • iterative and incremental development
      • softwareのprocessと生産性に関する研究
      • 複雑で適応力のあるsystem
    • Scrumの革新的な価値と原則は,softwareとは異なる種類のproduct開発や,さまざまな仕事のflowを生み出すためにも使える
  • Why Scrum
    • 事前の設計を創発的な設計とjust_in_timeで組み合わせられるapproach
    • より機能横断的
  • ゲノミカ社の顛末
  • Scrumは役に立つか
    • 頻繁なrelease
    • 組織的な機能不全や無駄を晒す
    • iterationのたびに動作・統合・テスト・business的に価値のあるfeatureのdeliveryに注力
    • Cynefin framework
      • 複雑な領域
        • 創発
        • 検査と適応
        • Scrum〇
        • 探索(調査)・理解(検査)・反応(適応)
      • 込み入った領域
        • 専門家が適切なpracticeを適用する領域
        • Scrumでも対応できるが,最善ではないかもしれない
        • 日々のsoftwareの保守作業など
        • Six Sigmaのような戦術的・定量的approachの多くは特にうまくいく
          • 単純な領域にも〇
      • 単純な領域
        • 正統的なbest practiceの領域.既知のsolution.
        • 適切に定義され,反復可能な手順が組み合わせられたprocessを用いたほうが,Scrumより上手くいく
      • chaosな領域
        • 状況と行動に対して誰かが責任を負う
        • Scrumは×
      • 無秩序
        • 状況を構成要素に分解して,それぞれをそのほかの4つの領域に当てはめる必要がある
      • 割り込み駆動の作業
        • Scrumは×
        • カンバンが〇
          • 推奨
            • 作業がsystemをどのように流れているか可視化
            • 各手順で仕掛け中の作業(WIP)を制限.こなせる以上の作業はしない.
            • system内の作業の流れを計測,最適化して,継続的に改善
          • softwareの保守とsupportに〇
          • systemごとにScrumとカンバンの使い分けもよい
  • まとめ
    • Scrumは複雑なproduct開発という営みの変化を受け入れられる
      • 組織のpotentialを妨げている機能不全や無駄を可視化

Part 1 Core Concept

Ch02 Scrum framework

  • Scrum frameworkの概要
  • practiceに焦点を合わせ,役割,activity,作成物について見る
  • 概要
    • Scrum: 作業をまとめあげ,管理するためのframework
      • value,principle,practiceに基づき,組織に合ったengineering practiceや,Scrumのpracticeを実践するための具体的なapproachの追加ができる
      • → originalのScrumができあがる
      • 建物の土台や壁のようなもの.備品や機能の付加だけが可能.
      • 人間中心主義
        • 正直,開放性,勇気,尊敬,集中,信頼,権限付与,協力といった価値に基づく
      • practice: role, activity, 作成物, それらに関連するruleで構成
  • Scrumの役割
    • 1つ以上のScrum_teamから構成
    • product_owner
      • productのleadershipの権限
      • どのfeatureや機能をどの順番で構築するか判断する責任
      • チームの目標に明確なvisionを持ち,関係者全員に伝える
      • 開発や保守を含めたsolution全体を成功させる責務
      • 最も価値の高い作業が行われるようにする義務
      • Scrum_masterや開発チームと協力.質問にすぐ答えられるようその場にいる必要.
    • Scrum_master
      • Scrumのvalue, principle, practiceを関係者全員が理解し,受け入れられるよう手助けする
      • as a coach, processについてleadershipを持ち,チームがoriginal Scrum approachを育てられるようにする
      • 組織変革のmanagementを支援
      • as a facilitator
      • impediment(ゴルフでのコース上の小石など)を取り除くときにleadershipを発揮
      • not a manager, but a leader
    • development_team
      • productをdesign, develop, testする責任
      • product_ownerが設定した目標を達成するための最善の方法を決定
      • 5人~9人
  • Scrumのactivityと作成物
    • flow
      • vision → groomingでfeatureに分解 → product backlog
      • sprint planningの結果: forecast/ commitment
      • sprint backlog
      • sprintの実施 with daily_Scrum
        • daily_Scrum: 作業の流れの管理のため,検査と同期を行う適応型planning activity
      • → product increment
      • sprint review: productをstakeholderとScrum_teamが検査
      • sprint_retrospective: processをScrum_teamが検査
    • product backlog
      • product_ownerが,stakeholderと協力して収集,定義し,正しい順序にする
        • 順序: value, cost, knowledge, riskから
      • grooming
      • prioritized/orderedはどちらでもよい
      • 各itemの大きさ・コストを認識
        • 相対基準
    • sprint
      • timeboxing
    • product planning
      • product_ownerと開発チームがsprint goalを合意
      • 持続可能なpace
      • sprint backlog: 第2のbacklog.product backlog itemごとに細かいtaskに分解したもの.
      • just_in_timeのplanning
      • 期間: 2週間~1か月.sprint planningは4時間~8時間
      • simple cycle: product backlog itemを1つ選び,itemをtaskに分解し,選んだitemがsprintに収まるかjudge
        • taskは1時間単位で見積もる
    • sprintの実施
      • 完成: 高品質な機能を達成するのに必要な作業をすべて終えたという強い自信があること
      • チーム memberがtask levelの作業を定義.自己組織化して実施.
    • daily_Scrum
      • sprint期間中の毎日・同じ時間に,15分以内のtimeboxで実施
      • a.c.a. daily standup
      • 検査と適応のactivity
      • Scrum_masterがfacilitatorとして,各memberがほかのmemberに3つの質問
        • 前回のdaily_Scrumのあと,自分が何をしたか
        • 次回のdaily_Scrumまでの間,どんな作業をするか
        • 進捗を妨げる障壁・impedimentは何か
      • → 全員が今の状況の全体像を理解
      • sprintで作業をすばやく柔軟に実施するうえで欠かせない
      • sprint backlog itemの状況を開発チーム member間で共有するためのもの
      • 同期および検査と適応の毎日のplanning activity
    • 完成
      • sprint の成果: 出荷判断可能なproduct increment
      • 完成の定義: 品質・出荷判断可能であることへの,自信の度合い
      • 出荷判断可能: sprintで構築したものに対する自信の度合い
        • 終わらせるべき重要な作業で,完了していないものがないということ
    • sprint review
      • 構築中のproductの検査と適応
      • 参加者同士が会話
      • 開発activity全体へのreview
      • 今起きていることを可視化,次の開発をガイド,ビジネス上最も適切なsolutionが確実に作り出されるようにするための機会を得る
      • チーム内外で情報が双方向に流れるようになる
    • sprint_retrospective
      • processの検査と適応
        • Scrumと関連する技術的なpracticeについて議論
        • 継続的なprocess改善
          • 現実的な数のprocess改善actionを特定し,実施をcommit
            • 次のsprintで取り組む
  • まとめ
    • Scrum frameworkの役割,activity,作成物のすべてに焦点を当てて,Scrumのcoreとなるpracticeを見た

Ch03 Agile principle

  • Agile principleをtraditional 計画駆動のproduct developmentのprincipleと比較
    • Scrumとの違いの理解の下準備
  • 概要
    • a.c.a. 順次的なprocess
    • 計画駆動の開発
      • 基礎となる信念が,product開発に伴うUncertaintyと見合わない
  • 変動性とUncertainty
    • 役立つ変動性を受け入れよ
      • product developmentは製造業とは全く異なる
        • 製造業: 要件を固定し,よく理解された工程に従うことで,(定義された振れ幅の中で)常に同じ完成品を作り出す
        • product development: ほかにないproductをただひとつだけ作り出す
          • 1つだけのproduct: 料理のrecipeに似ている
    • iterativeでincrementalなdevelopmentを採用せよ
      • iterative: 計画された手戻り戦略
        • 構築しているものを改善するために,いくつもの道を辿る
          • 優れたsolutionに辿り着く
        • 最大の欠点: Uncertaintyがあるため,どれだけの改善があるか事前に判断・計画することが難しい
      • incremental: 全部作る前に少し作ってみる
        • productを小さい部品に分割し,その一部を構築して,実際の環境でどのように動くか学習し,その学習に基づいて適応し,続きを構築する
        • developmentを調整し,やってきたことを変更するうえでの重要な情報を獲得する
        • 最大の欠点: 部品ごとに構築すると,全体像を失ってしまうriskがある
      • 併用することで,個別に使う場合の欠点を埋められる
      • Scrumではsprintと呼ばれるtimeboxingされたiterationで適応を繰り返すことで,iterative and incrementalという考え方を実現する
        • Water Scrumは×
        • featureに対して作業をし,統合・テストを経ることで,全体的な視点でproductを見られる
        • sprintの結果についてfeedbackを受け取ることで,適応ができるようになる
          • iterative developmentと継続的な改善に対するcommitmentの一部として,将来のsprintでやり直しを計画できる
          • → どの程度の改善が必要か事前に正確に知ることができないという課題を克服
        • 適切で経済的にも意味のある回数のiterationを行いつつ,productをincremental development
    • 検査,適応,透明性(経験的なprocess control)を通じて変動性を活用せよ
      • 計画駆動とScrumの違い
        • processが定義される度合い
        • 成果のばらつき
        • 使われるfeedbackのtiming, 量
      • Scrumの核心が,検査,適応,透明性
        • 構築するものだけでなく,構築する方法も検査と適応を行う
          • このために透明性が必要
            • 透明性: productを作り出すための重要な情報はすべて,productの構築にかかわる人が入手できること
            • communicationの基礎: 透明性により,観察・理解が可能になる
            • → 信頼関係
    • あらゆる形のUncertaintyを同時に削減せよ
      • 目的(what)のUncertainty: 最終的なproductのfeatureを取り巻くUncertainty
      • 手段(how)のUncertainty: product developmentに用いられるprocessやtechnologyを取り巻くUncertainty
      • 顧客(who)のUncertainty
      • iterative and incremental developmentにより容易に同時の削減ができる
        • 検査と適応,透明性を定常的に行うことで実現
        • 未知の未知を学習できる
  • 予見と適応
    • 予見への願望と適応の必要性との間のバランスをとる
    • 選択肢を広げておく
      • 最終責任時点(LRM)
        • 拙速な判断は×
        • 判断しないcostが判断するcostを上回るときに決定する
        • 判断に関する理解が深まれば,判断のcostが下がっていく
    • 事前に正しく行うことは不可能だと認める
      • 重要な知識がない状態では,精度の低い要件を大量に作ってしまう
        • 目的のUncertaintyが見えなくなる
        • 無駄になる
      • Scrumでは,ある程度は事前に要件を集め,計画を立てるが,必要な分だけ
        • 詳細は,構築中のproductの学習に合わせて埋めていく
    • 適応型で探索型のapproachを好む
      • 適応: 何らかのactivityで知識を得ること
        • prototypeの構築,概念実証(POC),勉強,実験
        • 調査によって情報を買う
        • tool, technologyが,調査のcostを大きく下げる
    • 経済的に妥当なやり方で変化を受け入れる
      • 予見のし過ぎは逆効果
        • 自己成就的な予言pattern
      • Scrumでは変更cost曲線をできるだけ平たんにする
        • processにおける作業の量と流れを管理し,時間の影響を変更costに与えないようにする
          • 多くの作業の成果物(詳細な要件,設計,testcaseなど)をjust_in_timeで作り出す
    • 予見的な事前の作業と適応型のjust_in_timeの作業とのbalanceを取る
      • 経済的に妥当なやり方で,素早いfeedbackに基づく適応の量を最大化し,事前の予見を最小化する
        • かつ,complianceや法規制,企業の目的から外れない
      • 革新的なproductを素早く開発するためには,適応すべきことに対して,chaosにならない程度の予見が必要
        • chaos → 作業が非効率
  • 検証による学び
    • 想定を確認したり反証したりする知識を得たとき
    • 重要な想定をまず検証する
      • 想定: 推測や信念.検証による学びがまだのもの
        • 開発に重大なrisk
        • Scrumでは最小化かつ残る期間を短くする
          • iterative and incremental developmentをlow cost researchと組み合わせる
    • 複数の学習loopを並行して活用
      • Scrumにおける継続的な学習
        • feedback loop
        • 予め定義された複数の学習loop
          • daily_Scrum, sprint review
            • pair programming(秒単位のfeedback), test driven development(分単位のfeedback)
    • 素早いfeedbackのためのworkflowをまとめる
      • Scrumでは作業の直後にfeedback
        • 経済的恩恵が大きい
        • 学習loopをすばやく閉じる
        • riskを小さくできる
  • 仕掛け中の作業(WIP)
    • 作業は経済的に妥当なサイズにまとめよ
      • 計画駆動: all-before-any型approach
        • batch サイズ: 100%
        • 規模の経済をproduct developmentに当てはめたもの
      • Scrum: batch サイズを小さくする
        • 規模の経済の当てはめは重大な経済的損失を呼ぶ
        • 恩恵
          • cycle time削減
          • flowの変動性の低減
          • feedbackの推進
          • riskの低減
          • overheadの低減
          • 士気と危機意識の向上
          • cost, scheduleの肥大の抑止
        • 1個流しにこだわることはない
          • 作業の流れ,全体の経済性も重要
    • 在庫を認識し,適切な流れで管理
      • 在庫: WIP
      • 大量の在庫があるときの変更は,重大な無駄につながる
        • → just_in_timeで在庫管理を健全に行う
      • 要件が多すぎると,要件の変更時に在庫の無駄が生じる
      • 要件が十分にないと,作業をすばやく流せない
      • → ちょうどよい在庫と多すぎる在庫との間で適切なbalanceを見出すことが目的となる
      • 在庫は要件だけではない.ほかのものも管理要
    • 作業者の手待ちではなく,作業の手待ちに注目
      • 作業の手待ち: 実施したいのに何らかの原因でできない作業
      • 作業者の手待ち: capacityに余裕があり,もっと作業ができる人
      • 走者ではなくバトンを見よ
      • queue理論のgraph
        • 作業の手待ち(遅延した作業)は,いったん高稼働率になると,指数関数的に積みあがる
      • → 作業の流れの中でbottleneckを見つけ削減する,という経済的に意味のあるactivityに注力する
    • delay_costに考慮
      • delay_cost: 作業の遅延やmilestoneの達成の遅延に関連した,経済的cost
        • どの種類の無駄が経済的に損失を与えるか算出できる
  • 進捗
    • 自分たちがdeliveryし,検証したものによって測る
    • realtimeの情報に適応してreplan
      • plan: 物事がどう進むか事前に予見しただけのもの
      • 経済的に重要な情報の流れに適応
        • 開発期間中に継続的に行う
    • 動作する資産を検証することで進捗を測る
      • 動作する資産を検証 → 重要な想定の検証 → 次のstepへのfeedback
      • 顧客にとって価値のある作業をどれだけ終わらせたかがimportant
    • valueを主眼に置いたdeliveryに集中
      • 中間成果物は顧客が認識できる価値をもたらさない.目的のための手段に過ぎない.
      • それ自体が重要なfeedbackを生み出したり,重要な知識を得るために役立つことに意味がある
  • 作業効率
    • 素早く進む,しかし,あわてない
      • 機敏 & 状況に適応 & speed
      • 機敏 & 持続可能なpace & 品質
    • 品質を作りこむ
      • 機能横断型のScrum_teamに責任
      • 継続的に作りこんで,sprintごとに確認
      • valueのincrement: 強い自信をもって完成され,productに組み込んだり出荷しようと思えばできるようになっている
    • 必要最低限の儀式
      • 不要な形式主義の儀式 ←→ Scrumは価値中心的
        • processのためのprocess
      • documentを書くcase
        • productの一部
        • 重要な議論や意思決定,合意を記録して,何があったのか将来分かるようにするという目的
        • 新しいmemberが追い付くうえで役に立つ,価値の高い方法
        • 規約上の要件
  • まとめ
    • 核心的なAgile principle
      • Scrumの方法を導く基本的な信念
      • 計画駆動との違い

Ch04 sprint

  • sprint: 1週間~最大1か月までのcycleの繰り返し
  • timeboxing
    • 短く固定された期間に,一度設定した目標をなるべく変えず,チームで合意した完成の定義を達成した出荷判断可能なproduct incrementを生み出す
  • 概要
    • sprint: Scrum frameworkの枠組み
      • goal, memberは変えない
      • 特性は,あらゆるチームのあらゆるsprintに当てはまる(一部例外がある)
  • timeboxing
    • 時間管理のtechnique.
    • 仕事の能率を高め,scope managementを支援
    • sprint goalに向けて選択した作業を完了するために,持続可能なpaceで働く
    • merit
      • WIPの上限設定
      • 優先順位づけを強制
        • 重要な少量の仕事が優先される
        • 集中力を研ぎ澄ます??
      • 進捗状況の可視化
        • sprintの最終日という締め切りまでに重要な作業が完了し,検証されているかどうかという観点で進捗を可視化できる
      • 不必要な完璧主義を避ける
        • 期限がある
      • 締めくくりの促進
        • 切迫感
      • 予測可能性を改善
        • 予測の範囲がはっきりする
  • 短期間
    • 計画の立てやすさ
    • すばやいfeedback
    • 投資収益率の改善
    • 損失の限定化
      • 失敗しても,短い期間を失うだけで済む
    • 熱狂を取り戻す
      • 待ち時間が少なくなる
      • 目に見える進捗,終わりがある
    • 頻繁なcheckpoint
      • 動作するfeatureを実際に見て,誰もが意思決定できる
  • immutable sprint term
    • 例外
      • feedback speed up
      • 休暇,会計年度末
      • release span
    • 一定のrhythmのmerit
      • 予測可能,計画が立てやすい
      • 安定した健康的な鼓動
        • 高速で柔軟なbusiness valueのflowを実現するため
      • zoneに入りやすくなる,roleを果たせるようになる,波に乗りやすくなる
      • 平凡だが必要不可欠なactivityが習慣化される
      • 短いrhythmで,仕事への集中力を一定に保てる
      • 調整のためのoverheadが大きく減少
    • 簡潔なplanning
      • velocityへの信頼度up
        • sprint単位で平準化
      • releaseまでのsprintの回数がわかる
  • immutable goal
    • sprint goal: sprintを要約したもの.取り組むbusiness上の目的とvalue
      • 明確で1つの事柄に焦点を当てる
      • 複数のgoalとなることもある
      • development_teamが洗練・合意し,sprintで完成できるproduct backlog itemを特定する
        • sprint goalをさらに精緻化
    • 相互commitment
      • チーム
        • sprintの最終日までにsprint goalを達成することをcommit
      • product_owner
        • sprint期間中はsprint goalを変えないことをcommit
      • sprint importanceを表現
        • business needsを変化に適応させることと,チームが短期間でvalueを生み出す能力を集中的に効果的に発揮させることのbalanceをとる
        • sprint goal → チームは明確に定義されたvalueに集中
    • 変更と明確化
      • 変更は×,明確化は〇
    • 変更の影響
      • あらゆる点でloss大きい
    • 実利的であるべし
      • 経営状況や障害など実利的に問題があれば,ruleより実利を優先する
      • 変更の必要性を,経済的な観点でproduct_ownerがチームと議論できれば,やる気と信頼は高まる
    • sprintの中止
      • 経済的な事情
      • 奥の手
  • 完成の定義
    • 出荷判断可能な
      • ≠ 出荷しなければならない
      • sprintで構築したものが完成しているという自信
        • 出荷するために必要な仕事(重要度の高いテストや統合など)が確実に完了している
    • 概念的には仕事のcheck listのようなもの
      • 変動要因
        • 成果物の性質
        • 成果物に使われている技術要素
        • 成果物を構築した組織
        • 現在の可能性に影響しうるimpediment
    • sprint期間より長くなりうるテスト
      • 自動化に取り組む
    • 完成の定義は時間とともに改善
    • 完成の定義と受入条件
      • 受入条件: product_ownerが規定した満足条件
        • 受け入れテストで確認
      • product backlog itemは,個別の受入条件とsprint levelの完成の定義の両方を達成して,完成したとみなされる
    • 完成と完全に完成
  • まとめ
    • Scrum frameworkにおけるsprintの果たす重要な役割
      • sprint: ほかのactivityや作成物を配置するEssential Scrumの枠組み
        • 短い,timeboxing,期間は固定
        • sprint goalで定義
          • 経済的な妥当な理由以外は変更不可
        • 出荷判断可能なproduct incrementを生み出す
          • 全員で合意した完成の定義を満たす

Ch05 要件とuser_story

  • 要件の扱いが伝統的なprojectとどう違うか
  • user_story: business valueを表現する共通形式
  • 概要
    • Scrumでは,要件の詳細はprojectを通じて継続的に対話しながら調整
    • 要件はjust_in_time.チームが開発を始める必要なときに,必要な分だけ
      • business goalを達成するために操作できる重要な自由変数
    • Product Backlog Item(product_backlog_item): 要件の置き場所.それぞれが何らかのbusiness valueを表す
      • 会話の中で,より詳細なproduct_backlog_itemに分解し,最終的にsprintに入る大きさまで小さく・詳細化される
        • 設計・構築・テストができる
      • Product Backlogはproduct_backlog_itemの集合のsnapshot
      • product_backlog_itemの標準形式はない
        • user_storyやusecaseなど
  • 対話する
    • 要件: 構築しようとしているproductに欠かせない事柄についての共通理解を促進するcommunication手段
    • 音声によるcommunicationは,帯域が広く,feedbackもすばやく,安くて簡単に共通理解が得られる
    • 双方向communicationが問題解決のためのideaの発見を促す
    • Product Backlogは生きているdocument
  • 改良し続ける
    • 段階的洗練戦略
  • what's user_story
    • 様々な種類のproduct_backlog_item(特にfeature)に期待されるbusiness valueを表現する便利な形式
      • business側と技術側ともに理解しやすくなっている
      • 単純な構造,会話のために優れたplaceholder
      • 段階的改良もしやすい
    • Agile development principleとneedsを効率的に結びつける軽量approach
    • 要件の詳細化として,重要・役立つ情報の記録のために使う
    • Card
      • userの分類(役割),目的,求める理由(利益)を具体的に書く
      • 要件の意図や本質を捉えた数行の文章にする
        • 関係者をより詳細な議論に導く
    • 対話(Conversation)
      • Conversationは,要件の詳細を適切な時期に具体化・共有するためのstart point
        • user_storyはConversationのための約束事
      • user_storyが,書くことに向けていた注意を対話に向ける
      • 豊かな情報のやり取りと協調をもたらす
        • 正確な要件を誰にも理解できる表現にする
      • 文書と相互補完的
    • 確認(Confirmation)
      • 満足条件,受入条件
        • 期待される振る舞いを示す
      • 受入テスト
      • 具体例を精緻化し,user_storyを作成・改善するprocessを駆動できる.user_storyに自動化された受入テストも用意できる
  • 詳細化のlevel
    • user_story: Scrum のvalueを生み出すflowに顧客やuserのvalueを持ち込むのに最適
      • 大きさの問題
      • → 複数の抽象化level
        • epic: 数か月の期間,複数回のrelease
          • 期待されていることの概要,概要levelの全体像をもたらす
        • feature: 数週間の期間,1 sprintには入らない
      • epic, featureなどuser_storyの最小限の形式をstoryと呼ぶ
      • 関係するuser_storyをまとめたもの: theme
      • task: user_storyより具体的.構築するものについてのhow(not what)を決める
  • うまく書けたuser_storyとINVEST
    • INVEST: user_storyが書き手の意図に合うかどうかを評価するために有用なprinciple
    • Independent
      • 依存性を最小化
    • Negotiable
      • user_storyは内容と理由を書く
        • 規制や制約がなければ,方法がNegotiableとなるようにする → Innovation
    • Valuable
      • 顧客と利用者双方にとって → product_ownerから見てすべてのstoryはValuableが要
      • technical storyはProduct Backlogに入れない.business storyの関連タスクとする
    • Estimatable
      • storyの規模,労力,costが目安
    • Small
      • 近いうちに取り掛かりたいstoryは小さくする必要がある
        • sprintで扱うため
    • Testable
      • 確認 → 5.4
      • 必須ではないし不可能なこともある
  • 非機能要件
    • system levelの制約
    • できる限り多く完成の定義に含める
      • → すばやいfeedback
  • 学習のためのstory
    • prototype, POC, 実験, 学習, spike
    • 探索的activity
    • cost, valueの算出・比較
    • fail first戦略もある
  • storyの収集
    • userは作家というより批評家
    • userにチーム memberとして関与してもらう
    • user_story記述workshop
      • 目的: business valueについて協調的にbrain storming,想定するproduct/serviceのためのuser_storyの類型を作る
      • 初回はuser role analysis
        • personaというprototype的人物描写も作成する
      • 進め方は上手くいくやり方でいい
    • story mapping
      • user中心指向の観点からuser_storyを作成
      • 抽象的なuser actionを,詳細taskによって組み立てられるworkflowに分解する
        • epic/theme/sprint可能なstory
      • userにとってのvalueから優先順位づけ
      • storyの分解とuset中心設計の考え方の結びつけ
        • user目線での行為の流れを示す
        • 顧客の価値という大きな観点からの,個々のstoryの関連性が分かる
      • workflow: contextとなり,関係するstoryに注目できる
      • user_story記述workshopに,優先順位を補完する
  • まとめ
    • Scrumでの要件の扱いを見た

Ch06 product_backlog

  • 概要
    • product_backlog: productに求められる機能を,優先順位をつけてリスト化したもの
      • 何を作るか,どの順番で作るかについての認識が一か所にまとまり,共有できる
      • Scrum frameworkの肝
  • product_backlog_item
    • だいたいはfeatureや機能項目を表し,userや顧客の目に見える価値をもたらす
    • user_story形式で書かれることが多いが,書式は不定
  • good product_backlogの特徴
    • Detailed appropriately(適切な詳細度)
      • 取り掛かる時期に合った詳細度.近いほど細かい.
      • 適切なtiming
    • Emergent(創発的)
      • 時間とともに姿を変える
      • 対応可能になっている
    • Estimated
      • story_point, 理想日を使う
      • 近いものは小さめで正確な見積もり
      • 遠いものは見積もりはしなかったり,Tシャツのサイズ程度の見積もりになることもある
    • Prioritized
      • 遠いものは細かい優先順位不要.全体のlevelでの優先順位程度でいい
  • grooming
    • DEEPなproduct_backlogのために,product_backlogの中身を整理
    • product_backlog_itemの作成と改良(詳細の追加)/product_backlog_itemの見積もり/product_backlog_itemの優先順位づけ の総称
    • product_ownerが主導する全員での共同作業
      • 開発チームは,各sprintの作業時間の最大1割程度までgrooming用に時間を確保
    • timing
      • 最初はrelease planningのときに,stakeholderとともに
      • 週に1度かsprintに1度程度で,development_teamとともにgrooming workshop
        • daily_Scrumのあとにincremental groomingを行うこともある
          • 全員でやる必要はない
      • sprint reviewの際にも行う
      • きちんとprocessに組み込みさえすれば,timingは重要ではない
    • business valueを柔軟かつ高速にdelivery
  • 準備完了の定義
    • grooming: Backlogの最初のitemを準備完了にする
    • 作業のchecklist
      • product_backlog_itemについて必要なことのリスト
    • 厳しく設定すると,sprint goalの達成可能性が大きく上がる
  • flow management
    • product_backlog: 不確実性がある状態でも高速かつ柔軟にvalueを提供する流れを実現できる
      • 重要な情報は絶え間なく少しずつやってくる
      • → 作業を整理して管理し,頻繁にやってくる情報をすばやく効率的に処理しながら対応する必要
    • release flow management
      • release planningに備えたgrooming
      • 必須/できれば含める/含めない の3 エリアに分ける
    • sprint flow management
      • groomingにより,feature群をsprintに流し込める
        • product_backlogの先頭のitemは,明確に定義されていてテスト可能な状態
      • product_backlogを要件のpipelineと考えてgroomingが〇
        • pipelineからsprintに流し込まれた要件を,設計・開発・テスト
        • product_backlogを上がっていく間にgroomingで要件が見直されていき,準備完了な状態になる
          • development_teamが理解できるほど詳細で,1回のsprintで完了できる規模になる
        • 必要十分なだけのproduct_backlog_itemを在庫として抱え,一定のflowを作ることがimportant
          • sprint 2回から3回分程度のstoryを準備完了状態で抱えておくとうまくいく
  • どんなproduct_backlogをいくつ用意するか
    • 基本原則: Productごとにproduct_backlogを1つ用意
      • 注意が必要なcaseある
    • Productとはなにか
      • さまざまな捉え方
      • goal: component_teamの数をできるだけ減らす
      • → packagedで,デリバリー可能であり,利用者に価値をもたらすものに合わせて,product_backlogを並べる
    • 大規模product -階層化backlog
      • できるだけ1つのproduct_backlogがよいが,現実的に不可能なこともある
      • → 階層化backlog
      • feature area単位のBacklog Itemは.対応するproduct_backlogのitemよりも,サイズが小さい
      • release train → Ch12
        • portfolio_backlog, program backlog, チーム backlogの3 level
    • 複数のチーム -単一のproduct_backlog
      • Productごとに1つのBacklog → Productにかかわるすべてのチームがproduct_backlogを共有するため
        • Product全体で見たときの経済的最適化可能
      • 各チームがproduct_backlogのどのItemに対応できるのか知っておく必要
        • → 共有Backlogに対するチームごとのviewを用意する
      • チームの交換可能性に価値がある
    • 単一のチーム -複数のProduct
      • チームは複数のProjectの担当は極力避ける
      • 少なくとも,同時に複数のProductにかかわらないようにする
      • どうしても同時に複数のProductの作業をするときは,各product_backlog_itemを1つのproduct_backlogにまとめる
  • まとめ
    • product_backlogが果たす,不確実性のもとで高速かつ柔軟に価値を提供する流れを実現するための役割

Ch07 見積もりとVelocity

  • 概要
    • まず作ろうとしているもののサイズを見積もる
    • さらに,その作業におけるVelocityを計測
      • 各sprintで完成したItemの見積もりサイズを合計することで出せる
    • → 期間・costを導ける
  • いつ何を見積もるのか
    • Portfolio Backlogの見積もり
      • 作成するすべてのProductの優先順位づけ
      • ざっくりとした相対的な見積もり(Tシャツのサイズていど)
    • Product Backlogの見積もり
      • product_backlogのgroomingの一環として行うactivity
      • 見積もりmeeting @初回のrelease planning
        • 以降も新たなproduct_backlog_itemの見積もりが必要なら見積もりmeetingを招集する
      • 成熟したScrum_teamならすべてのproduct_backlog_itemを同程度のサイズにまとめられる
      • 見積もる理由
        • すべてのproduct_backlog_itemが同時に同じサイズにはならない
        • チーム memberがすべてのproduct_backlog_itemのサイズを同程度にまとめられるようになるには,それなりに時間がかかる
        • 同じサイズにすることが目的となってしまい,不自然なところでstoryを分割せざるをえなくなることを避ける
        • 最重要なこととして,見積もりの最大の目的は,対話の過程でいろいろな気づきが得られる
          • 健全な議論を促す
    • taskの見積もり
      • commitmentが達成可能だと確信するため
      • 大きさは理想時間単位で判断(a.c.a. 工数)
  • product_backlog_itemの見積もりの考え方
    • チームで見積もる
      • development_teamが,全員で見積もる
      • 全員の意見をまとめて,それぞれのproduct_backlog_itemのサイズを判断できるようにする
    • 見積もりはcommitmentではない
      • 数字を操作しないでよいようにする
    • 正確性か精度か
      • 無駄は×
      • やり過ぎると逆効果
    • 相対サイズの見積もり
  • product_backlog_itemの見積もりの単位
    • story_point
      • product_backlog_itemの大きさを計測する指標
      • storyの複雑さ,物理的サイズなどを組み合わせて,相対サイズを測る単一の指標としたもの
      • development_teamの視点からの,storyの完成に要する作業を表す
    • 理想日
      • 誤解を招くriskあり
        • あと(理想日)日で終わるというわけではない
      • 作業日数(人日)で表す
  • planning poker
    • memberの同意ベースで見積もりを行うtechnique
    • 見積もりの尺度
      • フィボナッチ数列や2の累乗などで,同程度のサイズのproduct_backlog_itemをひとまとめにして同じ数字をassign
    • 進め方
    • merit
      • チーム memberをまとめて,正確な見積もりとなる
      • 議論によりproduct_backlog_itemの理解が深まる/共有できる
  • Velocity
    • 各sprintで完成した仕事量
    • 計測対象: 生産量(サイズ), not 成果(value)
    • 利用目的
      • Scrumでのplanning
      • チームの現状を診断
  • Velocityの幅の算出
    • 幅を持たせる → 不確定要素があることが伝わる
    • min/max sprint数が分かる
    • 最大値と最小値の平均や,90%信頼区間など単純計算で求める
  • Velocityの予想
    • sprint planning
      • commitしたproduct_backlog_itemのサイズを合計してチームの予想Velocityとする
      • 2回のsprintで見積もりを行うなどで,幅を求める
  • Velocityへの影響
    • 向上のための手段や悪影響のある手段など
  • Velocityの誤用
    • performanceの指標としては使えない
      • 数字の操作(pointのインフレなど)や手抜きが起こる
    • 見積もりの正確さの検証,チーム内での改善がどの程度進んでいるのかの判断にのみ使う
  • まとめ
    • サイズの見積もり,Velocityの算出,期間の求め方
    • 各levelでの見積もり
    • story_point/理想日
    • planning poker
    • Velocityの使い方

Ch08 技術的負債

  • 概要
    • 負債の返済のために十分に注意が必要
    • systemの設計や実装は,業務ドメインに関する知識をよく反映できるように発展させていく必要
    • 無責任や不注意といった原因で発生する,ナイーブな技術的負債
    • 不可避な技術的負債
    • 戦略的な技術的負債
  • 技術的負債の行く末
    • 予測不可能な臨界
    • deliveryに要する時間の長期化
    • 不具合の多発
    • development/support costの増加
    • productの退化
    • 予測可能性の減少
    • 伸び悩み
    • 募る不満
    • 顧客満足度の減少
  • 技術的負債を生む要因
    • 納期を守るためのpressure
      • Velocityの偽装
    • testを減らせばVelocityが向上するという神話
      • TDDのような優れた手法を使うのが〇
    • 負債が生む新たな負債
  • 技術的負債の管理
    • どんなproductも技術的負債からは逃れられない
    • 技術者の言い分とbusiness関係者の言い分のbalanceを取る
      • product_ownerが存在する理由の1つ
  • 技術的負債の発生の管理
    • 優れた技術的practiceの活用
      • ナイーブな技術的負債を増やさない
      • simple design, TDD, CI, 自動テスト, refactoringなど
      • refactoringによる負債の支払い
    • 厳しい完成の定義の使用
      • checklistの技術的な網羅性を高める
    • 技術的負債の経済的意味についての適切な認識
      • 技術的負債の多方面への影響
        • 真のcostより低く見積もってしまいやすい
  • 技術的負債の可視化
    • 技術的負債という例えの最大のmerit: development_teamと経営者の会話での共通認識の獲得
    • business levelでの技術的負債の可視化
      • 組織のBalanceSheetに短期・長期の技術的負債の行を追加
      • Velocityの変化の追跡
        • 金銭的costを明確にできる
    • 技術者levelでの技術的負債の可視化
      • 既存の障害管理systemに記録
      • product_backlog_itemを作成
        • 返済のcostが高い場合
      • 技術的負債だけを扱うBacklogを作成
        • 技術的負債の現状を把握
        • どの時期に負債を返済するか積極的に決められる
      • 同じ場所で作業なら,掲示板を壁に掲げるのもよい
  • 技術的負債の返済
    • category
      • 偶発的な技術的負債
      • 既知の技術的負債
      • 返済対象の技術的負債
    • flow
      • 既知の技術的負債を返済すべきか判断
      • 作業中のコードに偶発的な技術的負債を見つければ,きれいにする
        • 多すぎるときもできるだけは対応する
        • 返済できない分は既知の技術的負債としてまとめる
      • sprintごとに既知の技術的負債のいくつかを返済対象の技術的負債とみなす.
        • とくに利率の高いものを選ぶ
    • すべての技術的負債を返済すべきというわけではない
      • 寿命が近づいているproduct
      • 使い捨てのprototype
      • 短期間しか使わないproduct
    • boy scout ruleに従う(負債を見つけたらその場で返済)
      • 「来た時より美しく」
      • 偶発的な技術的負債の返済用の時間を予めある程度見込んでおく
        • 5%~33%
    • 技術的負債の返済はincremental
      • 一括払いは×
      • 返済のためだけのsprintが必要となってしまうような状況にしない
      • 既知の技術的負債をピックアップして返済対象の技術的負債とみなし,次のsprintで返済
    • 金利の高い技術的負債から返済
      • 多くのコードが依存していて頻繁に変更が加わるモジュールなどでの負債
    • 技術的負債を返済しながら顧客に価値をもたらす作業も行う
      • できるだけ,返済のためだけのsprintは作らない
      • 負債の返済だけを扱うproduct_backlog_itemは置かない
      • merit
        • 負債の削減の作業を顧客に価値を届ける作業とうまく組み合わせて進めれられ,product_ownerが適切に設定した優先順位に合わせられる
        • development_team_member全員が,技術的負債の削減に関する責務を共有.ほかの人が後で対応してくれるものではないとはっきりできる.
        • 技術的負債の予防や対策の力を養える.
        • 金利の高い分野を見つけやすくなる. ← 対応中のコードは何かしらの重要性がある(からこそ対応している)ため.
        • 対応不要な分野の技術的負債の返済に,時間を無駄遣いせずに済む.
      • 既知の技術的負債の返済をproduct_backlog_itemと関連付けて進めるのは,simpleに組み合わせられて〇
  • まとめ
    • 技術的負債の概念
    • 3つの分類
    • 管理
    • activity
      • 発生の管理
      • 可視化
      • 返済

Part 2 Role

Ch09 product_owner

  • 概要
    • product_owner: productの統括を認められた中心的な存在.Scrum_teamを構成する3つのRoleのうちの1つ.
    • 2方向を見る → business analyst & tester
      • 組織内のstakeholder, client, userが持つneedsや優先順位について,代理ができるくらいに深く理解
        • product managerとして振る舞い,正しくsolutionが開発されていることを保証
      • development_teamに何をどの順番で構築するか伝える
      • & 受け入れ条件を明確にして,条件を満たすテストを実行させる
        • 抽象的なtestは書く
  • 主な責任
    • 経済性の管理
      • 各levelで適切な経済的意思決定が継続的になされるようにする
      • release levelの経済性
        • product development中に生じる経済的に重要な情報に対応
        • scope,納期,予算,品質との間で継続的にtradeoff
        • sprint終了時に,次のsprintを実施するかどうか判断
          • product_backlogによる柔軟性
      • sprint levelの経済性
        • sprintごとのROI(投資収益率)を高めるため
        • sprintのcost: 期間とチーム 構成を把握
      • Product Backlogの経済性
        • 経済状態に応じた優先順位に責任
    • planningへの参加
    • product_backlogのgrooming
    • 受け入れ条件の定義と検証
      • product_backlog_itemの受け入れ条件を定義する責任
        • 受け入れ条件: 機能要求や非機能要求が満たされているとproduct_ownerが納得できる条件
        • sprint planningの前に受け入れ条件が必要 ← 準備完了の定義に含まれる
      • 受け入れ条件が満たされていることを確認する最終的な責任
      • 検証は,sprint実施時に行う
        • sprint reviewまで待たない
          • sprint reviewでのデモは完成した機能のみ
    • development_teamとの協力
      • 積極的な関与,献身,毎日果たすべきRole
    • stakeholderとの協力
      • 内外のstakeholder
  • 特性とskill
    • domain skill
      • product visionをまとめ,そのvisionに向けてチームをleadできるvisionary
      • visionは詳細でも明確でもなくてよい
        • 進んで変化に対応
      • business, domainの知識が必要
        • → 機能の優先順位づけ
    • 対人skill
      • stakeholderとよい関係が必要
        • → 交渉,合意形成
      • stakeholderとdevelopment_teamとの橋渡し
        • 適切な言葉で情報を伝えるcommunication skill
      • 特性
        • 現状に反する場合でも声を出す
        • ideaに自信がある
        • domain 知識がある
        • 単純かつ簡潔にわかりやすく情報を伝えられる
        • 信用されている
      • 周囲のmotivationを高められる
        • businessの課題を伝えて,仕事の目的を思い出してもらい,情熱を持続させる
    • 意思決定力
      • 意思決定の権限が必要
      • 適切なtiming, 正当な理由
        • 最終的な意思決定者
      • business needsと技術的な実現性とのbalance
    • 説明責任力
      • business resultを届けることへの説明責任
      • resourceを有効に活用する責任
        • product_backlogの変更,優先順位の調整,開発の中止が可能
    • stakeholder, Scrum_teamともにかかわる,フルタイムの仕事
    • product_owner, Scrum_master, development_teamは共通のgoalをもつ1つのunit
  • 1日の様子
    • 1週目,2週目
      • portfolio planning
        • portfolio managerや統治機構と,portfolioの期待値について議論
          • → 新しいproduct planningに影響.product planningのinputになる
      • product planning
        • 適切なstakeholderと一緒に新しいproductのvisionを考える
        • 終了したら,productの案をportfolio planningに提出
          • → 組織の経済的filterにかけられ,開発の予算やscheduleが決定
    • 3週目
      • 初期のrelease planning
        • 内部stakeholder, development_team_member, ときに外部stakeholderも参加する,product_backlog_item記述(story writing) workshopを含む
          • release planningで使用する概要levelのproduct_backlogを作成
        • 見積もりworkshop
          • 1~2日
          • development_team_memberが価値の高いproduct_backlog_itemの規模を見積もる
        • 最初のrelease planningのfacilitation
          • product_backlogの優先順位づけ
          • 制約(scope, schedule, budget)のbalanceをとる
          • stakeholderに加え,development_team_memberの一部~全員で,product_backlog_itemの並び順に影響を与える技術的な依存性を特定
          • goal: releaseの全体像の明確化.いつ何ができるのかというbusinessの最初の質問に答える
          • 1~2日
          • 継続的なactivity
    • 4周目~ Scrum_teamが最初のsprintを開始
      • 開始時に,sprint planningを統括
      • 実施中は,daily_Scrumに参加
      • 質問に答え,review可能になった機能をテスト
        • 毎日する必要があるので,できないときは代理を立てる
      • 内外のstakeholderに会って,次のsprintの優先順位が正しいことの確認
      • 今後のsprintで機能を選択するときに影響を与えるuserからの重要なinputを取得
      • product_backlogのgrooming
      • sprintの終わりに,検査と適応の2つのactivityに参加
        • sprint review, sprint_retrospective
  • 誰がproduct_ownerになるべきか
    • 社内開発
      • 開発の恩恵を受ける部門から任命された人がなる
    • 商用開発
      • product managerやproduct marketerなど,clientの声を代弁する人がなる
      • できるだけ多くのactivityに責任をもつ
        • 1人でこなしきれないほど膨大ならproduct_owner チームを作るが,Scrum_teamのproduct_ownerの役割は常に1人
    • 外部委託開発
      • 委託元の社員がproduct_owner
      • 固定価格契約は× → 複雑
    • component開発
      • 技術componentに注力 → Backlogの優先順位を決定できる技術志向の人がなる
      • feature_teamの技術的要求の優先順位や統括方法がわかるproduct_ownerが必要
  • その他のRoleとの組み合わせ
    • 余裕があれば,同じ人が複数のScrum_teamのproduct_ownerの担当も〇
      • それぞれの成果に関連があるときはこの方が簡単
    • product_ownerとScrum_masterの兼任は×
  • product_owner チーム
    • 1人の人間が, product_ownerとして意思決定し,stakeholderやScrum_teamとの橋渡しをする必要がある
    • 1人のproduct_ownerに対してproductに問題があるだけなら,productの問題に対応するべき
      • 必要なときのみproduct_owner チームを作る
    • product_owner proxy
      • 事業部門の人にproduct_ownerを担当してもらい,IT部門の人はproduct_ownerとチームのやり取りをするproduct_owner proxyを任せるcase
      • 特定の状況でproduct_ownerの代理になれる人
        • 本当のproduct_ownerではなく,代わりに戦術的な意思決定をする人
        • 責任はproduct_owner
    • chief product_owner
      • 階層的にscale
      • 各チームのproduct_ownerが上の階層に投げることなく,ほとんどの意思決定をできるようにしておく
  • まとめ
    • product_ownerのRole
      • productの統括を認められた中心的な存在
    • product_ownerの重要な責任と特性
    • Scrumの各activityにおけるproduct_ownerの行動
    • 誰がなるべきか

Ch10 Scrum_master

  • 概要
    • Scrum_master: Scrumのvalue, principle, practiceがみんなに正しく理解され,受け入れられるようにする
      • as a coach
      • 自分たちに適したperformanceの高いScrum手法で開発できるように,processのleaderとして支援する
  • 主な責任
    • coach
      • Scrum_teamのAgile coach
        • development_teamとproduct_owner間の垣根を取り払う → product_ownerが直接開発を駆動できる
        • 問題には支援する.impedimentは解決する.
          • 新人product_ownerが責任を理解し,Roleを果たせるようcoaching
          • product_backlogのgroomingなどのactivityを継続的に支援
        • Scrum_masterとproduct_ownerの関係: sport チームのcoachとownerの関係に似ている
          • Scrum_master: Scrumでbusinessの成果を最大化,期待を管理,product_ownerがチームに必要なものを提供,変化に対するproduct_ownerの不満や要求を聞き出し,チームが実行可能な改善へと翻訳
    • servant leader
    • processの権威者
      • Scrumのvalue, principle, practiceを順守させる権限
      • チームのprocessの改善を継続的に支援して,届けるbusinessのvalueを最大化
      • 機能部門managerやproject managerが持つ権限とは異なる
        • チーム memberの採用や解雇はできない
        • チームに作業を依頼したり,仕事のやり方への指示はできない
        • 仕事を完成させる責任はない
        • チームが自分たちのprocessを定義して遵守することを支援するだけ
    • 防御壁
      • チームがvalueを届けることに集中できるようにする
    • impedimentの除去
    • change agent
      • 意識の変化を支援
        • 変化の必要性やScrumの影響・利点を理解してもらう
      • 長期的な成功につなげる
      • 大きな組織では複数のScrum_master
  • 特性とskill
    • 博識
      • いずれも専門のtop levelでの知識は不要だが,ある程度の知識は技術でもbusinessでも必要
    • 質問力
      • 内容を促す質問(probing question)
      • 自分で答えを見つけられることを認識してもらう
    • 辛抱強い
      • 自分の方がチームの集合知よりも賢いと考えない
      • 定期的に内省を促す質問をして,チームにsolutionを見つけてもらう
    • 協力的
    • 保護力
      • 経済的に正しいbusiness judgeができるようにチームを保護
      • Scrum_teamが健全なbalanceを取れるように支援
      • Scrumからさまよい出るmemberを支援.チームが難しさを克服できるようにする
    • 透明性
  • 1日の様子
    • Scrumのactivityの開催やfacilitationに毎日時間を使う
      • sprint planning
      • sprintの実施
      • sprint review
      • sprint_retrospective
      • daily_Scrum
      • activityの準備・統括・Scrum_teamが価値の高い成果を達成できるように支援することも含む
    • 毎日チーム memberをcoaching
    • 毎日一定時間をcommunicationに使う
    • sprintでは,product_ownerとともにproduct_backlogのgrooming
    • change agentとしての時間
    • impedimentの除去
  • Roleを果たす
    • 誰がなるべきか
      • project managerやproduct managerからScrum_masterになることもある
      • technical leadは△
      • managerとの兼任も△(×)
    • 必ずしもfull timeではない
    • ほかのRoleとの組み合わせ
      • ほかのRoleと兼任するより,複数のチームのScrum_masterになるのが〇
  • まとめ
    • Scrum_masterのRoleなど

Ch11 development_team

  • 概要
    • 機能横断的
  • Role別のチーム
    • 技術的skillを一通り備えたチームが必要
    • できるだけ機能横断的
  • 主な責任
    • sprintの実施
      • 大半の時間を割く
      • 自己組織化
    • 日々の検査と適応
      • daily_Scrumに全員で参加
    • product_backlogのgrooming
      • sprintの10%を使い,product_ownerのactivityを支援
    • sprint planning
      • sprintの期間に応じて,半日~1日
      • 反復して実施, just_in_time
    • productとprocessの検査と適応
      • sprint review
      • sprint_retrospective
  • 特性とskill
    • 自己組織化
      • bottom up型の創発的な特性
        • 外部からの圧力なし
      • 複雑適応system
        • 多くのentityが様々な方法でやりとり
        • やりとりは,単純で局所的なruleで統括され,定期的なfeedback
        • 大いに堅牢で斬新
      • managerは自己組織化チームのための環境を設定・再構築する
    • 機能横断的な多様性と十分な能力
      • product_backlog_itemを選択し,Scrum_teamの完成の定義を満たして動作する,高品質の機能を作り出す
      • 成果の手渡しの数を最小化
      • 複数の視点が良い成果になる
        • 問題解決のための認知toolの持ちより
          • 解釈,戦略,mental model,手法やsolutionの嗜好が異なる
          • → すばやいsolution,高品質の提供物,大いなるinnovation,という観点から良い成果につながり,経済的valueへと変わる
      • チームの多様性のために,senior, juniorを組み合わせる
        • みんなで協力して学習し合う健全な環境
    • T型skill
      • 幅広さと深さ
      • 継続的に学習してskill setを増やせるような環境が必要
        • skill set: domain knowledge, technical knowledge, thinking skillなど
        • 学習と実験の時間がうまく作れるように,managerがチーム memberを支援
      • 専門家は,複数のチームに余裕がある状態で時間を分割するか,ほかのmemberの学習支援に時間を使う
      • チーム memberがcoreとなる専門分野をもち,全体として柔軟性をもたらすような,skillに重なりのあるチームを作ることがgoal
    • 銃士の姿勢
      • one for all, all for one
      • 仕事を成し遂げる責任をチーム member全員が負う
      • できないことがあるときは,skillある人に学習支援をしてもらい,チームの総合力を高める
      • 1人に負担がかからないように作業を構成
      • 議論に多様性
    • 広帯域のcommunication
      • 有益な情報をすばやく交換,overhead少なく効率的にやり取り
      • 情報共有の頻度と品質を向上
        • → 検査と適応の機会が増え,意思決定を迅速にできる
        • 情報の経済価値は時間に依存 → 共有速度が高まれば,チームは情報の価値を最大化できる
      • 方法
        • face to face
        • TV会議system
        • 機能横断的チーム
          • 形式的な提出物によるやり取りの量も回数が少なくなる
        • valueのない儀式を減らす
        • 小さなチーム
          • channel数の増加率
    • 適切な規模
      • 小さなチームの理由
        • 社会的手抜きが少ない
        • 建設的なやり取りが頻繁に起こる
        • 調整に必要な時間が少ない
        • 誰も陰に埋もれない
        • 小さなチームの方がmemberを満足させられる
        • 有害な過度の専門化が発生しにくい
      • 人数が多すぎたら,9人程度にチームを分割
      • Scrum projectのscale: 複数のScrum_teamを作る
        • Scrum of Scrum
          • 上位levelのdaily_Scrum相当のものを開催する
    • 集中とcommitment
      • 集中: チーム memberが積極的にかかわって,チーム goalに専念
      • commitment: よいときも悪いときも,チーム goalの達成に尽力
      • 3つ以上のprojectの仕事を同時に行うのは経済的でない
        • 調整・想起・情報の追跡に時間がかかり,valueを付加する仕事の時間が減るため
        • 基本は1つがよい
    • 持続可能なpaceで仕事をする
      • Scrumの優れた技術的なpracticeで平準化
    • 長寿
      • groupではなくチーム
      • チーム: 機能横断的で多様性のある協調性の高い人たちで構成され,visionを共有し,それを実現するために協力する集団
      • group: 共通のlabelがついた人の集団
      • 長寿は経済的に好ましい
      • forming, storming(争乱期), norming(規範期), performimg
      • 上手く機能したチームはbusiness資産になる
        • 歴史的に重要な情報を蓄積
          • Velocityや見積もりの履歴
      • Agileの通貨はチーム
        • 個人と対話に価値
      • チームの信頼,一貫性,作業効率を保つ
      • 人ではなくチームを移動させる方が,経済的に優れている
      • チームは資産
        • 同時に行うWIPの数やproductの種類を決めるときのcapacityの単位
  • まとめ
    • development_teamのRole
      • product_backlog_itemを出荷判断可能なproduct incrementに変える責任
      • sprintにおける責任
      • 10個の特性
      • 自己組織化,機能横断的で多様性がある,仕事を成し遂げるために十分なskillがある
        • T型skill
      • 銃士の姿勢
      • 広帯域のcommunication
      • 小さなチーム
      • 集中とcommitment
      • 長寿

Ch12 Scrum_teamの構成

  • チームの構成や,チーム間のかかわり方が,Scrumをうまく進めるために重要になる
  • 概要
    • businessのvalueを提供するために,複数のScrum_teamsの協力が不可欠
  • feature_team or component_team
    • feature_team: 機能横断型かつcomponent横断型のチーム
    • component_team: 何か1つのcomponent, subsystem(featureの一部)のdevelopmentにのみ注力
      • a.c.a. asset チーム, subsystem チーム
      • 同じ専門skillを持った人たちの集まりで構成される実行部隊など
      • 中央管理型の共有resource的
      • 各component_teamが作ったcomponentを統合し,完全なfeatureにまとめてdelivery
    • 一番良いのは,機能横断型のfeature_team
    • 移行措置としては,1つのfeature_teamがfeatureをproduct_backlogから取り出し,作業完了までの責任を持ち,完成までの手配をする
      • 個々のcomponent_teamも残り,各チームからfeature_teamのmemberをassignし,仲介者・収穫者の責務を持たせる
      • 頻繁にやり取りするcomponentを1つのfeature_teamにまとめる
    • component_teamを導入するのは,resourceを1つのチームにまとめて集中管理した方が合理的なときだけ
  • 複数チーム間での調整
    • Scrum of Scrum
      • チームをまたがる作業を複数チーム間で調整
      • question
        • 前回以降で各自のチームの作業で,ほかチームに影響しそうなもの
        • 次回の各自のチームの作業で,ほかチームに影響しそうなもの
        • 各自のチームの今抱えている問題で,ほかチームに助けてほしいもの
      • 階層化も〇
    • release train
      • vision, planning, 複数チーム間の依存関係などを調整するための手法の1つ
      • チーム間でのsync
      • product levelでの高速で柔軟な流れに注力
      • featureが「駅を出発」するscheduleが決まっている
      • rules
        • 頻繁に定期的にplanning, solutionのrelease日またはPSI(出荷判断可能なincrement)の公開日を決めておく(固定期日,固定品質,可変scope)
        • すべてのチームでiterationの長さをそろえる
        • 全体での中立的かつ客観的なmilestoneを決める
        • 継続的なsystem integrationを,top level(system level)だけでなくfeature level, component levelで行う
        • releaseできるincrementを定期的に(一般的に60日/120日ごと)用意し,client向けのpreviewや内部review, system level のQAに使えるようにする
        • system levelのhardening iterationを実行し,技術的負債の返済やrelease levelの検証・テストを行う
        • 各チームを同じような構造にするために,基盤になる各種component(interface, SDK, 共通でinstallするsoftware, license, UX framework, data, Web serviceなど)をきちんとそろえる
      • richな概念
        • portfolio level, release levelなど,何段階かの詳細度で考えられる
        • enterprise backlog modelに基づく
          • portfolio_backlog, program backlog, チーム backlogの3段階のbacklog を使う
          • チーム levelのrelease train
            • 各チームが数個のfeature areaに分かれてまとまる
            • 現実的な頻度で,feature areaをまたがったsystem全体の統合やテストを行う
              • 列車が発射する直前をhardeningのための時間と決めていることもある
      • release trainの流れ
        • release planningのmeeting
        • sprintの実行
        • release train levelでの検査と適応
  • まとめ
    • Scrum_teamを構成するさまざまな方法
      • feature_team
      • component_team
      • feature_team, component_teamの組み合わせ
        • 徐々にfeature_team主体に移行し,codeの共同所有を実現
    • Scrum of Scrum
    • release train
      • 数多くのScrum_teamのactivityを調整

Ch13 manager

  • 組織内にはScrumと関係ないRoleがあり,それらも組織に必要
  • 各managerのRoleを見る
  • 概要
    • Scrumでもmanagerはimportant
    • functional_managerの責務: teamの編成と育成, 環境を合わせてなじませる,value創造の流れを作る
  • teamを編成する
    • 境界を定める
      • managerが,product, project(砂場)を定める
        • teamの構成を決める(誰をどのprojectとするかを決める)
          • teamはprojectの中で自己管理する
        • 自己組織化したteamにどこまで許すか決定
        • いくつのprojectを作るか決定し,各projectの境界も定める
    • 明確なgoalを定める
      • 目的と方向性をteamにもたらす
      • product_ownerがgoalをより具体化する
    • teamの体制を決める
      • business上のneedsや制約とのbalanceをうまくとったteamを作る
      • 機能横断的なScrum teamを作る
      • 各分野やcommunity(functional area)にfunctional_managerがいて,各functional areaからmemberを選んでteamを組む
    • teamの構成を変更する
      • memberの変更
    • teamに権限を持たせる
      • 自己組織化したteamでお互いをよりうまく管理することの達成のため,team_memberに責務を委譲
      • 権限のlevel
        • 通知,説得,相談,合意,助言,確認,委譲
      • 信頼し,委譲した分は任せる
      • team_member間に銃士の姿勢を育てる
  • teamを育てる
    • managerがteam を管理するわけではない
    • teamを活気づける
      • 楽しくて創造的でvalueをもたらせるような環境を作るのが責務
        • → motivation, energyを引き出す
      • task levelの作業のassignはやる気をそぐ
    • 能力を伸ばす
      • memberが常に何かを学び,skill setを磨き続けられるような環境づくりをする
        • 研修の受講,カンファレンスへの参加
      • 個別のfeedbackの頻度を調整し,各memberの直属の上司が属するteam内での学習loopにマッチさせる
        • sprint単位など
      • 個人のperformanceがteamのperformanceを以下に支えるかという観点で行う
    • functional areaのleadershipを発揮する
      • functional area での一貫性を保ち,memberを指導する
      • areaに関する標準を設定
    • teamの安定を保つ
      • teamの構成を可能な限り変えずに保ち続ける
  • 環境に合わせてなじませる
    • value chain 全体がScrumを受け入れるようにする
    • Agileの価値を広める
      • managerはAgileの価値と原則を受け入れる
        • 理解し,信じ,実践し,周囲にも仕向ける
    • 組織内のimpedimentを除去
    • 社内調整
      • 全体をAgileのprincipleに合わせていく
    • 対外調整
      • simplest: ほかの組織のScrum_teamをまるごと借りる
      • 固定金額の契約は×
  • 価値創造の流れを作る
    • manager's Role @Scrum
      • 戦略的な方向性を定める
      • 戦略目標を達成するための組織的resourceを,採算を考慮して揃える
    • 全体的な視点で考える
    • 財政の管理
      • 任された財源をどのように使うか責任
      • portfolio management, corporate governance
    • 評価や報告の管理
      • 評価や報告をScrumの価値や原則に見合ったものにする
        • 作業の手待ちを評価
        • 動作する検証済みの成果物で進捗を見積もる
        • すばやいfeedback flow を作る
      • 革新会計の要点となる評価基準
        • 革新会計: 不確定要素が多い状況でproduct, serviceを作るような組織でimportant
        • 行動につながる評価基準を使って,自分たちがどの程度すばやく学べるか評価
          • → business valueのある結果を得るための進捗を見る重要な指標
        • 3段階
          • 実用最小限の製品(MVP)を作って,組織やproductの現状に基づいた行動につながる評価基準のbaselineを設定
          • productのincrementalな改良をもとに行動につながる評価を向上させ,目標値に近づける
          • 行動につながる評価の値から目標に向かっての進み具合が実証できればそのまま続行.実証できなければ,新たな戦略にpivotして,この手順を繰り返す
  • project manager
    • Scrum_teamにおける project managementの責務
      • Scrumの3つのRoleに分散している
      • 調整を任せるのではなく,さまざまな分野にまたがる依存関係を把握して各所とやり取りし,ほかチームとの調整を効率的にできるようにすること
    • project managerのRoleを残す
      • 大規模で複雑な開発の場合は,手配や調整にからむタスクが非常に多いので,そのままRoleを残すのも〇
      • ただし,かなり大規模になったときのみ
        • できる限り,チーム間でのcommunication channelを見直すべき
          • Scrum of Scrumなどを使う
      • 調整の責務を第3者に渡すべきではない
        • project managerはScrum_teamのassistant(servant leaderのようなもの)
          • system全体の視点で考えて,各clusterや個々のチームのために動く
          • チーム間の調整に何が必要か,誰もがきちんと理解している状態にする.実際の調整はチーム自身で行う
      • 大規模なproduct/service developmentでほんの一部だけがScrumを採用している場合にも使える
  • まとめ
    • Scrumの組織におけるfunctional_managerのRole
    • 4 category
      • team編成
      • team育成
      • 環境を合わせてなじませる
      • 価値を創造する流れを作る
    • 伝統的な組織とScrumを使った組織でのfunctional_managerの責務の比較
    • project managerの責務,Role

Part 3 planning

Ch14 Scrumのplanning principle

  • 伝統的な開発よりplanningに時間を割く
  • Scrum principleの一部をさらに掘り下げ,planningにどのように適用するのか見る.その土台となる議論を見る.
  • 事前にきちんと計画を作れると思うな
    • 検査と適応の経験に従う
    • 最初のうちにある程度はplanningの成果物を出す
      • 事前のplanningとjust_in_timeでのplanningのbalanceのため
  • 事前のplanningのやり過ぎに注意
  • planningの選択肢は,最終責任時点まで変更可能にする
  • planを守ることよりも,planの調整や再計画を重視する
    • knowledgeがない状態で作られたため,事前のplanは抜けがある
  • plan list management
    • WIP management
    • 無駄なplanningの作成物を作らない
  • 早めにrelease, 頻繁にrelease
    • すばやいfeedback, ROIの向上
    • 市場に出せるlevelは保つ
  • 早めに学び,必要ならpivot
    • pivot: 方向転換しながらもそれまでに学習したことはそのまま維持し続ける
      • 製品,戦略,成長のengineに関する根本的な仮説を新たに策定し,それを検証できるコースに方向転換すること
    • 学習loopを高速かつ経済的に回すことが目標であり,正しくない方向に向かっていればpivot
  • まとめ
    • Scrumにおけるplanning principleの概要を見た
    • 原則に従い,経済面で妥当なplanningを達成する
    • 事前に用意する適度な量の計画と,実際の結果をふまえたより詳細なjust_in_timeの計画との間で,うまくbalanceをとる

Ch15 さまざまなlevelでのplanning

  • Scrumにおけるplanningの概要を全体的な視点で見る
  • 概要
    • 5種類のplanning
      • 範囲,作成者,対象,成果物
  • portfolio_planning
    • 複数のproductの中から,どれをどの順番でどの程度の期間で進めていくか決める作業
    • 概念的にはproduct_planningより上だが,inputの1つはproduct_planningで得られる新たに考え出したproduct idea
  • product_planning(envisioning)
    • 作ろうとしているproductの本質を見出して,productを作るための大まかな計画を作る
    • まずvisionを作り,その後,概要levelのproduct_backlogを作る
      • product_loadmapを作ることも多い
    • product vision
      • user, clientといったstakeholderたちが得る価値を明確に説明するもの
    • 概要levelのproduct_backlog
      • まったく新しいproductを作る場合なら,少なくとも最低限の要件は事前に決めて,product_backlogに含める
      • 少なくとも最優先のitemがどれになるかも判断する
      • 想定されるuser_storyを設定
    • product_loadmap(release loadmap)
      • productを今後どのように構築してどのようにdeliveryするのかのincrementalな性質を示し,各releaseに含まれる重要なfeatureについても示す
      • continuous deploymentがあっても有用になりうる
    • 意思決定者に十分な安心感を与え,product developmentを認めてもらうため
  • release_planning
    • incremental deliveryに向けて,scope, 期日, 予算とのtradeoffを考慮する
    • product_planningが終わったら,releaseの最初のsprintを開始する前に最初のrelease_planningを実施する
      • そのreleaseでどれだけのものを作るか,それをいつreleaseするのかの間でbalanceを取ったもの
    • ある程度のitemをproduct_backlogに用意して見積もる必要がある
    • product_backlogに線を引く
    • product_loadmapとproduct_backlogをより強く結びつける
    • 期間を,そのreleaseを達成するために必要なsprint数で表す
    • 直近の数回のsprint程度の推測は,作業の調整や事前に必要な支援のために有用.それより先の推測は無駄
  • sprint_planning
    • product_backlog_itemの中から,Scrum_teamが次のsprintでどのitemに取り組むかを決める
    • 各sprintの最初に行う
    • sprint backlogを作る
      • product_backlog_itemの完成に必要な作業を,task levelで記述
    • より踏み込んだlevelで,just_in_time planning
  • daily_planning
    • 最も詳細なlevelのplanning
    • team_memberが集まり,高度に可視化されたstyleで,当日の大まかな予定を話し合う
    • resourceのproblemに気づけるようにする場でもある
    • 良い流れでsprintを進める
  • まとめ
    • さまざまな詳細度でのplanningが,Scrumの開発中にどのように発生するのかを見た
    • Scrumの階層的なplanningの図

Ch16 portfolio_planning

  • 複数のproductを作るにあたって,product_portfolioをどのように管理するか,継続的に理にかなった選択をする必要がある
  • portfolioの管理processを,Agile practiceとうまく協調させる必要もある
  • 概要
    • portfolio_planning: portfolio_backlogのitemから,どれをどの順番にどの程度の期間で進めていくか決める作業
      • item: product, そのincrement(1回分のrelease), or project
    • 素早く柔軟な流れを壊さないように実施する
    • timing
      • product_planningのdataを使って,どのproductにどの順に投資するのかを判断し,portfolio_backlogにまとめる
      • 新たなproductに対してだけでなく,既存(仕掛け中)のproductについても見直す
    • 参加者
      • 内部のstakeholder
        • business的な大局観が必要
          • portfolio_backlog itemの優先順位の決定や,仕掛け中のproductに対する判断のため
      • 各productのproduct_owner
        • 必要なresourceを主張
      • option: senior architect, technical leader
        • 技術的な制約を考慮
    • process
      • output: portfolio_backlog, active product群
      • outputのために,4種類のactivityがある(→ 以下に続く)
  • schedulingの戦略
    • 組織内のproductに割ける限りあるresourceを,経済的に理にかなった方式で配分するために,product群を優先順位づけ
    • lifecycle 収益で最適化
      • 最適化が効いているかどうかをどの変動要因で判断するか決定する必要
      • → lifecycle 収益を使ってあらゆる判断やtradeoffを見る
        • 標準化されていて使いやすい経済的枠組み
      • lifecycle 収益の総量が最大となるように,portfolio_backlog内のproductを並べ替える
      • goal: portfolio_backlog itemを並べ替えて,portfolio全体のlifecycle 収益を最大化すること
      • 最も影響する重要な2つの変動要因
        • delay_cost
        • 存続期間(作業量やproductの規模の代替)
        • → いずれも各productで異なる場合は,重み付きで一番短いjobを優先する(WSJF)
          • delay_costを存続期間(or 実装の作業量)で割ったもの
    • delay_costを算出する
      • 経済的な意思決定をするにあたって欠かせない情報
      • ほとんどの変動要因が時間の影響を受けるという事実
        • → 時間軸を必ず考慮してportfolio_backlog内のitemを並べ替える
      • 算出方法: spread sheetを2つ作り,遅延がない場合と遅延がある場合の2種類の収益をそれぞれ計算すればよい
      • model
        • user的な価値
        • 時間的な価値
        • riskの削減/機会の確保
        • 以上の3つの属性について,delay_costを1から10までの数字で設定し,合計したものがproductのdelay_costになる
      • または,よくありがちな特徴でdelay_costを分類する
        • 線形, 巨大なcost, すぐにでもやるべき, 固定期日, 対数, 実体がない
    • 見積もるのは正確性であって精度ではない
      • portfolio_backlogのitemを適切にschedulingするために,各productの作業量/costを理解する必要
      • 最初の見積もりが必要になる時点では手持ちのdataはたかが知れているので,精度より正確性に注目する
      • Tシャツのサイズなどでcostの範囲を関連付け
      • → すばやく見積もれる,十分な正確さを得られる,portfolio levelで次の動きを決めるための情報を用意できる
      • → 無駄な時間を削減,見積もりの数字を過大評価したり誤った安心感を与えることもなくなる
  • inflowの戦略
    • product developmentを始めるかどうかの判断において,組織の経済的filterを以下に適用するのかを見る
    • 経済的filterの適用
      • envisioningのoutputは,product visionに加えて,信頼の閾値を明確にするための情報となる
      • → このdataをもとに,product developmentを進めるか中止するか判断
      • ↑ このactivityが新しいproductへの「経済的filterの適用」
        • 組織の資金需要を満たすかどうかを確かめるactivity
      • 組織ごとに経済的filterを定義
        • よいfilterはコストをはるかに上回る価値を生み出せる機会をすばやく承認できる
        • それ以外の機会は,やむを得ない事情がある場合を除いて却下すべき
          • costや価値に合意が取れず決断ができないなら,十分な資金援助が得られないことは明白
          • ほとんどの組織ではよい機会がありあまっている
    • 追加と取り出しのbalanceを取る
      • 年に1度で達成内容の詳細をproduct levelまで全部決めてしまう必要はない
      • productをportfolio_backlogに追加する頻度を高くする(月に1度か少なくとも四半期に1度)
        • → 新しいproductのreviewやportfolioへの追加にかかるcostや労力を大きく軽減できる
        • → portfolio_planningの全体的な安定性や予測可能性を高められる
      • productを小さめにすることにも力を入れる
        • 頻繁に取り出せるようにしておく
        • → inflow, outflowのbalance〇
      • portfolio_backlogの肥大化 → portfolio_backlogに追加するproductの流れを絞る
        • 経済的filterを調整して,productを承認する条件を厳しくする
        • → より価値の見込めるproductだけを承認
    • 創発的なchanceへの素早い対応
      • 創発的なchance: 事前に想定できなかった出来事や,まず起こりえないと思われていたこと
        • 経済的valueは急降下していく
      • 機会についての評価を月に1度などのpaceで頻繁に行っていて,適切な経済的filterを設定しており,releaseの規模を小さくしてWIPを増やさないようにしていれば,対応できる
    • 小さめなreleaseを頻繫に行うための計画
      • 明白なmeritのほかに,コンボイ効果を回避できる
        • 大きなproductが共有resourceを占有することを回避
      • 徐々にreleaseしていった方が経済的なmeritが大きい
      • 一括releaseをできるだけ避けるようにplanning
  • outflowの戦略
    • 作業者の手待ちではなく作業の手待ちに注目
      • productをportfolio_backlogからいつ取り出すのか判断するカギとなる戦略
    • WIPを制限する
      • 自分たちが完了させられるだけの量に達したら,それ以上のproductをportfolio_backlogから取り出さない
      • 制限の程度
        • Scrum_teamがいくつあるか,それぞれのteamがどのtypeのproductの作業ができるかで判断
    • team全員の準備が整うのを待つ
  • 仕掛け品の戦略
    • 現在作業中のproductについて,開発を続行するかpivotするか停止するかを判断する助けとなる
    • 定期的に判断
    • 臨時にも判断する
    • 限界費用を使う
      • これまでにいくら使ったのかは一切無視して判断する
      • 判断のflow
        • 資金の追加投入に値するか → 維持
        • 必要最小限の機能が実装されているか → delivery
        • 別の未知はあるか → pivot
        • → 打ち切り
  • まとめ
    • portfolio_planningに関する11の重要な戦略
      • すべて互いに補強し合う
      • 各categoryで1つずつのみの場合
        • delay_cost
        • 小さめのreleaseを頻繁に
        • WIPを制限
        • 限界費用

Ch17 envisioning(product_planning)

  • product_backlogを最初に作るときに,productについてのvisionのための事前の作成物を用意するactivity
  • 概要
    • goal: ideaを詳しく説明し,できあがるであろうproductの本質を示し,実際に作るための大まかなplanを用意
      • ideaをportfolio_planningに組み込めるだけの十分な自信が必要
    • productの資金調達にまず不可欠なのは,visionを持つ
    • client, feature, 概要levelのsolutionについて理解するために必要な程度に情報を把握する
    • productにかかるであろうcostの見当をつける
    • 短時間で実施する
    • timing
      • 何度も繰り返す
      • きっかけは誰かからのidea
        • 組織の戦略的filterを通し,組織の戦略方針に一致しているか調べ,さらなる調査と資金投入の価値があるか判断
        • 通過したら,最初のenvisioning
          • これから作ることになるproductに関する十分な理解を得て,最初の最低限のreleaseがどんなものであるべきか定義
          • → 最大限の価値をすばやく提供,costを抑えられる,すぐに役立つfeedbackを得られる
          • feedbackで間違いを判断したら,pivotしenvisioningをやり直して計画を見直す
    • 参加者
      • 最初のenvisioningに必ず参加が必要なのはproduct_ownerのみ
      • 内部のstakeholderも巻き込むことが多い
      • specialist(market分析,投資対効果の拡大,UX design,system architectureなど様々な分野)もかかわることが多い
      • Scrum_teamが割り当てられてからは,Scrum_master, development_teamも含めてteam全体で参加すべき
    • process
      • input
        • 最初: 戦略的filterを通過したidea
        • 2回目から: pivotしたidea
          • userやclientからのfeedback, 財源の状況の変化,競合の予期せぬ動き,その他重要な変更から,ideaを更新,修正する
        • planningの範囲
        • いつまでにenvisioningを完了させるか
        • 割けるresourceの量や種類
        • 信頼の閾値
          • envisioningの完成の定義
          • より詳細な開発に向けた出資をするべきか否かを意思決定者が決断する際に,十分な確信をもって結果を出せるようにするために必要な情報をまとめたもの
  • SR4Uの例
    • 最初の開発に進むべきか否かの判断材料
      • 最初のproduct vision, product_backlog, product_loadmap
      • userについての最初の前提の検証
      • userについてのそのほかの重要な前提・仮説や,最初のreleaseでテストしようとしているfeature群に関する説明
      • その他の全体を確かめたり,最初のreleaseが期待通りか判断したりするために使う,計測可能な基準
      • 対応すべき疑問点のlist
  • visionづくり
    • 説得力のあるvisionを作って共有
    • 説明しやすいsimpleなもの
      • 明快な指針を示せる
    • stakeholderがいかにして価値を得るのかという観点で語られることが多い
      • category
        • 参入条件
        • 使用可能性
        • 差別化要因/clientを喜ばせる
        • 妨害/ハードルを上げる
        • cost削減/時間の節約
    • formatの例 → 一番うまくあてはまるものを選ぶ
      • elevator statement
      • product data sheet
      • product vision box
      • conferenceのslide
      • press release
      • 雑誌のreview
  • 概要levelのproduct_backlogの作成
    • visionの完成: 概要levelのproduct_backlog_itemを上げる準備が整う
    • user_storyでのepicをenvisioningで作る
      • product levelのplanningに対応した大規模なuser_story
      • epic levelのstoryとvisionを組み合わせて,もう少し詳細なlevelでproductを表現し,幹部経営者やScrum_teamに渡す
    • visionを作ったのと同じ人たちが,storyも書く
  • product_loadmapの定義
    • visionと概要levelのproduct_backlogが完成したら,最初のproduct_loadmapの作成に進める
    • product_loadmap: 一連のreleaseでproduct visionのどの部分を達成していくか示す
    • incremental deploymentについて,当初の概要を示す
      • 1回のreleaseの規模を小さくして,releaseをより頻繁に行う
      • 小さめのrelease 1度で済んでしまうような計画なら不要
      • 頻繁なrelease: 個々のreleaseをrelease可能な最小限のfeature(MRF)単位にまとめる
        • MRF, a.c.a. 実用最小限の製品(MVP), 市場性のある最小限のfeature(MMF)
      • MRFの補完として,定期的なrelease(四半期ごとなど)を採用するのも〇
        • product_loadmapがsimple
        • わかりやすい
        • 内外を含めた関係者全員へreleaseの周知がしやすい
        • 組織のreleaseを事前の予測通りに活用できる
        • ほかのgroupもその組織の計画に合わせて動きやすくなる
        • MRFの開発がrelease間隔より短く済む場合は,さらに追加で価値の高いfeatureを作る
    • release goalの明示
      • releaseの目的と期待される成果を示す
      • solutionのreleaseの内容を決める助けとなるあらゆる要素を考慮
        • target client
          • 各segmentのclientに対していつどのように対応するか示す
        • 概要levelのarchitectureや技術面の課題
        • 市場の重要eventなど
      • 大雑把な予想に過ぎない
        • 詳細な情報が分かり次第loadmapを更新する
    • どの程度の将来までカバーするか
      • 大規模なvisionでも,理にかなった必要な分だけのloadmapを作る
      • 誰かに出資をお願いする期間はカバー必要
  • その他のactivity
    • 信頼の閾値を満たすために関係があると参加者が認めた作業なら,どんな作業を含めてもよい
      • e.g. 市場調査,競合productとの比較分析,大雑把なbusiness modelを作成して経済的filterと照合
    • envisioningを複数のsprintに分けて行うときには,担当teamがenvisioning関連の作業のbacklogを管理する
      • 優先順位を決めて,短期間(1週間程度)のsprintを回す
      • 知識を得るためのsprintもある
  • 経済的に理にかなったenvisioning
    • envisioning系の作業は,project charteringやproject inception, or project initiationと呼ぶこともある
      • このprocessを,総合的なstage gate型管理modelの一部として組み込んでいる組織もある
        • 重厚で儀式的なprocessになってはいけない
    • できるだけsimple
      • productの性質や規模,risk levelに基づいて,必要最小限の事前planning,そして知識獲得のための作業を行うのみ
      • 詳細な作成物はjust_in_time
      • goal: 現時点での最良な判断をするのに十分なだけの情報を,資金や期間を考慮して得ること
    • 指針
      • 現実的な信頼の閾値を目指す
        • 信頼の閾値: envisioningを終えてproductをportfolio_planningに送るために,最後にクリアすべきハードル
          • ハードルを上げるほど,クリアするために長い時間を要する
            • → delay_cost → クリアのためのcost up
          • WIPの無駄は避ける
        • → やり過ぎず,役立つlevelの閾値の設定が必要
          • 分かれ目は,組織やproductの特性で決まる
        • 一連の開発作業の明確なgoalと,結果を見て次の作業に進むかどうか判断するときの基準が知りたい
      • 注目するのは短期間だけ
        • 1度にやり過ぎず,主に,直近のreleaseで必須となるfeatureに注目する
      • すばやく動く
        • envisioningは手早く効率的に済ませる
          • → できあがるのが早まり,検証できる
          • → delay_costを小さくできる
        • 緊迫感をもってproductについての判断を下せるようになる
          • 適切なresourceを割り当てて,envisioningを適切なtimingで終えられるようにする助けとなる
        • 方法
          • envisioningの完了予定日をenvisioning teamに知らせておく
      • 検証による学びに投資する
        • envisioningのactivityを経済面で評価するときの基準
          • 対象とするclient, feature, and solutionについての検証による学びを得るためにどの程度役立ったのか
      • incrementalに出資する
        • 出資にかんする判断は,より正確な情報がそろうのに合わせて常に行う
        • envisioningに要する時間も短縮できる
      • 早めに学んでpivotする(fail_first)
        • 責任をもって効率的にresourceを管理し,手早く格安にenvisioningを行う
        • 資金負担を大きく減らすことができる
  • まとめ
    • envisioningについて
    • 具体例で,product visionや概要levelのproduct_backlog, product_loadmapを作る流れを見た
    • envisioningの際の知識獲得sprintを実行する方法
      • envisioningを終えるための信頼の閾値を満たすために有用
    • 経済的に合理的なenvisioningを行うための指針
      • 事前のproduct_planningとそれに続くScrumのclient value createとをうまく合わせられるようになる

Ch18 release_planning(長期計画)

  • release_planningでは,scope, schedule, budgetといった制約の下で,clientにもたらす価値と全体的な品質とのbalanceを取らなければならない
  • release_planningをどのようにScrum frameworkに組み込むのか,固定期日と固定scopeのそれぞれのreleaseで,release_planningをどのように行うか見る
  • 概要
    • featureをclientに届けるためのreleaseの周期を適切に定める必要
    • continuous deployment(delivery): sprintの終わりを待たず1つのfeatureが完成するたびにrelease
    • どの周期でも,ある程度の長期間にわたる概要levelの計画(release_planning)を作っておくと便利
    • a.c.a. 長期的planning, milestone駆動planning
    • 狙い: 重要な変動要因(期日,scope,予算など)のbalanceを取ったうえで,将来の状態を定める
    • timing
      • sprintごと
      • envisioningやproduct_planningのあと
      • product_planningの目的: productがどうあるべきか思い描く
      • ←→ release_planningの目的: そのproductのgoalに向けて,次の一歩を定める
      • 初回releaseの前に最初のrelease_planningを行い,release planを作成する
        • 通常は1日から2日程度だが,productの規模やreleaseのrisk,参加者のproductへのなじみによって変わる
        • 完全でなくてよい
        • 検証による学びをもとに更新する
          • sprint review中でも次のsprintの準備のときでもよい
    • 参加者
      • stakeholderとScrum_team全体が,互いに協力し合って行う
      • businessと技術のtradeoffを考慮して,もたらす価値と品質の間で最適なbalanceが必要なため
    • process
      • input
        • product_planningのoutput: product visionや概要levelのproduct_backlog, product_loadmap
        • releaseにかかわるであろうteamのvelocity
      • 繰り返すactivity
        • releaseの制約であるscope, 期日, budgetを確認し,これまでの流れやわかってきたことから,制約を変更する必要があるかどうか見直す
      • product_backlogのgrooming
        • 概要levelのproduct_backlogをもとに,より詳細なproduct_backlog_itemを作ったり,見積もったり,優先順位をつけたりする作業
        • timing
          • product_planningを終えてから,最初のrelease_planningに入る前
          • 最初のrelease_planningの一環として
          • 各sprint中で,必要に応じて
      • envisioningで定義された明確に定義されたrelease可能な最小限のfeature(MRF)を,常に見直す
        • client視点で,実現最小限の製品になっていることを確かめる
      • sprint mapを作ることも多い
        • 各product_backlog_itemがどのsprintで作られるか示す
        • 直近の範囲の可視化
        • → team内の依存関係やresource配分を管理しやすくなる.複数のteamでの共同作業の調整にも役立つ
      • release_planningのoutputをひとまとめにしてrelease planと呼ぶ
        • どの時点までに判断できる妥当なlevelの正確さでの計画を表す
          • 開発作業がどれくらい残っているか,いつごろ終わるか,どのfeatureができあがるか,costがどの程度かかわるかなどを含む
        • そのreleaseで求められるMRFを明確化
        • releaseのための各sprintで対象となるproduct_backlog_itemをどのように扱うのか示すことも多い
  • release制約
    • release_planningの目的: 次のreleaseで最も重要なものが何なのか,そしてそれをどの程度の品質で用意するのかを定める
    • scope, 期日, 予算といった制約は重要な変動要因であり,どうやって目標を達成するかに大きく影響する
    • product_planningにもとづいて,いくつかの制約が生じる
    • 各制約の固定/可変の組み合わせ
      • すべて固定
        • 現実的でない
      • scopeと期日を固定
        • 多くの問題があり,厳しすぎる
        • 固定したものはいずれもかなり予測しづらい
          • いずれかは犠牲になる
        • resourceを投入すればするほど多くの作業をこなせ,作業の所要時間も短縮できるという想定だが,現実的でない
        • 実現できないか,持続可能なpaceに反するか
        • Scrumのiterative and incrementalなapproachを使うことで,何か問題が発生しても早めに気づけるようになる
      • scopeを固定
        • 実際問題として,scopeのほうが期日より重要な場合
        • 全体的なscopeがあまりにも大きすぎる場合
        • より小さ目なreleaseに分割して,それぞれを期日で固定した方がよい
      • 期日を固定
        • Scrumの原則に最もあてはまる
          • timeboxingを重視するScrumにぴったり
        • 優先度の高いfeatureから作るという原則に従うことで痛みを軽減できる
        • 優先度の高いfeatureが本当に(合意済みの完成の定義にもとづいて)完成している場合だけ
        • MRFを小さめに定義できるとき
      • 品質を可変に
        • 制約が厳しすぎる場合
        • 期待に添わないsolution, 技術的負債の発生
      • 制約の見直し
        • 現時点でわかっていることから,制約のbalanceを見直すべきかどうか見極めることが,release_planningにおいて重要
        • 継続的に判断する
  • product_backlogのgrooming
    • 概要levelのproduct_backlog_itemを,user_story 記述workshopなどで,より詳細なlevelに踏み込んだproduct_backlog_itemにする
    • → teamで見積もって,どの程度costがかかるかを判断できるようになる
    • → releaseのgoalと制約に基づいて,各storyの優先順位を判断
      • MRFがrelease_planningの参加者間で常に合意の取れた状態である必要
  • release可能な最小限のfeature(MRF,Minimum Releasable Feature)の見直し
    • MRF: clientが期待する価値や品質をもたらすために,今回releaseに必ず含める必要があるfeature
    • release_planningの中でも重要なのは,真のMRFが何なのか再評価して見直すこと
    • 責任: product_owner
    • 各featureのsizeを知る必要
      • size: product_backlog groomingで判断
      • あらゆる判断は経済面の常識的な範囲内で行うため,各featureのcostを知っておけば,MRFの実現可能性をchackできる
        • 不可能ならpivotを考える
  • sprint_mapping
    • 直近のsprintについて,product_backlog_itemを事前にmappingしてみるのが有用
      • 複数のteamで作業を進めている環境で,協調が上手くいくようになる
        • 移動する先読み範囲: 直近のsprintと少なくともその後数sprintで必要なproduct_backlog_itemを検討する
        • team間の依存関係が扱いやすくなる
    • ある程度詳細なlevelまで落とし込み,見積もりが終わって,優先順位のついたproduct_backlogが必要
      • teamのvelocityを使って,product_backlog_itemをsprint単位に適切に割り当てられる
    • 一般的なschedule表にsprint_mapを並べることもある
    • 単一のScrum_teamのdevelopmentでは,mappingは最初のrelease_planningで行う
    • そのsprintで各teamがどのfeatureを担当するかを最終的に決断するのは,最終責任時点,sprint_planningのとき
    • product_backlog_itemとsprintのmappingをほとんど/全くしないこともある
  • 固定期日のrelease_planning
    • release_planningの手順
      • このreleaseでsprintを何回実行するか決める
      • product_backlogを適切な詳細度までgroomingする(backlog itemを細かくしたり,sizeを見積もったり,優先順位を決めたりする)
        • MRFを構成するfeatureは,与えられた時間の60~70%で完成できるようにしたい
      • teamのvelocityの範囲を計測する
      • 最も遅い場合のvelocityとsprintの数を掛ける.product_backlogの先頭からその結果分だけのitemを数え,そこに線を引く
      • 最も早い場合のvelocityとsprintの数を掛ける.product_backlogの先頭からその結果分だけのitemを数え,そこに2番目の線を引く
        • release日までにどのfeatureができあがるかという問いの答えがある程度分かる
        • release_planどおりに進んでいるか判断するためには,必須featureを表す線をproduct_backlogの上に重ねてみるだけでよい
    • sprintが終わるごとにrelease_planを見直す
  • 固定scopeのrelease_planning
    • 実際には期日よりもscopeの方がずっと重要という場合
    • 本当の意味でのMRFを厳選し,徐々に増やしていくようにする
    • → 固定scopeのreleaseもいくつかの固定期日のreleaseに分割できる
    • どうしても期日が最大の制約の場合の流れ
      • 少なくとも今回releaseしようとしているproduct_backlog_itemを含むよう,product_backlogをgrooming(新たなitemを作ったり,sizeを見積もったり,優先順位を決めたりする)
      • このreleaseでdeliveryするproduct_backlog_itemの合計サイズを決定する
      • team velocityの範囲を計測する
      • product_backlog_itemの合計サイズを最も早い場合のvelocityで割り,端数を切り上げる
      • product_backlog_itemの合計サイズを最も遅い場合のvelocityで割り,端数を切り上げる
  • costの算出
    • 手順
      • team_memberを決める
      • sprintの長さを決める
      • team 構成とsprintの長さに基づいて,sprintあたりの人件費を算出する
      • 固定期日のreleaseの場合は,sprintあたりのcostとsprint数を掛ける
      • 固定scopeのreleaseの場合は,sprintあたりのcostと最大sprint数,最小sprint数をそれぞれ掛ける
    • story_pointあたりのcostを把握しておけば,story_pointさえ求められればcostが分かるという別の方法がとれる
  • communication
    • 固定scopeのreleaseにおける進捗の把握
      • 完了させない作業のscopeが分かっている
      • その作業の完了に向けて,今どの程度の進捗なのかを把握することが目標
      • burn_down_chart: 現在のrelease goalに達するまでの残作業の累計を,sprint単位で示したもの
        • y: 残story_pointの見積もり, x: release内のsprint
      • burn_up_chart: releaseにおける作業の総量をgoalとして示し,sprint単位でそのgoalに近づいていく様子を示した図
        • 軸はburn_down_chartと同じ
        • 好まれる理由: release内でのscopeの変更を表しやすいから
    • 固定期日のreleaseにおける進捗の把握
      • releaseにおけるsprintの回数が分かっている
      • sprintごとの進捗を見ながら,最終的にどの程度のfeatureを完了させられそうなのか(deliveryできるscopeの範囲)を把握する
      • product_backlogの並び順を反転して,burn_up_chartを作成する
        • 目標とするfeatureの範囲に到達するまでの進捗の把握
          • 必須featureの完成までの進捗も確認できる
  • まとめ
    • release_planningについて
      • いつ,だれが,どんなことをするのか,最終的にどんなrelease_planができあがるのか
      • 固定期日/scopeそれぞれの場合でのrelease_planningの方法と,進捗を把握する方法について

Part 4 sprint

Ch19 sprint_planning

  • releaseは1つ以上のsprintで構成
    • 各sprintでは,user/clientに価値を提供する
  • sprintはsprint_planningから始まる
    • Scrum_teamが集まって,sprint_goalに合意し,sprintで何をdeliveryできるかを決定
  • Scrum frameworkにおけるsprint_planningの位置づけと実施方法について
  • 概要
    • sprintで構築する最も重要なproduct_backlog_itemを決定するために実施する
    • sprint_goalについて合意する
    • sprint_goalに合致しており,sprint終了までに現実的にdeliveryできるproduct_backlog_itemを決定する
    • 決定したitemをきちんとdeliveryできる自信を持つために,product_backlog_itemを完成させるための計画が必要
      • 選択したproduct_backlog_itemと計画を合わせたものが,sprint_backlogになる
    • timing
      • 継続的なjust_in_time activity
      • sprint開始時に実施する
      • 2週間から1か月のsprintの場合,sprint_planningに4~8時間かける
    • 参加者
      • Scrum_team全員
      • product_owner: 最初のsprint_goalを共有して,product_backlogの優先順位を示し,product_backlog_itemに対するteamの疑問に答える
      • development_team: sprintで何をdeliveryできるか決定し,現実的なcommitment
      • Scrum_master: Scrum_teamのcoachとしてplanning activityを観察し,内省を促す質問をして,確実に良い成果が得られるよう支援する
        • 何を作るか代わりに決められはしない
        • teamのcommitmentに問題を提起して,現実的で適切なcommitmentができるようにする
    • process
      • input
        • product_backlog
          • 最も重要
          • 準備完了の定義に合うように,sprint_planningよりも前にgrooming
            • 準備完了の定義: 受け入れ条件が定義済みで,適切なsizeで,見積もりが終わっていて,優先順位がつけられている
        • team velocity
          • 現実的な判断のため(以下2つも同じ)
        • 制約
        • team capacity
        • initial sprint_goal
          • development_teamのcommitmentが現実的なものになるため
          • teamは優先順位のbalanceが取れる
      • sprint_goalを達成するための計画を作る
        • sprint_backlog
          • product_backlog_itemを見積もり可能なtaskに分解
            • 1つのtaskは8時間以内
      • sprint_planningが終わると,development_teamのcommitmentが最終的なsprint_goal, sprint_backlogとなって伝えられる
  • sprint_planningの手法
    • 二部構成のsprint_planning
      • what part
        • development_team capacityを決定し,sprint終了時にdeliveryできるproduct_backlog_itemを予想する
      • how part
        • product_backlog_itemをtaskに分解して,task完了に必要な工数を見積もり,計画を立てる
        • 見積もったtaskの時間とcapacityを比較して,最初のcommitmentが現実的かどうか確認
        • 予想がcapacityの範囲や制約に収まれば,commitmentを最終決定して,sprint_planningを終了する
    • 一部構成のsprint_planning
      • itemの選択とそのための自信の獲得を交互に行う
      • まず,development_teamがcapacityを決定する
      • 次に, product_backlog_itemを選択して,それがsprintに収まるという自信を持つ
      • これをteamのcapacityの上限に達するまで続ける
      • 最後にcommitmentを最終決定して,sprint_planningを終了する
  • capacityの決定
    • sprint_planningの最初の重要なactivity
    • what's capacity
      • 影響を与える要因
        • sprint以外のactivityに必要な時間
        • sprint以外のcommitment
        • 個人的な休暇
        • 必要なbuffer
          • 経験的に決定
      • capacity
        • 単位
          • product_backlog_itemに使う単位(story_point or 理想日)
            • team velocity
              • teamのこれまでの平均velocityや前回のsprintのvelocityを参考にする
              • そして今回のsprintとの違いを考慮する
              • → 予測したvelocity
          • or sprint_backlog_taskに使う単位(作業時間)
            • まず,team_memberが次のsprintで何日作業できるかを表明する
            • 次に,sprint以外のactivityにかかる日数を決定
            • team_memberの1日の作業時間を決定
  • product_backlog_itemの選択
    • sprint_goalがあれば,それに合わせてproduct_backlog_itemを選択する
    • なければ,product_backlogの優先順位の高いほうから順番にitemを選択する
    • skillの問題などでitemにcommitできないときは,優先順位がその次に高くて実現できそうなproduct_backlog_itemを選択する
    • 完成できそうにない場合は,clientにとって価値のある小さなitemに分割するか,完成できそうな別のitemに着手する
      • 準備完了の定義を用意しておくことで,定義・resourceが不十分だったり,依存関係が未解決のproduct_backlog_itemを選択して,sprintで完成できなくなることを回避できる
    • 「完成できそうなものだけを開始する」
      • WIPの制限や未完成作業のムダの原則に基づく
        • 出荷判断可能なproduct incrementがsprint終了時に必要
  • 自信の獲得
    • velocityを予測
      • commitmentが現実的かどうか確認
      • ただし,実際はtask levelにするまで分からない
    • → さらに,product_backlog_itemをtaskに分解することで自信を獲得する
      • taskは見積もり可能で,team capacityを考慮して決定
        • 一種の設計で,itemを完成させるためのjust_in_timeの計画
      • 分解した結果がsprint_backlog
      • それぞれのskillを把握しておかないと,正しいcommitmentができない
        • ただし,個人へのtask assignは×
  • sprint_goalの洗練
    • sprint_goal: sprintでのbusinessの目的と価値をまとめたもの
  • commitmentの最終決定
    • sprint_planningが終了するまでに,development_teamはsprintでdeliveryするbusiness valueにcommit
    • sprint_goalと選択したproduct_backlog_itemは,commitmentを具現化したもの
    • 予想/commitment
      • ニュアンスの違いは,development_teamが何をdeliveryするかのscopeと,Scrum_teamがsprintの実施中に手に入れた新しい情報への対応に影響する程度
  • まとめ
    • sprint_planningをいつ実施するか,誰が参加するか
    • 2つの手法
      • teamがproduct_backlog_itemを選択して,それらをすべてdeliveryできるという自信を獲得
      • product_backlog_itemの選択と自信の獲得を交互に行い,少しずつcommitmentに追加する
    • development_team capacityを決定するための2手法

Ch20 sprintの実施

  • Scrum_teamがsprint_goalを達成するための作業
  • sprintの実施において,Scrum_teamが計画,管理,実行,伝達するためのprinciple, technique
  • 概要
    • sprintの実施は,それ自体が1つのmini projectのようなもの
      • 出荷判断可能なproduct incrementをdeliveryするために必要な作業をすべて行う
    • timing
      • sprint_planningが終わった後に始めて,終了したらsprint review
      • 8割程度はsprintの実施が占める
    • 参加者
      • development_teamのmemberが自己組織化して,sprint_planningで設定したgoalを達成する最善の方法を決定
      • Scrum_masterは,あらゆる支援
      • product_ownerは,質問に答えたり,feedback, sprint_goalを調整,product_backlog_itemが満たすべき受け入れ条件を検証
    • process
      • input
        • sprint_planningで作ったsprint_goalとsprint_backlog
      • output
        • 出荷判断可能なproduct_increment
          • 開発が終わったproduct_backlog_itemの集まり
            • Scrum_teamの完成の定義に従う
      • 実施
        • testされた動作する機能に必要な計画,管理,実行,伝達
  • sprint_planning
    • 万全な計画にはしない
    • taskに依存関係があるときは,事前の計画が有用なこともある
    • sprintの実施の原則: 事前に完璧な作業計画を立てるのではなく,状況に応じてtask levelの計画を立てる
      • teamで継続的にtask planningをすることで,sprintを取り巻く環境の変化に適応できる
  • flow management
    • teamの責任
    • どれだけの作業を並行でやるべきか,特定のitemにいつ着手すればよいか,task levelの作業をどのように構成するか,何の作業をすべきか,誰が作業すべきか,を決める
    • 並列作業とswarming(群がる)
      • 単純なmulti taskでもoverheadは極めて高い
      • 並列作業が少なすぎてもムダ
      • swarming
        • 適切なbalanceのために,team_memberのT型skillやcapacityを活用できるだけのitem数に絞って作業する
          • deliveryするvalueを最大化しながらも,各itemの作業時間を短縮
        • 新しいitemに着手する前にcapacityあるteam_memberが集まって,すでに誰かが着手したitemを完成させる
        • taskではなくgoalに集中し,より多くより早く作業が終わる
        • 同時に作業するitemの数を極力減らすべき
          • 複数のitemが適切な場合もあるので,必ずしも1つではない
      • mini waterfallのようになるのは×
        • 同時にすべてのproduct_backlog_itemに着手することになるため
        • → riskが非常に高い
    • どの作業から着手すべきか
      • itemの優先順位をproduct_ownerが決定
        • 技術的な依存関係やskill capacityの制約がitemの順番に影響を及ぼすため,常には上手くいかない
        • → development_teamは,itemを適時適切な順番で選択する能力が必要
    • どのようにtaskを計画すべきか
      • 作業に論理的な順番はない
      • test first development
      • 適時team_memberがtaskや担当をうまく構成する
        • → 作業の手待ちを最小化し,team_memberがほかのmemberに手渡す作業の量や回数を減らせる
        • → すばやいfeedback, 課題の発見と解決が迅速に実施できる
    • どの作業を完了させるべきか
      • team_memberが決定
        • 経済的に合理的な方法でinnovative solutionを作るための権限を与える必要
      • product_owner, managerは,どのtaskを完了させるべきかに影響を与えるinputを持っている
        • product_ownerが機能のscopeと受け入れ条件を確定する.いずれもtask levelの作業の境界線となる
        • 完成の定義に必要なbusiness 要件を提供する
        • product_ownerは,businessに重大な結果をもたらす技術的判断が経済的合理性をもって行われるように考慮しながら,teamと一緒に作業する
      • 決定の中には,完成の定義の技術的な側面に組み込まれているものもある
      • そのほかの決定は,機能に特化したもの
        • development_teamはproduct_ownerと一緒にtradeoffを行い,経済的に合理的な決定をすることが望まれる
    • 誰が作業をするのか
      • 作業をすばやく正しくできる人が最適
      • 様々な要因が影響する
      • team_memberの共同責任
      • T型skillで,より効率的なteamになる
  • daily_Scrum
    • team activityを高速にして,solutionまでの流れを柔軟にする,毎日の検査と適応のactivity
    • 24時間ごとに15分のtimebox
    • 自己組織化teamが仕事をより良くするために,検査とsyncを行う適応型planning activity
    • goal: sprint_goalの達成に集中している人たちが集まって,何が起きているかの全体像を共有し,どれだけの作業をしているか,どのitemに着手したか,team_memberの最適な作業配分についてみんなで理解すること
    • 待ち時間の回避にもなる
    • flowの管理に欠かせない存在
  • taskの実行(technical_practice)
    • 短期間のtimeboxというiterationで作業する → 出荷判断可能なproduct incrementを届けることを期待されている
      • 技術的負債を制御して仕事をやりきるというpressureがteamにかかる
      • → 適切な技術的skillを持っていなければ,長期にわたって継続的にbusiness valueを届けるために必要なagilityのlevelを達成できない可能性がある
    • Scrumを使う場合は,software developmentのtechnical_practice_skillが必要になる
      • TDD, refactoring, simple design, pair programming, CI, codeの共同所有, coding standard, metaphor
        • called as XP
    • 長期的なScrumの利点のためには,task levelの作業に,強力なtechnical_practiceが必要
  • communication
    • information radiator(radiate: 放射 ← 光を放つ)
      • task_board, burn_up_chart, burn_down_chartの組み合わせ
    • task_board
      • sprintの進捗が一目で伝わる簡単だが強力な手法
      • sprint_backlogの変化の状態を伝える (→ 図20.6)
      • sprint_backlog_itemが複数のtaskで表現
        • すべてのtaskはTO DOから
        • → 進行中
        • → 完了
      • カンバンではより詳細なboard
    • sprint burn_down_chart
      • product_backlog_itemのtaskは,いつでもsprint_backlogに追加できる
      • y: 見積り残作業時間, x: sprint日数
      • 進捗管理に使える
      • 傾向線を書くことで,sprintのflowを管理するための知識となる重要なdataを得られる
      • 常に残りの見積もり時間を使用する.実際にかかった作業時間は不要.
    • sprint burn_up_chart
      • sprintの進捗を可視化
        • 完了した作業の量を表す
      • y: story_point, or 作業時間, x: sprint日数
        • ほとんどはstory_point
          • ↑ business valueのための成果に注目するため
          • 作業の流れが滞っていないか,teamがどのようにproduct_backlog_itemを完成させているかの感覚がつかめる
  • まとめ
    • sprintの実施について
      • sprintの大部分を占めるもの
      • who, what, whenの計画に従うものではない
      • teamのskillを活用して,完了した作業やsprintの予期せぬ環境の変化からfeedbackを受け取る
      • flow management principleに従う
        • 並行していくつの作業をするか,何の作業に着手するか,作業をどのように構成するか,誰が作業をするか,作業にどの程度の時間をかけるか,を決める
      • daily_Scrum meetingはflow managementのimportant activity
      • technical_practice's importance for high level agility
      • sprintの進捗を視覚的に伝える
        • task_board, sprint burn_down_chart, sprint burn_up_chart

Ch21 sprint_review

  • productに集中したもの
  • 目的,参加者,事前準備,問題について
  • 概要
    • 作業結果(出荷判断可能なproduct_increment)の検査と適応をする.
    • sprint終了間際に実施する
    • product developmentのinputにかかわった人に対して,これまでに構築したものについて検査と適応をする機会を提供する
      • 質問,観察,提案したり,現状を考慮して今後の方針について議論する
    • 正しいproductを開発中だと組織が確信できるようになる
      • → 最も重要な学習loopの1つ
        • sprintの期間は短いので高速
        • → 頻繁に軌道修正〇
  • 参加者
    • sprint_reviewは,Scrum_teamに対して,sprintの実施に毎日参加できないような人たちからのfeedbackを得る重要な機会を提供
    • sprintで作成された成果について議論する最初の機会
      • すべての利害関係者が参加すべき
        • Scrum_team
        • 内部stakeholder
          • business area owner(developing systemの発注者), exective management, resource担当managerなど
          • → teamが経済的に合理性のある成果に向かっているか確認
          • 内部userがいる場合は内部userからのfeedbackも有益
        • そのほかの内部stakeholder
          • 営業,marketingから,productが市場で成功するかどうかの有益なfeedbackを得る
          • support, 法務部は,teamの進捗の把握や,timelyなinputを提供したり,自分たちの仕事をいつ開始すればよいか判断するために,参加することもある
          • ほかのdevelopment_teamの代表者も〇
        • 外部stakeholder
          • client, user
            • direct feedback
          • 内部の議論で済むなら,必要はないかもしれない
          • 常識,熱意,人格を考慮して招待する対象を検討
  • 事前準備
    • 誰を招待するのか決める
      • 適切な人たちを集める
    • schedule調整
      • Scrum_team以外の参加者が多いので,調整が難しい
      • important stakeholderが希望するscheduleを聞いてから,そのほかのactivityをその時間の前後に設定する
        • sprintの期間は固定されているので,ほぼすべてのsprint_reviewのscheduleが決まる
      • 長さ
        • sprintの期間,teamの規模,reviewに参加するteam数など複数の要因で決まる
        • 4時間のtimeboxを超えない
        • sprint 1週間につき1時間
    • sprintの成果が完成したことを確認
      • 利用可能になったproduct_backlog_itemを,product_ownerがjust_in_timeでreview
    • demoを準備
      • goal: productの検査と適応のために透明性を提供すること
      • 儀式を少なく,価値を高く
      • sprint 1週間につき30分から1時間をsprint_reviewの準備に使う
    • 誰が何をするかを決める
      • facilitator, demoを誰がするか,Scrum_teamが決定
  • approach
    • input
      • sprint_backlog, sprint_goal, teamが作成した出荷判断可能なproduct_increment
    • output
      • groomingしたproduct_backlogと更新したrelease_plan
    • sprint_goalの何を達成して何を達成していないかの概要を示し,出荷判断可能なproduct_incrementのdemoをして,productの現状について議論し,今後のproductの方向性を適応させる
    • 概要
      • sprint_goal, sprint_goalに関連したproduct_backlog_item, sprintで実際に開発したproduct_incrementの概要をScrum_teamのmemberが伝えるところから始まる(product_ownerが担当することが多い)
      • sprintの成果とsprint_goalを比較したときの結果が分かる
        • 不一致なら,説明
          • 責任追及,非難はしない
        • 何が達成できたかをもとに,今後取るべき行動を決定する
    • demo
      • sprint_reviewの目的はdemoではない
        • 最も重要な側面は,参加者たちの徹底した対話や協力
        • → 生産的な適応を可能にし,有効活用する
        • demoは,対話をより具体的にするための効率の良い方法
      • 準備完了の定義に,Scrum_teamがdemo方法を理解することも含まれる
      • product_ownerの要求を満たしていることをdemoするテストが必要
        • sprint_reviewでは,テストを使ってdemoできる
    • 議論
      • product_incrementのdemoは会話の中心になる
      • productや今後の方向性に関する意見,コメント,妥当な議論が,参加者に強く求められる
      • sprint_reviewは問題解決の場ではない
      • Scrum memberが,client/userを喜ばせるためのfeedbackを得ることで,productのbusiness, marketingの認識を深める
    • 適応
      • question
        • stakeholderは見たものを気に入っているか
        • 変更点を見たいと思っているか
        • 今でも市場やclientに受け入れられるのか
        • 重要な機能が不足していないか
        • 不必要なところに機能を作りこみすぎたり,costをかけすぎていないか
      • → product_backlogやrelease_planの適応のinputになる
      • grooming @sprint_review
        • より大きなscopeのrelease_planにも影響する
          • 変動要因に影響
            • scopeの変更など
      • sprint終了ごとに,適応の方法,変化の反応方法,それらを実施できる時期を見つけるための機会を提供する
  • sprint_reviewのproblem
    • signoff
      • 正式な認可やsignoffのeventではない
        • 事前にproduct_ownerが承認済み
        • product_ownerがproduct leadershipの権限を持つため,承認は決定事項
        • 要求があれば新しいproduct_backlog_itemを作成し,機能変更の予定を立てるのが〇
          • なぜ要求を出した人がstakeholderから外れていたか調査し,今後は調整する
    • 参加者の不在
      • 数週間で価値のあるものを作り出せると思われていないため
      • 解決方法: business valueのある出荷判断可能なproduct_incrementをsprintごとに開発する
        • → 頻度の高いreviewに参加する価値を理解してもらえる
    • 大規模project
      • sprint_reviewの共同実施
        • merit
          • stakeholderはsprint_reviewに1回だけ参加すればよい
          • 成果が統合できれば,個別のincrementではなく統合した結果をreviewすればよい
            • すべてのteamが完成の定義に統合test要
        • demerit
          • 時間がかかる
          • 大きな部屋が必要
  • まとめ
    • sprint_reviewの目的であるScrum developmentのfeedbackについて
    • 参加者のgoalは,現状のproductの検査と適応
    • 非公式なactivityだが,最小限の事前準備をする
    • Scrum_teamは,reviewの概要とsprintで達成したことを説明する
    • product_incrementのdemoをする
    • 質問,意見,提案が歓迎される
    • grooming, release_planの更新を行う

Ch22 sprint_retrospective

  • productを構築するのに使ったprocessを,Scrum_teamが調査する
  • 目的,参加者の概要,事前準備,主要なactivityを見る
    • 最も重要なのは,参加者が発見した改善をsprint_retrospectiveの後に継続的に行うこと
  • 概要
    • 考える機会を与えるもの
      • teamは何が起きているのかを調査したり,自分たちの仕事のやり方を分析したり,改善の方法を見つけたり,改善の計画を立てたりする
      • teamのproductの作り方に影響を与えるものであれば,なんでも自由に調査・議論できる
        • e.g. process, practice, communication, 環境, 作成物, tool
    • 最も重要で,最も使用されているpractice
      • teamが自分たちの環境に合わせてScrumをcustomizeできる機会を提供するため
      • しかし「実際の」作業ではないので過少評価されている
    • Scrumが提供する継続的改善に不可欠
      • sprintごとにretrospectiveを行い,insightやdataを見失うことなく活用できる
      • 早期にincrementalな学習ができる
        • → projectの成果に大きな影響
    • theme
      • sprintでうまくいったので,今後も続けたいこと
      • sprintでうまくいかなかったので,今後は中止したいこと
      • これからやった方がよいこと,改善した方がよいこと
    • → 行動可能な変更点を決定,incrementalに改善したprocessで次のsprintに取り組む
  • 参加者
    • Scrum_team全員
      • team memberの多様な視点で,さまざまな観点からprocessの改善点を見つけられる
      • Scrum_master: processに欠かせないRole,processの権威
        • teamが合意したprocessで守られていない点を指摘
        • teamにとって重要な知識やideaの源泉となる
      • product_ownerとteamの信頼関係をScrum_masterがcoachingして築くまでは,product_ownerは参加できない
      • 信頼と安全が確保できれば,product_ownerは欠かせない
        • 高速で柔軟性の高いbusiness valueのflowの達成のため
        • 要求のflowをteamに伝えるchannelやrouteなどのRoleを担う
    • stakeholder, managerなどは,招待されたときだけ
      • 参加は安全性の問題がないときだけ
  • 事前準備
    • sprintの期間が短かったり,実践的で簡潔なretrospectiveのformatを使っていれば,事前準備には必ずしも時間はかけなくていい
    • focusを定義
      • default: Scrum_teamが使用したprocessの関連する側面をすべてreviewする
      • 現状のteamの重要性や改善点に合わせて,別のfocusの選択も〇
        • e.g.
          • TDD skill up方法にfocus
          • 要求の誤解の頻発の理由にfocus
      • 開始前にfocusが分かることの効果
        • Scrum_team以外の人たちを招待するかどうか決定できる
        • 適切なexerciseを選択できる
        • retrospectiveを円滑にするために必要なdataの収集や準備に時間をかけられる
      • 具体的に定義 → retrospectiveから計測可能な価値を抽出〇
        • → 持続可能なhigh performance Scrum_teamになる
    • exerciseを選択する
      • 協力して考え,探索し,意思決定するためのもの
      • 通常のexercise
        • event timelineの作成と発掘
        • insightのbrainstorming
        • insightのgroupingと投票
      • focusや参加者に合わせて変更可能
      • 新鮮さのために新しいexerciseを試すのも〇
      • 事前準備で決める必要はない, just_in_timeで決定〇
        • data, 備品が必要なexerciseは,事前準備で決めておく
        • 準備しながら,柔軟性は確保
    • 客観的dataを収集する
      • data収集に必要な作業は,retrospectiveの開始前に済ませておく
      • 客観的data: 確実なdata(not 意見)
        • e.g. どのようなeventがいつ起きたか,着手したが完成しなかったproduct_backlog_itemの個数,完了した作業のflowを示したsprint burn_up_chartなど
      • この段階では,dataの構造化や分析は行わない
    • retrospectiveを構成する
      • sprint_reviewと場所や時間を合わせるかどうか,参加者やexerciseの都合などから考えておく
      • 正確な時間は,team人数,年数,memberがremoteにいるかどうかなどの要因の影響を受ける
        • sprintの期間に合わせて時間を決定する
          • 2週間のsprintなら1.5時間をretrospectiveに割り当てる
      • 成功に最適な場所
        • 情報にaccessしやすい仕事場
        • 安全な環境のために仕事場以外
      • facilitatorは,Scrum_masterがやることが多いが,誰でもよい
        • 中立性のため外部から招くこともある
  • approach
    • input
      • 合意したfocusなど,retrospectiveで使用するとteamで決めたものならどんなexerciseや道具でもいい
      • 事前に収集した客観的data
      • 参加者は,sprintについての主観的なdataを持参する
      • 前回retrospectiveで作成したinsight backlog
    • output
      • 次のsprintで行う具体的な改善action
      • 今回retrospectiveで作成したinsight backlog
      • 仲間意識の向上
    • theme
      • sprintでうまくいったので,今後も続けたいこと
      • sprintでうまくいかなかったので,今後は中止したいこと
      • これからやった方がよいこと,改善した方がよいこと
    • 有効なapproach
      • retrospectiveの雰囲気づくり
        • team/個人を徹底検証するのは不愉快な経験なので,心地よくなってもらうための雰囲気づくりが必要
        • 報復を恐れずに自分の意見を言えるような,安全性を感じてもらう
          • rule設定/取り決め
            • 自分の意見や内輪の恥をさらしても安全であることを明確にする
            • 間違いを探しても安全だとわかるように,個人ではなく組織のsystemやprocessにfocusしていることを明確にするruleを設定しておく
          • 問題が人の問題であることもあるが,retrospectiveは問題解決の場ではない
            • 責任の所在を明らかにしたり,個人の振る舞いを非難したりする場ではなく,Scrum_teamのprocessを改善する場
            • 非難のない環境を作るためのruleであることを明確にしておく
        • 積極的な参加の前例を作る
          • 参加者に口を開いてもらう
            • 今の感情やenergy levelを一言で表現してもらうteamもある
            • 内容より,何かを言うことで,話そうという雰囲気を作る
      • 参加者によるcontextの共有
        • → 客観的に大局的にsprintを見ることができるようになる
        • 多様性のある個人の視点をteamの視点に統一
          • sprintのevent, 達成, 欠点に対する大局的な考えに基づくようにする
            • × 個人的な経験
              • → ただの意見の言い合いになる
        • contextを共有して行動可能な成果に注力
        • 雰囲気づくりができたら,客観的data(commited product_backlog_item, 完成したproduct_backlog_item, 不具合数など, retrospectiveのfocusに合ったもの)を共有する
        • 主観的dataも共有・議論する
          • → 誤解の回避のため
          • 誤解があると,他人のcommentや提案を理解できない
        • event_timeline
          • sprintのeventの流れをvisualに表現した作成物
          • 簡単で強力
          • event: buildが動かなくなった,本番環境の修正で手間取った,Salinaが休暇から戻ったなど
          • timelineを壁やwhiteboardに描き,eventを表すカードをtimelineに貼り付ける
            • colorfulなcardを使う
          • sprintのactivityの流れが時間軸で可視化されて,contextがよくわかる
            • → 見逃していたり忘れていたeventをすばやく特定できる
        • 感情seismogram(seiein: 揺れる)
          • event_timelineの補完
            • 上下に並べる
          • sprintにおける参加者の感情の起伏を視覚的に表現
          • 客観的dataだけでなく,主観的dataまで含めてcontextを共有できる
      • 改善につながるinsightの特定
        • dataを深く調査,理解,解釈して,process改善のためのinsightを獲得
        • system levelの(より大きな)focusが必要
          • → 表面的なproblemだけでなく,根本的な原因を特定できる
        • まずは共有したdataを発掘
          • insightを明らかにするための質問
            • 何がうまくいったか
            • 何がうまくいかなかったか
            • やり方を変えるところはないか
          • → brainstorming
        • insight backlog
          • 優先順位をつけたが,まだ実行されていないinsight
          • 検討すべきものがあるか調査
        • insightを意味のあるgroupに分けて,類似や重複しているカードを示す親和図法のようなexerciseを行うことが多い
          • silent groupingは,時間の効率も効果も高い
          • 複数のcategory area(継続,中止,挑戦)に分けることもある
        • → 参加者同士の深い議論につながり,根本原因,重要なpattern,関連をよく理解できるようになる
      • 次のsprintで実施する具体的な改善actionの決定
        • insightからvalueを抽出するために,実際に行動可能なものにする
        • 前回から行われた改善actionのreviewもする
          • 何故できなかったのか把握
          • 改善を続けるか,優先順位を新しいinsightと入れ替えるかなどする
        • insightの選択
          • 短期間で実行できる以上のinsightが手に入る
          • 参加者がどれを重要と思っているか,どこを改善していきたいと思っているかで決めることが多い
          • ドット投票
          • 参加者がinsightに専念できるcapacityや期間によって,いくつ選択するか決定する
            • 期間: 次のsprint期間
            • capacity: 前回のretrospectiveで見つけたactionの計画から決定できる
              • product_ownerからのinputをもとに,Scrum_teamが時間を割り当てる
              • capacityが分かれば,どのinsightに取り組むべきか分かる
        • actionの決定
          • 優先順位のついたinsightが手に入り,それらに取り組むcapacityが判明した状態
          • 具体的なactionの決定
          • ほとんどのactionは,次のsprintで1~2人のScrum_team memberが担当できる程度の具体的なtaskになる
          • development_team_memberのtask levelの作業が必要
            • 誰がどれだけの時間をかけるかteamで決定する
            • → insightが実行可能かどうか決まる
          • すぐにinsightには取り組めない
            • 次のsprintではinsightの調査が必要
            • まず問題をよく理解するためのactionを作る
        • insight backlog
          • retrospectiveで発見したが,すぐには改善できない課題をまとめる
          • backlogのinsightと新しいinsightを比較して,次のsprintで集中するところを決める
          • 定期的にgrooming
          • 選択肢しなかったinsightを破棄することもある
            • 必要ならまた発見できるという考え
      • retrospectiveの終了
        • 学んだことをふまえて,決定したteamのactionを再確認する
          • commited actionと担当者を読み上げるだけの簡単なものでいい
        • 感謝を述べる絶好の機会
        • retrospectiveを改善できる提案を求める
  • その後のfollow
    • 参加者が選択したactionをfollow_up
      • 何度も言い続けるしかないものもあるが,それ以外はsprint_planningで指摘する
    • actionに関連するtaskをsprint_backlogに追加して,新しい機能よりも優先順位を高くする
      • 分離×.統合〇.
      • team_memberの時間を必要としないactionは,Scrum_masterのimpediment listに加える
      • ほかのteamや組織のactionは,担当者の適切なbacklogに入れておく
        • 確実に実行されるように,Scrum_masterは外部の人たちをfollow
  • sprint_retrospectiveのproblem
    • retrospectiveを実施していないか,参加者が少ない
    • All fluff(ふわふわしたもの, つまらないこと), no stuff(本当に役立つこと)
      • 外部からretrospective facilitatorを招いて支援してもらう
    • 部屋にいる象を無視している
      • 劇的な影響をもたらす重大な問題に誰も触れない
      • Scrum_masterがleadershipのRoleを担い,まずそのimpedimentを除去する
    • facilitatorのskill不足
      • 外部からretrospective facilitatorを招いて支援してもらう
    • 気がめいってenergyが奪われる
      • 雰囲気づくりの時間を作る
    • 責任追及game
      • facilitatorがすぐに悪い振る舞いを消滅させるようにする
    • 不満大会
      • face to faceで対話するようにする.
    • 現場の改善をつぶす
      • retrospectiveは改善活動そのものではない
    • 意識が高すぎる
      • Scrum_masterが熱意を和らげるよう支援する
    • followがない
      • Scrum_masterの支援が必要
  • まとめ
    • sprint_retrospectiveは,teamがScrumをうまく活用できたか振り返る時間,改善案を策定する時間
      • Scrum_team member(必要ならそれ以外の人たちも)の共同作業
      • 事前準備が終わったら,雰囲気づくりをして,dataに基づいたcontextを共有して理解を統一し,改善insightを見つけ,改善actionを決定し,retrospectiveを終了する
      • 終了後は,参加者をfollowして,改善actionを実行していくことがimportant
        • → 次のsprintでteamがより効果的になる
      • 成功を阻害する問題に注意を払い,すばやく対処することもimportant

Ch23 未来へ

  • Scrumを実践するうえでの,普遍的な最終目的はない
  • agilityに向かって,独自の道を定義する必要がある
  • 最終形態などない
    • Scrumの適応やScrumの移行について完成の定義はない
      • 継続的改善の一形態
      • より効率的かつ経済的にbusinessの目的を達成するための手段に過ぎない
      • productによって状態が異なる
  • 独自の道を探し出す
    • 学び,検査し,適応して,進むべき道を探る
      • base: 組織独自の目標・文化,変わりゆく複雑な環境
    • 自分の学習loopを素早く完結させて,その学びに基づいて,検査と適応を行う
  • best practiceを共有せよ
    • practice: Scrumの核心的基礎的な側面
    • approach: Scrumのpracticeの1つの実装
  • Scrumを使って,進むべき道を探し出せ
    • enterprise_transition_community
      • managerと経営者で構成されたgroup
      • 組織変革のための取り組みや,Scrum_teamを妨げている重大なimpedimentの除去がbacklogに入る
      • Scrumを適用するためにScrumを用いる
        • iterative and incrementalによりいっそうAgileになっていくうえで適切なapproach
  • 歩みを止めるな
    • 経験上,teamの最初の2回程度のsprintはうまくいかない
    • 次のsprintで,前のsprintより良くなっていさえすればよい
      • 始めるのを遅らせてはならない
    • Scrumの実施を難しくするimpedimentが必ずある
      • 機能不全やムダが可視化される
      • こうした課題の解決は,Scrumでは組織の中にいる人にゆだねられる
    • 現状維持をしたいという強い力の考え
      • 組織を変革するために確固たる信念をもって辛抱強く立ち向かう必要
      • 変革に対する抵抗は自然なもの
      • 協力し合うことで障害を取り去る
      • → team, product development, 組織が,Scrumの実践の恩恵を十二分に理解できるようになる

『Webフロントエンド ハイパフォーマンス チューニング』学習メモ

Ch1 Web performanceとは何か

  • performance: userの様々な振る舞いにWeb pageが応答する速さ
  • Web page内でのinteractionのperformanceの最適化を目指す

Ch2 browserのrenderingの仕組み

  • 対象とするrendering engine
    • history
    • WebKit系のrendering engineを見る
    • rendering engine: browserの内部で利用するHTMLの描画engine
      • HTML, 画像ファイル, CSS, JavaScriptなどの各種resourceを読み取って,画面上の実際のpixelとして描画
    • JavaScript engine
      • V8など
        • V8はNode.jsでも使われている
    • WebView: browserと異なり,Web pageの表示のみを行うcomponent
      • online contentsをapplication内で表示/application内のcontentsを再installすることなしにdynamic updateのため.
      • WKWebView > UIWebView
  • browserのrenderingの流れ
    • HTML, CSS, JavaScript, HTTPなどの周辺要素が相互に関連し合って進むため,複雑
    • 4つの工程からなるrenderingが始まって,最終的に描画されるまで: Frame
  • resourceの読み込み: Loading
    • browserが, URLからHTMLを読み込んで,そこからさらにrenderingに必要な付属するresourceを読み込んで解釈
    • resourceの取得のためのnetwork protocol
      • (表)
      • 内部的な手続き
          1. URLに含まれるhostnameの解決
          1. HTTPによる取得
          2. 2-1. TCP connectionの確立
          3. 2-2. (@HTTPS) TLS connectionの確立
          4. 2-3. HTTP requestの送信とHTTP responseの受信
      • IPについて
      • TCPについて
      • TLSについて
      • UDPについて
        • QUIC protocolなどで使われている
      • HTTPについて
      • DNSについて
    • 各resourceの読み込み
      • HTMLの読み込み
        • URLからHTTP request → HTTP responseとしてHTMLを取得
        • → 取得したHTMLを解釈し,DOM(Document Object Model) treeを構築
          • DOM: HTMLのDocumentを表現するObject.rendering engineが利用する木構造を持つ内部表現.
          • DOM treeへの変換過程で,画像やCSSなどのDocumentに紐づくresourceの取得や読み込みを行う
          • DOM tree: JavaScriptからアクセス〇 → DOM操作
          • process
          • img: 画像.link: CSS.script: JavaScript
      • CSSの読み込み
        • CSS: HTMLで記述されるDocumentの内容や構造に対して装飾を加える
        • 要素を指定するCSS selectorと,それらに適用するCSS propertyと値の組を宣言する
        • link: 外部CSS fileを宣言.style: HTML file内部に埋め込まれたCSSの読み込み.
        • rendering engineがparse → CSSOM(Object Model) treeに変換
        • CSSOM treeはrendering engineの内部表現だが,JavaScriptからaccess
  • JavaScript 実行 -Scripting
    • JavaScriptの実行: 最初にJavaScriptファイルを読み込んだとき + DOMイベントが発火しevent listenerが起動するとき
    • 字句解析と構文解析
    • compile
      • 抽象構文木 → 実行可能な形式
      • JIT compile型が多い ←→ 仮想マシン用コードへの変換
        • JIT compile型: その処理系が動作しているマシンのCPUが直接解釈できる機械語に変換
          • 実行時のperformance〇
          • multi platform対応difficult
          • compile時のoverhead大
        • JIT(Just In Time) ←→ AOT(Ahead Of Time)
    • 実行
      • JavaScript内では,DOM APIを通じてDOM treeを操作
      • 後続のRendering, Painting phaseやLoading phaseを引き起こす
  • Layout tree構築 -Rendering
    • Calculate Style + Layout
    • Calculate Style
      • すべてのDOM要素に対して,どのようなCSS propertyが当たるのか計算
      • CSSOM tree内をすべて参照して,CSS selectorのCSS ruleのマッチング
      • CSS rule のmatching
        • CSS selectorのmatching
          • ある要素の親要素や同じ階層の要素に条件をつけるCSS selectorがある
            • e.g. body > .container > .button
            • selectorを右から左に解釈してmatching
        • 適用されるCSS propertyの算出
          • DOM要素に適合する複数のCSS rule setを,詳細度でソートしてスタイルを計算する.
          • 詳細度は,CSS selectorにより決定.
            • p.41 表に,selectorと詳細度の対応がある
          • 詳細度が大きいほど優先.同じときは,後に宣言されたものが優先.
          • 要素のstyle属性に記述されたCSS ruleは,どのCSS rule setよりも優先
          • CSS propertyに付加する!importantはstyleよりさらに優先される
          • Specificity Calculatorで確認できる
    • Layout
      • 要素の大きさ,margin, padding, 位置,z軸の位置を計算
  • rendering結果の描画 -Painting
    • Paint
      • 内部の低レベルな2D graphic engine向けの命令の列(Display List)を,Layerごとに生成
      • browserによって,組み込むgraphic engineが異なる
      • bottleneckにはならない
    • Rasterize
      • 生成された命令から,pixel(bitmap)へと描画
      • overhead大きい
      • layerという単位で1枚ずつ描画
        • layer: overwrapして表示するcontentsがあるときに生成
        • 描画済みのlayerを再利用して,再renderingが素早く容易になる
    • Composite(複合,合成) Layers
      • pixelにしたlayerを合成して最終的なrendering結果を生成
      • 3Dの処理などはGPU.ほかはCPU.
  • 再rendering
    • DOM eventにより発生
    • JavaScriptのコードにより,どのphaseを引き起こすか知ることがimportant

Ch3 tuningの基礎

  • 闇雲なtuningの害
    • trade off: developerの時間的resource.コードの単純さ.
    • best practice
      • HTTP requestを減らす
      • CDNを使う
      • Expires headerを設定する
      • componentをgzipする
      • style sheetは先頭に置く
      • scriptは最後に置く
      • CSS expressionの使用を控える
      • JavaScriptCSSは外部ファイル化する
      • DNS lookupを減らす
      • JavaScriptを最小化する
      • redirectを避ける
      • scriptを重複させない
      • ETagの設定を変更する
      • Ajaxをcache可能にする
  • ×推測,〇計測
    • bottleneckの解消がimportant
  • 目指すべき指標を設定する
    • performance metrics: RAIL
      • user中心のperformance model
      • Web page以外にも,複雑なinteractionやanimationを含むWeb applicationやHybrid applicationにも適用できる
      • Response, Animation, Idle, Load
      • Response: 100 ms
        • userが感じられる視覚的な変化
        • over 100 msなら,処理中を意味するindicatorの表示が〇
        • 指のtouchやscrollはAnimationと同じく16 ms以内が必要
      • Animation: 16 ms
        • 連続して行われるframeの中で1 frameの処理時間の目安
        • frame: Scripting, Rendering, Painting
        • 16 ms → 60 FPS(Frames Per Second)を満たす
        • frame中のJavaScriptの処理時間は6 ms以内
      • Idle: 50 ms
        • Idle状態で実行されるJavaScriptの処理時間
      • Load: 1000 ms
        • 1000 ms以内にsplash screenを表示して,そのほかのresourceの読み込みは遅延でも〇
        • cacheやloading 画面の表示で,各種resourceの読み込みを遅らせるのが〇
  • 計測手段
    • Chrome DevToolsなどdeveloper toolによる計測
      • Web page内の細かな計測や解析を行うのに有効
      • Web pageがどのように処理されてRenderingに至るのかを詳細・多角的にみられる
      • performanceのbottleneckの原因箇所の調査に有効
      • 継続的かつ定量的な計測には向かない
    • JavaScriptによる計測
      • performanceのmetricsの収集・算出の自動化
      • userの環境にばらつきがあるcaseで特に有効
    • performance診断tool
      • performanceが適切かどうか,performance改善のためのtechniqueをadvice
    • 継続的監視
      • 改修を重ねていくときにperformanceの問題を常に確認する必要がある
  • Chrome DevToolsなどdeveloper toolによる計測
    • AndroidでのChrome DevToolsの利用方法
      • PCとAndroidをUSBで接続する
    • WebViewを使う場合
      • minimum code for Android application内でWebViewを呼び出しつつChrome DevToolsを利用するactivity
    • iOSでのWeb inspectorの利用
    • Chrome DevToolsの主要機能
    • Network panel
      • networkを通じたresource取得のtimelineを細かく見る
      • blue line: DOMContentLoaded
        • 遅い場合はscriptによる読み込みブロックなどの問題
      • red line: Load event
        • 遅い場合はresourceの容量が過大
      • 回線状況の再現も〇
      • 個別のresourceの取得時間: timeline上の表示にカーソルを合わせる
      • Connection SetupやRequest/Responseの内容
        • Waiting(TTFB)が長いときは,サーバ処理に時間がかかっている
    • Performance panel
      • page loadや操作に関するすべてのeventを分析〇
      • frame chart
        • blue/red lineはNetworkと同じ
        • green line: 最初のPaintが発生するtiming(page上になんらかの表示が反映されるtiming)
        • 特に時間のかかっている処理の割り出しに使う
      • profileの取得: Performance panelの記録
        • Rendering engine内のほとんどすべてのphaseのprofileを細かくとることができる
    • Memory panel
      • memory leakの検知やmemoryの使い過ぎの把握のため
      • heap snapshot, memory割り当ての確認ができる
  • JavaScriptによる計測
    • Navigation Timing APIによる計測
      • browserのnavigation時の詳細なperformance情報を取得できる
      • browserの各段階の処理時間を計測〇
      • 以前のWeb pageのunloadの時間など,Web serverでは検知できない情報を得られる
      • Objectのpropertyの差を求め,処理時間を算出
      • timing Objectは参照するtimingに注意
      • navigation Objectの内容も合わせて見る
        • どのようなnavigationか
    • User Timing APIによる計測
      • 任意の処理にかかる時間を計測〇
        • interactionなど必ずしも計測地点を機械的に宣言できない処理の計測
      • performance
        • mark()
        • measure()
        • getEntriesByName()
    • Resource Timing APIによる計測
      • 個別のresourceの取得にかかっている時間の統計情報を取得
        • redirectにかかる時間
        • DNS lookupにかかる時間
        • network connectionの確立にかかる時間
        • HTTP responseを受け取るのにかかる時間
      • Network panelとほとんど同じものが対象
      • PerformanceResourceTiming Object
    • Performance Observerによる監視
      • これから起こる処理のperformance informationを指定して監視
      • 柔軟にperformance informationを取得
        • SPAなどinteractionを多く持つようなWeb pageでのperformanceも容易に取得〇
        • 記録・解析のためにreal timeでserverに送信も〇
      • modern browserの中では,Google Chromeのみ対応
    • 高精度なtimestampを得る
      • performance.now()とDate.now()の違い
        • performance.now()は高い信頼性と精度
        • performance.timing.navigationStartからの経過時間を返す
        • 浮動小数点 ←→ 整数
          • FPSの算出など高い精度が必要な計算や,animationの同期処理を行う場合などで有効
  • performance diagnostics tools
    • performanceの改善のための助言ができるtool, service
    • 詳細は分からないが,best practiceとの乖離が分かる
    • Audits @ Chrome DevTools
      • 数clickだけの操作で手軽に行える
    • PageSpeed Insights
      • onlineでURLを入力
    • Lighthouse
      • PageSpeed Insightsと近い用途だが,CLI toolの提供や結果のexportの容易さなど,定期的な実行により適している部分がある
      • PWAへの準拠度や,accessibility対応の計測も〇
  • performanceの継続的監視
    • New Relic Browser

Ch4 resource読み込みのtuning

  • resource読み込みの流れ
    • HTML fileから始まるresourceのgraphを構築しつつ,network protocolを通じてresourceを取得・parse
    • TCP/IP + HTTP/1.1で考える
  • HTML/CSS/JavaScriptを最小化する
    • 余計なbyte列を除去する各tools
      • deploy前で自動化する
    • JavaScript libraryは最小化されているものを使っても〇
  • proper image typeを選択
    • 写真: JPEG, simple animation: GIF, others: PNG
  • image fileを最適化
    • 各toolsを,wrapper tool, task runnerやbuild toolなどから使うことも多い
  • Web fontも最適化可能
  • CSSのimportを回避
    • HTTP requestを減らすという原則 + 直列な取得・読み込みを避けるため
    • toolやメタ言語で結合する
  • JavaScriptのsyncな読み込みを避ける
    • JavaScriptのdocument.write()はDOM treeの構築に影響を与えるため,script要素はdocumentのparseやCSS fileの読み込みをブロックする
  • JavaScriptをasyncに読み込む
    • defer attribute
      • JavaScript fileは,DOM treeが構築されてから初めて実行
        • DOMContentLoaded eventの発火前に実行
      • 実行順を保証
    • async attribute
      • JavaScriptのdownload時点で実行される
      • 実行順を保証しない
        • 依存関係は,ファイルの結合などで解消が必要
    • JavaScriptでscript要素をasyncに読み込む
      • 読み込むtimingを細かく制御したい場合など
    • async 読み込みの利用方針
      • asyncが一番performance〇
      • asyncがダメならdefer
      • deferもダメなら通常のscript要素
  • device pixel比ごとに読み込む画像を切り替える
    • srcset
    • さらにresponsive対応をするなら,pictureやsizes
  • CSSのmedia queryを適切に指定する
    • FOUC(Flash Of Unstyled Content)の回避のため,renderingの前にCSSの取得と読み込みを待つようになっている
    • link要素のmedia属性を適切に指定することで,screen以外のCSS fileの読み込みがrenderingをブロックしないようになる
      • CSS内でmedia属性を指定することよりよい
  • CSS spriteを使って複数の画像をまとめる
    • HTTP requestを減らす
    • まとめた画像の一部を切り取って表示
  • CriticalCSSで最初の描画を最適化
    • CSSをinline化
    • 最初の描画に必要なCSSをstyle要素に書き出す
    • CriticalCSS以外のtoolもある
    • ほかの最適化techniqueではperformanceが不十分なときに検討
  • resourceを事前読み込みしておく
    • DNS pre fetch(dns-prefetch)
      • 対象のpageをホストしているドメインには意味ない
    • resourceの事前読み込み
      • link rel="prefetch"
    • Web pageのpre rendering
      • link rel="prerender"
      • landing pageやpage送りのnavigationがあるときなど,遷移先が限られているときに〇
    • connectionの投機的開始
      • link rel="preconnect"
    • 事前読み込みするresourceの動的追加
      • 事前読み込みのtimingを制御
  • Gzip圧縮を有効にする
    • HTTP response内のContent-Encoding: gzip
    • Apacheでの圧縮の指定方法
    • 画像や動画など圧縮済みのものは回避要
    • HTTP response headerをdeveloper toolで見ることで圧縮の確認ができる
  • CDNを用いてresourceを配信する
  • domain sharding
    • 多くのmodern browserでは,hostごとの同時connection数の上限は6
    • CDNなどでresourceを配信するhostを複数用意
    • DNSの名前解決にかかる時間は増える
    • HTTP/2ではあまり意味がない
      • 1つのconnectionで並列にrequest/response
  • not redirect
    • directoryの名前で終わらず,/をつけるかファイル名を明示する
      • directoryの名前で終わると,/をつけたURLにredirectされる
  • browserのcacheを活用
    • Expires header
      • 強いcache
      • Apacheでの指定方法
      • HTTP response headerを確認するとわかる
      • server/clientで時間設定がずれていると×
    • Cache-Control header
      • 強いcache
      • max-age
      • Apacheでの指定方法
    • Expires/Cache-Control headerの使い分け
      • Cache-Control headerが優先される
      • Expires headerは古い
    • URLにtokenを付加する
      • 強いcacheを疑似的に消す
      • PHPなどのserver sideで付加することがほとんど
    • 弱いcacheの活用
      • 条件つきHTTP requestを使う
    • Last-Modified headerの設定
    • ETag headerの設定
      • Entity Tag(version)で表現
    • Last-Modified/ETag headerの使い分け
      • ETagが優先される
      • Apacheでの指定方法
      • 複数台のWeb serverのときは,ETagが変わってしまうため対応が必要
        • ETagの柔軟性が不要なら,ETagを付加せずLast-Modifiedのみ指定
    • cacheの使い分け
      • 静的なresourceは強いcache
      • まず強いcacheを使えないか判断し,だめなら弱いcache
  • Service Workerの使用
    • JavaScriptからcacheの制御を柔軟に実行可能
    • Web Workerの一種で,main threadとは別threadで動作
    • Web pageとWeb server間でproxyのように動作し,resourceをcacheから取得するかWeb serverから取得するか決定
    • Service Workerの導入
      • https or localhostのみ〇
      • code例
      • offlineに対応したWeb applicationの開発もできる
      • cacheの制御やresourceの取得も柔軟にcustomize〇
      • cacheでresourceのload時間を短くしたい場合にも有効
      • 対応browserは限定的なので,HTTP headerによるcacheをまず適用したうえで実施する
    • 廃止されるApplication Cacheの代替になる
  • HTTP/2の利用
    • SPDY protocolがbase
      • SPDY protocol: resource読み込みのlatencyの削減を目的にGoogleが開発
    • binary化したprotocol
      • HTTP/1.1: text baseの通信
      • 効率〇
    • HTTP/1.1のsemanticsの再利用
      • HTTP/1.1とTCPの間に挟まって通信を効率化するような形
    • requestとresponseの多重化
      • browserの同時connection数のlimitなし
    • HTTP headerの圧縮(HPACK)
      • RFC7541
      • 以前送ったHTTP headerの差分のみをお互いに送る
        • 無駄が減る.requestごとの効率up
    • HTTP/2 protocolはTLSが事実上必須
      • 速度は問題ないケースもある
    • HTTP/2で無意味になるtechnique
      • HTTP request数を減らしたり,同時接続数の制限を疑似的に増やす必要がなくなる
    • HTTP/2 対応 reverse proxyの利用
      • clientからのaccessをHTTP/2 serverが処理し,実際のcontents配信はHTTP/1.1 serverが行う構成を取れる
  • QUIC protocol
    • UDP上のnetwork protocolで,QUIC protocolの上でHTTP/1.1やHTTP/2 protocolを使える
    • merit
      • connection開始時のlatencyの削減
        • tokenの使用による
      • Head-of-Line Blockingの削除
        • 再送を個別のpacket単位で行う
    • UDP上でありながら,TCPのpacket loss検出や誤り検出ができ,TLSの盗聴・改ざん防止もできる
    • 書籍が書かれた時点では,Google Chromeのみ対応
      • Googleのserviceでは使われている
  • build tool
    • ファイルの依存関係を解決し,複数のファイルをまとめる目的
    • task runnerも同等の用途で使われる
    • tuningのためのtechniqueの自動化に必要
    • TypeScriptやBabelのtranspileや,buildまでの経路の複雑化などから,build toolは不可欠になってきている

Ch5 JavaScript実行(Scripting)のtuning

  • HTML5になり,文書だけでなくapplicationを表現するplatformになった.
  • 文書と構造: HTML, CSS ←→ 動的な側面: JavaScript
  • JavaScriptの実行model
    • UI thread
      • tab1つにつき1つのUI thread(main thread)
      • JavaScriptの実行だけでなく,rendering engineの様々な処理が実行
        • Layoutの計算,rendering処理,DOM eventの発火など
    • event loopと実行queue
      • JavaScriptはevent loopというmodelで動作するため,single threadでの動作にもかかわらず,複数の処理を同時に実行できる
        • responseの受け取りなどの継続する処理は,asyncで動作するcallbackの受け渡しやevent listenerによる
        • networkなど処理待ちの時間は,タスクを一度終了しUI threadに制御を戻す.処理の再開時にはじめてUI thread上での処理が始まる.
        • 例外
  • JavaScriptのbottleneckを特定する
    • Performance panelによる計測
      • rendering engineの行うほとんどの処理のprofileを取れる
        • JavaScript, UI threadのrendering, DOM eventの処理など
        • JavaScriptでは,どの関数でどのくらい時間がかかっているか細かくわかる
      • performance diagnosticsなら,まずはPerformance panelでprofileを取る
    • 各処理の確認方法
      • 警告箇所と,ほかの処理の妨げになっているところや明らかに処理時間が長いものを見ていく
  • GCを避ける
    • requestAnimationFrame()などのときに,問題になる
    • 検知: Performance panelでprofileを取る
    • 防ぐ: 新しいObjectを生成しないか,必要なObjectや配列を予め生成しておく
  • memory leakを防ぐ
    • importance
      • performanceやapplicationの安定性のためにimportant
      • desktopでもswapで遅くなるし,mobileではapplicationがcrashする
    • detection
      • Performance panelでprofileを取る
    • heapの3点観測
      • heap snapshotを3つとる
      • Summary viewの見方
        • 黄色のObject: JavaScriptから参照されているObject
        • 赤: documentのDOM treeから分離したDOM treeに含まれているDOM要素
    • console.log()によるmemory leak
      • log()以外も,consoleに値を解析して表示する類のものは,特殊な参照がつく
      • debug処理の除去の自動化ができる
    • DOM leak
      • DOM tree自体もleakする
    • DOM leakの検知
      • memory leakの検知と同じ
      • 不要になったDOM要素はGCで初めて回収される → profileを取り終える前に,Performance panelの左上のゴミ箱マークで,GCを発動させて不要なDOM要素の解放が必要.
  • WeakMap, WeakSet
    • weak reference: GCでは利用されていると見られない
    • WeakMap: あるObjectの拡張や,private memberを持ちたいときに使える
    • WeakSet: あるObjectにflagを立てたいときに使える
    • 利用して〇なら最初から利用する
  • Web Workersの利用
    • codeの複雑化,thread生成costなどのtrade offあり
    • 利用方法
      • Web WorkersのthreadとUI thread間の通信: message passing(asyncにデータを通信し合う
        • postMessage(), event listener
        • 共有ではなくcopy
    • multi Web Workersを生成する
      • multi coreで並列計算
      • navigator.hardwareConcurrencyを参照してコア数を取り,それに応じたWeb Workersを生成する
        • 論理的なコア数が見える
    • Transferableを利用
      • copyとcopyのoverheadを回避
      • 所有権が移動する
      • Transferableを実装しているObject
        • ArrayBuffer: 型つき配列のdata storage
        • MessagePort: ほかのdocumentとの通信のために使う
    • 制限
      • 使えないObject
        • DOM要素,document Object, window Object, parent Object
      • → 純粋なデータ処理のみをWeb Workerで行う
  • asm.jsによるJavaScript高速化
    • 高速実行のためのJavaScriptのsubset language
    • specification
      • 計算はすべてstatic typing
      • 計算で使える型はint, double, floatのみ
      • asm.js module内部では仮想的にGCが利用不可
    • asm.js形式のコードを書きだすtranspilerによって処理を記述する想定
    • いずれWebAssemblyにreplaced
  • WebAssembly
    • より高速なloadと実行を目的として各browser vendorによって策定されている,browser上で実行可能なbinary format
    • JavaScriptの一部の機能を代替
    • merit, compared to asm.js
      • load time短縮
      • parseの簡略化
      • heap sizeの制限緩和
      • memoryに対する柔軟な読み書き
  • SIMD.jsの利用
    • SIMDJavaScriptから扱えるAPI
    • SIMD: Single Instruction Multiple Data
      • 複数の値の計算を一度に行う
      • data levelでの並列計算
      • x86ではSSE(Streamed SIMD Extensions), ARMではNEONという命令セットがある
        • SIMD.jsのAPIは,内部でこれらの命令を使う
    • 利用方法
    • 算術演算の一覧
    • 高速化の目安
      • 4つを一度に計算しても2~3倍程度
    • 標準化と対応browser
      • WebAssemblyに置き換えられていき,正式な仕様にはならない見通し
  • 高頻度で発火するeventの抑制
    • scroll, resize, touchmoveなど
    • setTimeout()やrequestAnimationFrame()で,ある一定の頻度でのみ実際の処理を行うようにする
    • そのほか,視差効果やscroll event listenerなど
  • mobile端末でのclick eventの遅延をなくす
    • meta要素によるviewportを適切に設定する
    • FastClickやTappy libraryを使っても〇
  • Passive Event Listenerでscrollのperformanceを改善する
    • event.preventDefault()が無効になることを保証
    • capture phaseでevent listenerを呼び出し
    • browserでのsupportの確認処理
    • scroll performanceの改善以外にも,event listenerがinteractionをブロックする時間が気になるときには検討〇
  • setImmediate()のasync 実行
    • setTimeout()は,指定した時間の後にasync実行
      • ↑ ずれがある
    • ←→ setImmediate()は,UI threadがidleになったらすぐに実行
    • clearImmediate()で解除
    • polyfill libraryのsetImmediate.jsで使える
  • idle時処理を使う
    • requestIdleCallback()
    • cancelIdleCallback()で解除
  • page表示状態を確認する
    • 状態に応じて,animationのon/offなどを行う
    • 正確なpage viewの測定にも使う
    • Page Visibility API
      • document.hiddenを参照
      • visibilitychange event
      • document.visibilityState
  • 無駄なForced Synchronous Layoutを減らす
    • DOM操作→関連するDOM要素のLayout情報を参照で,Forced Synchronous Layoutが引き起こされる
      • Recalculate StyleとLayoutがsyncに処理される
      • JavaScriptともsyncに実行
    • Layoutに影響する操作
      • style attributeやstyle propertyを通じて要素の大きさや座標にかかわる操作をする
      • DOM要素のclass属性を変えて,当たるstyleを変更して要素の大きさや座標を変更する
      • DOM treeの構造に変更を加える操作(DOM要素の追加・削除など)
    • 計測
    • Layout Thrashingを避ける
      • loop中でFSLを繰り返し起こしてしまうこと
    • FSLを防ぐ
      • DOM 操作の前にLayout情報を参照する
      • requestAnimationFrame()で計算済みのLayout情報を参照する
  • DocumentFragmentの追加
    • Web pageのdocumentの断片を表す
    • DOM treeへのDOM要素の追加を速くできる
    • 複数のDOM要素を格納〇
  • Intersection Observerで効率的に交差を検知する
    • あるDOM要素と親要素が視覚的に交差しているか監視
    • 使い方
    • not supportedなら,scroll eventで処理したりしないといけない.問題がある.
  • canvas要素の2D Context animation
    • 特徴
      • requestAnimationFrame()やsetTimeout()で一定時間ごとにcanvas要素の再描画が必要
    • sub pixelを避ける
      • あらかじめ整数値に変換しておく
    • 描画結果のcache
      • prerenderingとも呼ぶ
    • canvas要素をlayerとして使う
      • 必要な前景layerでのみ描画
  • requestAnimationFrame()を活用する
    • setTimeout()やsetInterval()の課題
      • proper timingでcallbackの呼び出しがdifficult
    • requestAnimationFrame()によるanimation
      • 自動的に呼び出しtimingを最適化
      • 指定したcallbackを,browserのrenderingの処理に合わせて,proper timingで呼び出し
  • JavaScriptからCSS Transitionを使う
    • animationの進行中はJavaScriptのコードは一切実行されない
      • requestAnimationFrame()とは異なり,JavaScriptがbottleneckにはならない
    • UI threadとは別のthreadで実行
    • rendering engine内部で最適なtimingで実行される
  • WebGL
    • GPUを用いた高速なgraphic処理のためのcross platformなAPIであるOpenGLのうちの,OpenGL ES2.0をbrowser上から利用するためのAPI
    • library
  • WebCL
    • GPUによる超並列計算ができるOpenCLをbrowser上から利用できるAPI
    • not supportedで,一般的な使用は×
  • 小さな最適化
    • 有意味でないことが多い
    • まずはbottleneckの解析
    • 次は,アルゴリズム・データ構造や基礎技術の改善

Ch6 Layout tree構築(Rendering)のtuning

  • Rendering: Calculate Style + Layout
  • interactionの高速化にもつながる
  • Layout tree構築の流れ
    • CSSのmatching処理
      • CSS rule set: CSS selector + CSS property
      • CSS selectorは右から左に向けて処理
      • selectorの記述が増えるほど,試行回数が増えて時間がかかる
    • DOM要素の位置情報を計算する
      • rendering対象内での絶対位置
    • Rerendering
      • 内部表現の再利用,不要な処理のskip
      • Recalculate Style
      • 操作とRerendering時に起こる処理との対応を知る
  • Layout tree構築におけるperformanceの計測
    • Performance panel
      • Recalculate Style
        • Elements Affected
      • Layout
        • Nodes that need layout
        • Layout root
  • 高速なCSS selectorの記述
    • DOM treeにも注意が必要
    • CSS selectorをsimpleにする
      • 試行回数の改善に加えて,CSS rule setの詳細度が一定になることで,保守性も上がる
    • 子孫selector, 間接selectorを避ける
    • 全称selectorとの組み合わせを避ける
      • そもそも全称selectorを避けた方が無難
  • BEMを用いる
    • 設計・保守しやすさを上げる + performance〇
    • BEM: Block, Element, Modifier
      • Block: page内を構成するひとかたまり.header, footer, 記事など.
      • Element: Blockを構成する要素
      • Modifier: BlockやElementの見た目や振る舞いを拡張
      • 1つのclass selectorのみでCSS selectorを宣言する
  • CSS selectorのmatching処理を避ける
    • DOM要素のstyle propertyを直接変更すると,matching処理を回避できる
      • 必ずそうするべきというわけではなく,高速なperformanceが必要なanimationやinteractionのときのみ
    • 利用していないCSS rule setを減らす
      • UNCSS
        • build toolとの組み合わせも〇
    • media queryを指定する
      • 不要なrule setをまとめて除外できて〇
  • Layoutを高速化する
    • a.c.a Reflow
  • Layoutを避ける
    • Layoutの原因
      • DOM要素の座標や大きさの変化
      • DOM treeの構造の変化
      • DOM要素のcontentの変化
    • Layoutの範囲を限定する
      • いずれかの条件
        • svg要素
        • type="text", or type="search"のinput要素
        • table要素の子孫じゃなくてかついろいろ条件を満たす
  • DOM treeから切り離して処理する
    • DOM treeから離れれば,Renderingはなくなる
    • remove()
    • 必要になった時にappendChild()などで再挿入すればよい
  • Layoutを減らす非表示
    • display: none
  • img要素のsizeを固定
    • height, widthを指定しないと仮の大きさで1度Layoutが走る

Ch7 Rendering結果の描画(Painting)のtuning

  • interactionやanimationを実装するときに頻繁に実行される
  • Rendering結果の描画の流れ
    • → Ch2
  • 再描画(Repaint)
    • 原因
      • Layoutが引き起こされる
      • 描画が引き起こされる
        • Paintingに直接関係するCSS propertyを変更したとき
        • 確認: Chrome DevToolsのRendering option内の,Paint Flashing
      • Layerの合成が引き起こされる
        • opacity, transform CSS propertyが変更されたとき
          • 高速なanimationを実装するためには,これらのみの変更とするのが〇
        • cost小さい
  • CSS propertyの変更が何を引き起こすか
  • Layerの生成条件
    • Layer treeが構成される
    • GPUに転送されるGraphics Layerが,performanceに影響大きい
      • うまく扱うと,animationを高速化できる
    • Layer treeを確認する
      • Performance panel
      • Layer treeの詳細を確認
        • 歯車 → Enable advanced paint instrumentation(slow)にチェック → profileを取得 → Frames → Layers
      • Layerの範囲を確認
        • Rendering optionのLayers Borders
  • 描画のoverheadを解析
    • Performance panelでPaint Profilerを見る
    • Paint Profilerの確認方法
  • GPUによって合成されるlayer
    • transformCSS propertyに3D変形を指定したとき
      • GPUのVRAMに転送→Composite Layers処理があって初めて3Dになる
        • transform propertyが変更されてもPaintは起こらずComposite Layersのみ起こる.
        • Composite Layers内のGPUでの変換のみの処理は,Rerenderingの中で最速
  • translateZ hack
    • translateZ(0)により,結果を変えずにGPUで合成できる
    • position: fixedのscroll speedの改善
    • body要素にtranslateZ hackを用いる問題
      • translateZを使うためのrule
        • Rasterizeされることが少ない要素に用いる
        • 領域がそれほど大きくない要素に用いる
        • 必要なときだけ用いる
    • 必要なtimingだけtranslateZ hackを用いる
      • JavaScriptでDOM要素のstyle propertyを指定する
    • will-changeCSS propertyによるtranslateZ hackの代替

Ch8 高度なtuning

  • 大量のDOM要素を扱うvirtual rendering
    • virtual rendering(virtual list): 実際にuserに見える箇所でのみ,表示する要素をDOM treeに動的に挿入
    • concept
    • algorithm
      • scroll領域の確保
      • contentsの読み込み
        • 表示する要素は絶対座標を計算して追加
      • scrollの検知
        • 不要な要素はunload
    • 事例とlibrary
  • なめらかなanimation
    • 指標と基本的な考え方
      • RAILを使う
      • Rerenderingのphaseを減らす
    • skip Calculate Style
      • JavaScriptでDOM要素のstyle propertyを直接変更
      • 不要ならDOM treeの構造やDOM属性を変更しない
    • skip Layout
      • transformCSS propertyの値に,translate()やscale()を使う
    • skip Paint
      • Paintを引き起こさないproperty
        • opacity
        • transform
      • これらを使えない場合は仕方ない
    • layerの合成の最適化
      • translateZ hack
  • will-changeCSS propertyによる最適化
    • CSS property名を指定
      • opacity, transformのみ
    • scroll-positionを指定
      • 要素の移動(animation)や素早いscrollに対応
    • contentsを指定
      • animationや変更を予想
      • cacheの生成・維持を省ける
    • dynamicに利用
      • JavaScriptからのdynamicな利用が〇
      • CSSでの宣言は,その要素が常に変更されるときのみ
    • 使い方
      • 最適化においては,見かけほど有用ではない
  • CSS ContainmentでRerenderingを最適化
    • CSS Containment: DOM treeの一部に封じ込め〇
    • 利用方法
    • layout: Layoutの封じ込め
      • 副作用: floatCSS propertyでの回り込みの影響がなくなる
    • paint: Paintの封じ込め
      • Layoutの封じ込めとともに,大きな最適化
      • 副作用3点
    • style: styleの封じ込め
      • 単体では使わない
    • size: 大きさの封じ込め
      • 単体では使わない
      • layoutと併用したり,content/strictを指定して使う
    • content/strict: 複数の封じ込め
      • content: layout + paint + style
      • strict: layout + paint + size + style
        • 最も最適化の効果〇
        • まずはstrictで,だめならcontent
  • AMP(Accelarated Mobile Pages)
    • static contentsを高速に提供
    • 専用CDNやprerenderingなどで〇

Ch9 認知的tuning

  • indicatorを使う
    • 1sを超える処理や読み込みのとき
    • 10sを超えるときはprogress barなどの進捗の表示が必要
  • interface previewを使う
    • indicatorより印象〇
  • 処理が終わったように振る舞う
    • beforeunloadで処理中の離脱へのアラート
  • 無限scroll
    • 同様の要素を表示するpageで使う
    • userのscrollをJavaScriptで検知,pageの最下部になると,次のpageの情報を読み取って動的に読み込むべきcontentsを画面下部に追加
    • 一部のRerenderingで済むため速い
    • 実装上の注意
      • → 5.11
    • virtual renderingとの違い
      • 無限scrollはvirtual renderingと併用する
    • merit
      • waiting time小さい
    • demerit
      • footer使えない
      • back buttonで表示が壊れることがある
        • リンクは別windowにするなど対応が必要
  • 投機的なresourceの先読み
    • user activityの洞察と解析が必要
    • 事例
    • 手段
      • JavaScriptで実装したapplication levelのcacheを使う
      • IndexedDB, LocalStorageなどのstorageで保存するか,もしくは単にJavaScriptの変数で保持(SPAなどのとき)
      • Resource Hints API(4.11)も〇
    • SPA: Single Page Application
      • SPA以外は,page操作で断絶 → userの体感速度を大きく低下
      • Ajaxの発展形
      • library, frameworkが必要
        • React.js, Angular, Vue.jsなど

Appendix SVGのperformance特性

  • SVG: Scalable Vector Graphics
    • XMLで表現されるVector Graphicsのformat
    • browserで利用できる唯一のVector Graphics format
    • HTMLと親和性がある
      • img要素ではなく,svg要素で,その画像をdocument内に直接埋め込める
        • tagの記述も〇
        • JavaScriptでの振る舞いを追加したり,CSSで修飾もできる
    • JavaScriptSVG内の視覚的要素をanimationさせたり,event listenerを追加してinteractionを与えられる
    • HTMLのanimationの問題もいくつか回避している
    • JavaScriptでanimationを行う
      • 属性を操作
        • LayoutはSVG要素内に限定してくれる → 通常のDOM要素のanimationよりもperformanceの負荷小さい
      • CSS Transitionを使う
        • 通常のDOM要素のtransformCSS propertyの変化とは異なり,LayoutからRerendering
    • SMILによるanimation
      • SMIL: Synchronized Multimedia Integration Language
      • SVG animationは,SMILのanimationの要素を利用
      • SVG animationは,Web標準から外れる予定

『Web API: The Good Parts』学習メモ

Ch01 what's Web API

  • Web API: HTTP protocolを利用してnetwork越しに呼び出すAPI
  • API: Application Protocol Interface
    • target: XML over HTTP, JSON over HTTP
    • developerにAPIを公開することで,サービスに付加価値がつく
    • eco systemに参加
    • ProgrammableWeb: API directory service
    • third party JSのためのAPI
  • APIのpattern
    • 使用例
  • APIで公開するもの
    • serviceのcoreの価値のある部分すべてを利用可能にする
    • riskについて.
      • 公開しなくてもriskはある.
    • 利用規約で問題行動への対応を表明
    • APIを小売向けのような形で公開する
  • Web APIを美しく設計する重要性
    • 使いやすさ,変更しやすさ,頑強さ,魅力
  • Web APIを美しくするには
    • 仕様が決まっているものは仕様に従う
    • 仕様がないものはdefacto standardに従う
  • RESTとWeb API
    • RESTの本来の意味に合っていない使われ方がされている
    • RESTの考えを適用する場面は多いが,すべてがRESTではない
  • target developerの数とAPIの設計思想
    • LSUDs(Large Set of Unknown Developers)とSSKDs(Small Set of Known Developers)
    • SSKDs向けは,RESTを基本にしたAPIでは不十分
      • → Orchestration layer
  • まとめ
    • [Good] Web APIが未公開なら,すぐ公開を検討
    • [Good] Web APIを美しく設計する
    • [Good] RESTという言葉にこだわり過ぎない

Ch02 endpointのdesignとrequestの形式

  • APIとして公開する機能をdesign
    • UCを考える
  • API endpointの考え方
    • endpoint: APIにアクセスするためのURI
    • 覚えやすく,どんな機能を持つURIか一目でわかる
      • 短く入力しやすい
      • 人間が読んで理解できる
        • ProgrammableWebで正しい英単語を確認
      • 大文字小文字が混在していない
      • 改造しやすい(Hackable)
      • server側のarchitectureが反映されていない
      • ruleが統一
  • HTTP methodとendpoint
    • URI: 操作するもの.method: 操作方法.
    • 1つのURIのendpointに異なるmethodでアクセス
      • resourceと扱いの分離 ← HTTPの本来の考え方に合致
    • POSTは指定したURIに従属,PUTはURIそのもの
    • PATCH: 一部のみ変更
    • GET, POSTしか使えないとき
      • X-HTTP-Method-Override
      • _method
        • Railsが使っている
      • X-HTTP-Method-Overrideの方が利用しやすい
        • 固有の形式となることや,メタ情報が増えてしまうため.
  • APIのendpoint design
    • Web APIの基本: あるデータの集合と個々のデータをendpointとして表現し,それに対してHTTPのmethodで操作を表す.
    • Foreigh keyをそのままidとして使うのが良い
    • resourceにaccessするためのendpoint designの注意点
      • 複数形の名詞を使う
      • 利用する単語に気を付ける
      • spaceやencodeを必要とする文字を使わない
      • 単語をつなげる必要がある場合はハイフン
        • 基本は,単語のつなぎ合わせではなく,パスで区切る/query parameterとする/なるべく短い表現にするのがよい
  • 検索とquery parameterのdesign
    • pagination: 取得数と取得位置を指定
      • per_page + page, or limit + offset
    • 相対位置の問題
    • → 絶対位置での取得
    • 絞り込みのためのparameter
      • qは部分一致〇
      • URIにSearchを入れるのは,検索という意味を強調するために有用である
      • 検索に主体があるserviceのAPIの場合
    • query parameterとpathの使い分け
      • 一意なresourceを表すために必要な情報で,省略不可能な場合はpath, そうでなければquery parameter.
  • loginとOAuth 2.0
    • 認証のAPIとして,Authが真っ先に検討できる標準仕様
    • 自社開発のClient Applicationにおいて,ユーザ名とパスワードをapplication内に入力して認証を行う場合
      • OAuthのGrant Typeのうち,Resource Owner Password Credentialsを使う
        • 扱い方
    • access tokenの有効期限と更新
    • other Grant Type
      • Client Credentials: User name, Password不要な認証.Clientの認証のみ行う.
    • 自分の情報へのalias
      • me, self
      • ほかのユーザの情報の処理とは,処理自体を分岐することでバグを防げる
  • hostnameとendpointの共通部分
  • SSKDsとAPI design
    • LSUDsに比べて,end userにとってのuser experienceがより重要になる.
    • 汎用的という点では美しくなくてもよいケースがある.
      • 1 screen 1 API call, 1 save 1 API call
  • HATEOASとREST LEVEL3 API
    • HATEOAS: Hypermedia As The Engine Of Application State
      • Hypermedia @ Web API: APIのresource
    • media typeで,アクセスしたデータがどんなデータか指示
    • merit
      • URIの変更が容易になる
      • Hackableでなくてもよくなる
    • SSKDs向けのAPIには〇.LSUDsにはまだ△.
    • Client, Serverともに自分で開発するようなsituationでは,検討できる
  • まとめ
    • [Good] 覚えやすく,どんな機能を持つか一目でわかるendpointにする
    • [Good] 適切なHTTP methodを利用する
    • [Good] 適切な英単語を利用.単複にも注意.
    • [Good] 認証はOAuth 2.0

Ch03 response dataの design

  • data format
    • APIが返す構造化データの表現. JSON, XMLなど.
      • JSONがdefault. XMLは必要があれば.
      • JSONの方がsimple, 同じデータを表すのにサイズが小さくて済む, JSとの相性〇
    • data formatの指定方法
      • query parameter ← 最も使われている
      • 拡張子
      • request header
  • JSONPの取り扱い
    • JSON with Padding
    • domainを超えたaccessのため
    • 作法
      • callback function nameのquery parameterでの指定
      • jQueryのe.g.
      • JSONPはJSなので,media typeはapplication/javascriptになる
    • error handling
      • 200を返し,response bodyでerrorの内容を示す
    • 不要ならJSONPは使わない
      • 同一生成元policyを回避してしまうため
  • dataの内部構造の考え方
    • response data: APIのアクセス回数がなるべく減るようにする
      • APIのUCを考える必要
      • Web APIは,DBのinterfaceではなくapplicationのinterface
      • × Chatty(おしゃべりな) API
    • すべてのAPIでできるだけ多くのデータを返す準備をしておき,利用者が取得する項目を選択する
      • response group
    • envelope: 冗長.HTTPがやっているため十分.
      • JSONPのときだけは使うと便利
    • 同じ構造なら階層構造,そうでなければできるだけflatにする.
    • response全体をObjectにして,中に配列を入れるのが〇
      • response dataが何を示しているかわかりやすい
      • response dataをObjectに統一できる
      • security
    • 配列の件数,続きがあるかどうかの取り方
      • 指定の件数+1件を取れているかどうかなどでよい.
      • HackableでないAPIでよければ,HATEOAS的な考えで,次のURIなどを返すのも〇
  • 各dataのformat
    • 名前
      • endpointのdesignと同じ.
      • JSONではcamel case ← JSと同じ
      • snake caseの場合もあり.snake caseの方が読みやすいらしい
      • 配列の場合は複数,それ以外は単数
    • 性別
      • genderで文字列
      • 生物学的な使い方ならsex
        • sexなら1/2もあり
    • 日付
      • RFC 3339形式が〇
      • SSKDs向けならUnix timestampも〇
      • HTTP日付はformatが異なる
    • 大きな整数とJSON
      • 大きな整数は文字列で返す
  • response dataのdesign
    • あるデータを返すときは同じ構造になるよう,それぞれのデータの構造を定義してしまうとsimpleで〇
  • errorの表現
    • proper status code
    • detail
      • bodyで〇.headerに入れるのも悪くはなさそう
      • detail code, detail information link
    • HTMLで返らないようにする
    • @maintenance
      • 503
      • Retry-After
    • 意図的に不正確な情報を返す
  • まとめ
    • [Good] JSON,あるいは目的に応じたdata formatを使用
    • [Good] dataを不要なenvelopeで包まない
    • [Good] responseをできる限りflatな構造にする
    • [Good] 各dataの名前が簡潔で理解しやすく,適切な単複が用いられている
    • [Good] errorのformatを統一し,Client側でerror detailを機械的に理解可能にする

Ch04 HTTPの仕様を最大限利用する

  • 意義
    • 不本意に独自仕様をいれてしまう危険性を下げる
    • HTTP protocolがenvelopeの役割という例
  • status codeを正しく使う
    • APIで使うcode一覧
    • 2xx: success
      • 204: No Contentは,是非あり
        • PUT, PATCHは,200とともに操作したデータを返す(POSTは201)
        • DELETEは204
    • 3xx: 追加で処理が必要
      • redirect: 301, 302, 303, 307
        • Locationを伴う
      • POSTによるデータ送信 → GETで別のページを表示のケースが多い
        • 302, 301はmethodの変更を許可
        • 308, 307は不許可
      • APIではできるだけredirectを避ける
      • 300: Multiple Choices
      • 304: Not Modified
    • 4xx: Clientのrequestに問題があった場合
      • 400: Bad Request
        • ほかのcodeでは表せない「その他」
      • 401: Unauthorized. Authentication(認証) error. ← 誰ですか?
      • 403: Forbidden. Authorization(認可) error. ← 許可がないよ.
      • ほかにも色々ある
    • 5xx: Serverに問題があった場合
  • cacheとHTTPの仕様
    • cacheのmerit. → 可能な限り利用するべき
    • proxy serverへの考慮必要
    • reverse proxy
    • Expiration Model
      • fresh ←→ stale
      • Expires
        • 特定の日時に更新されることがあらかじめわかっているdataに使う
      • Cache-Control
        • max-age
          • HTTP時間
            • RFC1123を使う
    • Validation Model
      • 条件付きrequest
        • Last-Modified, ETag (Entity Tag)
        • If-Modified-Since, If-None-Match
      • e.g. MurmurHash3
      • strong/weak Validation
        • weakなら,広告などの違いは無視できる
    • Heuristic Expiration(発見的期限切れ)
      • ClientがCacheの期限を自分で決める
    • Cache-Control: no-cache
    • VaryでCacheの単位を指定
      • Server Driven Content Negotiation
      • Accept-Encoding, User Agent, Accept-Language, Authorization, Cookie
    • Cache-Control header
      • stale-while-revalidate
        • asyncでcacheの検証をしている間はcacheを返してよい → 速度〇
      • stale-if-error
        • origin serverに接続できなかったときに,stale cacheを返してよい秒数
  • media typeの指定
    • media type: data format
    • Content-Type @response
      • MIME: Multipurpose Internet Mail Extensions
        • top level type name/ sub type name [; parameter]
          • top level type: text/image/video/applicationなど
          • sub type: 具体的なdata format
      • 前提知識なくても読めればtext, そうでなければapplication
    • 正しいmedia typeをContent-Typeで返す
    • x-で始まるmedia type
    • 自分でmedia typeを定義する
      • Registration treeで接頭辞が決まっている
        • vnd.を使うことが多い
    • JSONXMLを用いた新しいdata形式を定義する場合
      • 独自に別のHTTP headerを用意するのが折衷案として〇
    • media typeが正しくないと,security riskあり
    • media type @request
      • Content-Type
        • 複数dataのPOSTは,multipart/form-data
      • Accept
        • どんなmedia typeを受け入れ可能か
        • q: Quality Value. そのtypeの優先度.
        • → serverが配信するdata formatを決定: Server Driven Content Negotiation
        • ServerのresponseではVaryにAcceptを指定する必要
        • URIで形式を指定する方が手軽といえば手軽だが,HTTPの仕様に即しているのはAccept
  • 同一生成元policy(Same Origin Policy)とCross-Origin Resource Sharing
    • CORSはJSONPより安全で公式の仕様
    • ClientからOriginというrequest headerを送る
    • ServerはAccess-Control-Allow-Originというresponse headerを返す
    • pre flight request
    • Access-Control-Allow-Credentials
  • 独自のHTTP headerを定義する
    • 接頭辞: X-
    • X-は不要という論もある
  • まとめ
    • [Good] HTTPの仕様を最大限利用し,独自仕様の利用を最低限に止める
    • [Good] 適切なstatus codeを用いる
    • [Good] 適切な,なるべく一般的なmedia typeを返す
    • [Good] Clientが適切なcacheを行えるように情報を返す

Ch05 設計変更をしやすいWeb APIを作る

  • 設計変更のしやすさのimportance
    • 影響が分かりづらい
    • 外部/mobile/web serviceいずれの場合も問題あり
      • web service,自分のserviceで使っているAPIであれば,問題は小さいが,cacheの問題はある
  • APIをversionで管理する
    • 新しいAPIを別のendpoint, または別のparameterをつけたURIなど,新しいaccess形式で公開が〇
    • 方法①: URIにversionを埋め込む
      • 最も一般的でわかりやすく,おすすめ
      • vを付けた方が分かりやすい
      • semantic versioning
        • APIではmajor versionのみパスに含めるのが一般的
      • path以外での指定
        • query parameter
          • 省略可能
          • 冗長だったり,省略したときに分かりづらいので,パスの方が〇
        • media type
          • HTTPの文法に則っており,パスのようにpresentation levelの指定がURIに含まれずに済む
          • Client libraryの解釈で問題がある可能性あり
          • → 独自のHTTP headerを定義して指定する方法がある
  • versionを変えるときの指針
    • security, authorityにアップデートは,後方互換なしで〇
    • 以降のバージョンアップの影響を小さくするために実施する
    • 常に最新版を返すaliasは不要
  • APIの提供を終了する
    • 終了日時の周知
    • Blackout Test
    • 予め提供終了時の仕様を盛り込む
      • 強制アップデート,ユーザのOSの調査
    • 利用規約にサポート期限を明記
      • applicationの性質による
  • Orchestration layer
    • LSUDs: one-size-fits-all(OSFA)
    • OSFAではなく,それぞれのClientに対応するために,ServerとClientの間にOrchestration layerを挟むようにする.
  • まとめ
    • [Good] APIのversionの更新は最低限にとどめ,後方互換性にも注意
    • [Good] APIのversionはmajor versionをURIに含める
    • [Good] APIの提供終了時は,すぐ終了するのではなく最低6か月は公開を続ける

Ch06 堅牢なWeb APIを作る

  • 安全性と安定性
  • Web APIを安全にする
    • riskのe.g.
  • Server-Client間での情報の不正入手
    • risk
    • HTTPS by TLS
      • URIのpath, query 文字列, header, bodyを暗号化
        • ↑やり取りに使われるほぼすべての情報
      • HTTP Strict Transport Security(HSTS)により,HTTPSの強制〇
      • HTTPSでもriskあり
        • Man-In-The-Middle attack(MITM): 不正な証明書を使用 ← 証明書の検証で回避
        • Clientでも対応が必要
      • 速度の問題
    • 認証局への攻撃
      • Certificate and Public Key Pinningで回避
        • OWASPに実装方法あり
  • browserでアクセスするAPIの問題
    • browserは汎用的で機能が豊富
    • XSS
      • JSON injection: 特にJSONについては,必ずJSONとしてbrowserに判断させる必要がある
        • Content-Typeの指定
        • Content Snifferingへの対応
          • X-Content-Type-Options: nosniff
            • JSONでデータを返す際には必ずつける
          • 追加のrequest headerのチェック
            • X-Requested-With: XMLHttpRequest
            • 追加のpre flight requestが必要になってしまうので,明示が必要
          • JSON文字列のescape
    • XSRF: Cross Site Request Forgery
      • Forgery: 偽造,捏造
      • 回避方法
        • methodを正しく使う
        • XSRF tokenを使う
        • X-Request-With
    • JSON hijack
      • 回避方法
        • JSONをSCRIPT要素では読み込めないようにする
          • X-Requested-With
            • XMLHttpRequest, browser以外からのClientからのアクセスのみを想定の場合は,必ずやる
        • JSONをbrowserが必ずJSONと認識するようにする
          • 正しいmedia typeを返す
        • JSONJavaScriptとして解釈不能,または実行時にデータを読み込めないようにする
          • JSONの配列ではなくObjectを返すようにする
          • 無限ループを仕込む e.g. Facebook
    • browserからのアクセスを想定しないAPIでは,browserからのSCRIPT要素を使ったアクセスを防ぐのが〇
  • 悪意あるaccessへの対策
    • どんなデータがやり取りされているか知られても,不正を働けないようにしておく必要がある
    • parameterの改ざん
      • 本来accessできない情報はServerでcheck → access禁止
      • rate limit
      • Server側でデータの整合性をチェック
        • minusのチェックなど(アイテムやポイントの数などの不正操作を防ぐ)
    • requestの再送信
      • stateを管理
      • 支払いの偽装
        • Consumable/Non-Consumable
  • security関係のHTTP header
    • X-Content-Type-Options
      • JSONJSON以外として解釈することを防ぐ
      • JSONAPIを配信する場合は必須
    • X-XSS-Protection
      • browserのXSSへの防御機能の有効化
    • X-Frame-Options
      • dataがFrame内で読み込まれるのを阻止
    • Content-Security-Policy
      • default-src 'none'
    • Strict-Transport-Security
      • HSTSのためのheader
      • HTTPSのみに限定
    • Public-Key-Pins
      • HPKPのためのheader
      • SSL証明書が偽造されたものでないかcheck
    • Set-Cookie headerとsecurity
      • Secure, HttpOnly
    • 実例
  • 大量accessへの対策
    • userごとのaccessを制限 ← 最も現実的
    • rate limit: 単位時間あたりの最大access回数
    • 決めること
      • ユーザの識別要素
      • limit value
      • limit valueの単位
        • UseCaseの考慮
        • APIのgroupごとに設定など
        • 1時間単位くらいが多い
      • limitのreset
        • rolling window
    • access制限緩和
      • 特定のapplicationや開発者
      • 課金
    • 制限値を超えたときの対応
      • 429 Too Many Request
      • 429以外のstatus codeが使われていることも多い
    • rate limitをuserに伝える
      • document + API利用者向けのdashboard
      • HTTPのresponseのheaderでrate limitを渡す
        • X-RateLimit-Limit
        • X-Rate-Limit-Resetは,resetまでの秒数をデルタ秒で表すのが〇
    • rate limitの実装
      • 実際は,RedisのKVSなどを使って記録する
      • そのほか,API公開をサポートするサービスにも機能がある
  • まとめ
    • [Good] 個人情報など特定のuser以外に漏洩したくない情報がある場合はHTTPSを使う
    • [Good] XSS, XSRFなど通常のWebと同様のSecurityだけでなく,JSON hijackなどAPI特有の脆弱性にも配慮する
    • [Good] Security強化につながるHTTP headerをちゃんとつける
    • [Good] rate limitを設けることで一部のuserの過度なaccessによる負荷を防ぐ

Appendix

  • Web APIを公開する際にできること
    • API documentの提供
      • 常に最新にしておく
      • API Blueprint
        • document公開補助tools: RSpec Api Blueprint, iglo, API Mock, apiary
    • sandbox APIの提供
      • e.g. PayPal, Gengo
      • hostnameのみ変えているcaseが多い
    • API Console
      • browser上で実際にAPIを操作して試せるtool
      • e.g. Graph API Explorer
      • 生成補助tools: Apigee
    • SDKの提供
      • maintenance cost大
  • Web API check list

『メタプログラミングRuby』 学習メモ

Part 1 meta programming Ruby

Ch01 initial M

  • introspection
    • Active Recordがintrospectionを使っている
  • meta programming: 言語要素を実行時に操作するコードの記述
    • codeを記述するcodeを記述
  • meta programmingの学習により,Rubyのruleがわかる

Ch02 Monday, Object model

  • すべての言語要素はObject model内に共存する
  • Open Class
    • classはscope 演算子のようなもの
    • monkey patchは×
  • Object modelの内部
    • Objectの中身
      • instance variable
        • 値が代入されたときに初めて出現
      • method
        • ObjectではなくClassに存在する.
          • 共通のClassを持つObjectはメソッドも共通
        • → instance method: Classに定義されていて,呼び出すにはObject(instance)が必要になるmethod
          • ←→ method: Object(instance)がもつmethod
    • Classの真相
      • Class.superclass # => Module
      • Class: Objectの生成やClassを継承するための3つのinstance methodを追加したModule
      • Moduleはinclude, Classはinstanceの生成や継承
      • Classの参照も保持できる.ClassはObject,Class名は定数
    • 定数
      • file systemと類似
      • Rakeの例: moduleで定数をまとめる例
    • まとめ
      • Object: instance variableの集まりに,クラスへのリンクがついたもの
      • Classについて
    • load, require
      • load: codeの実行のため.呼び出すたびにファイルを実行する.
        • 定数の扱いのための引数
      • require: libraryのimportのため.1回だけファイルを読み込む.
  • Object, Module, Classの関係について
    • 循環したり自己参照したりしている.
  • method call
    • method探索 + method実行
    • method 探索
      • receiverと継承チェーン
      • one step to the right, then up
      • Moduleも継承チェーンに入る.
        • includeは上に,prependは下にModuleを挿入
      • include, prependは1度目のみ有効
      • Kernel: ObjectがKernelをinclude
    • method 実行
      • receiverの参照を持つ
      • self, top level
      • private: explicit receiver不可
    • Refinements
      • monkey patchの回避.
      • usingで有効にする
      • 発展途上なので,直感に合わない挙動がある
  • 絡み合ったModule
    • 継承チェーンの確認
  • まとめ

Ch03 Tuesday, method

  • boiler plate methodの回避
  • 重複問題
  • dynamic method
    • dynamic dispatch: sendを使うことで,method nameをargumentにしてdynamicにcallできる
    • :(name) ← symbol
      • immutable. String: mutable.
      • immutableなので,メソッド名などのmeta programmingに関係する名前に使う
    • Pryの例
    • methodをdynamicにdefine
      • 実行時にmethod nameを決定するため,defではなくModule#define_methodを使う
      • Stringと変換可能
    • e.g.
      • Array#grep → define_method
  • method_missing
    • ghost method: method_missingのoverride
      • Hashieのe.g.
    • dynamic proxy: ghost methodを補足して,ほかのObjectに転送するObject
      • Gheeのe.g.
        • GitHubのObjectをdynamic hash に保持.hashのattributeは,ghost methodの呼び出しでアクセスできる
        • hashをProxy Objectでラップ.
    • respond_to_missing?もあわせてoverride必要
    • const_missing
      • 古いクラス名が呼び出されたときに,警告を出して新しいクラス名を返す
    • 受付可能な引数以外はBasicObject#method_missingを呼ぶ必要がある
  • blank slate
    • 最小限のmethodしか引き継がないClass
    • BasicObjectの継承.指定しなければObject.
    • methodの削除
      • Builderのe.g.
  • まとめ
    • Rubyのdynamicな能力により,複数のmethodに共通した外部の重複を排除できる
    • 可能であればdynamic method, 仕方なければghost method

Ch04 Wednesday, block

  • not from Object Oriented Design, but from Functional Programming Language like LISP
  • block day
    • blockの基本
      • do...end, {}
      • yieldでblockを呼び出す
  • Kernel methodで,usingのように例外の有無によらず処理を呼び出せるようにする振る舞いを追加できる
  • block is closure
    • blockは,コードと束縛の集まりの両方を含む
    • scope
    • scope gate: scopeを切り替えて,新しいscopeをopenする場所
      • class, module, def
      • defは呼び出したときに実行.class, moduleはすぐに実行
      • scopeのflatten, flat scope
      • shared scope
  • instance_eval
    • instance_evalに渡したblock: context 探査機
    • instance_execなら引数で渡すことができる
        - replace scope gate to method call
      
    • encapsulateの破壊
      • irb, test
      • Padrinoのe.g.
    • clean room: blockを評価するためだけのObject
  • callable Object
    • blockの使用の2process
      • codeの保管 → blockを呼び出して実行
    • block以外のコードを保管できるところ
      • Procのなか.← blockがObjectになったもの.
      • lambdaのなか. ← Procの変形.
      • methodのなか.
    • Proc Object
      • あとで評価
      • lambdaとprocで生成できる
      • ->lambda
      • &修飾
        • methodに渡されたblockを受け取って,それをProcに変換
        • Procをblockに戻すときも&修飾
      • HighLineのe.g.
        • あとで評価
    • Proc vs lambda
      • return
        • lambdaはlambdaから戻るだけ.Procは,Procが定義されたscopeから戻る
      • 項数(引数の数)
        • lambdaは一般的に厳しい.Procは合わせてくれる.
      • lambdaはmethodに似ていて,一般的にはlambdaを使う.
    • Method Object
      • blockやlambdaに似ているが,所属するObjectのscopeで評価
      • UnboundMethod
        • Active Supportのe.g.
        • 自分ではやらない方が〇
  • DSLを書く
    • event間で共有
    • global variableの削除
    • clean roomの追加
  • まとめ

Ch05 Thursday, Class definition

  • RubyのClass definitionはcodeを実行する
  • Classは高性能のModule. Class definitionに関することはModule definitionにも置き換えられる.
  • Class definitionの分かりやすい説明
    • Class, Moduleも単なるObjectで,selfになれる.
    • current Class
      • class_eval
        • self, current Classを変更する → Classを再open可能
        • flat scope
        • class_execもある
        • instance_evalとの使い分け.
    • Class instance variable
      • Class instance variableとObjectのinstance variableは別物
      • Class variableは△.共有の度合いが大きい.
      • testでのClass instance variableの使用
  • Class のtaboo
    • Class.new()で,Class keywordを使わずにClass作成
  • 特異method
    • 特定のObjectにmethodを追加できる.
    • Duck typing
    • Class methodはClassの特異method
    • Class macro
      • Module#attr_*のe.g.
        • attr_accessorなど
      • Module Classに定義されているので,selfがModuleでもClassでも使えるもの.
        • Class定義の中で使える単なるClass method
  • 特異Class
    • a.c.a. meta Class, singleton Class
    • 変わった構文を使わないとみることができない.
    • only one instance( so that called singleton Class )
    • Objectの特異methodの在り処
      • 特異methodがあれば,特異Classから探索する.特異ClassがObjectのsuper Classになる.
    • 継承
      • metaの2乗
        • 特異Classの特異Class
      • 大統一理論
        • Object, Module, Methodはそれぞれ1種類だけ.
        • Objectの特異Classのsuper Classは,ObjectのClass
        • Classの特異Classのsuper Classは,Classのsuper Classの特異Class
      • Class methodの構文
        • Class methodはClassの特異Classにある特異method
      • instance_evalは,current Classをreceiverの特異Classに変更する
        • 意図としては,selfの変更で良い.
      • Classのattributeの追加のe.g.
  • Class拡張
    • Object拡張も〇
    • どちらもObject#extendを使うのが〇
  • method wrapper
    • methodの再定義: 新しいmethodを定義して,元のmethodに名前を付ける
    • Thorのe.g.
      • around alias
    • Refinementsでaround alias
    • Prepend wrapper
  • 計算methodをaround aliasで変更することもできるというe.g.
  • まとめ

Ch06 Friday: codeを記述するcode

  • meta programmingの新しいtrickと,様々なtrickを組み合わせて難しいcoding課題を解決する方法を見る
  • Kernel#eval
    • REST Clientのe.g.
      • code文字列は文字列の代わりになるものを使うことが多い
    • 外部ソースにある任意のcode文字列を評価するときも使う
    • Binding Object
      • scopeをObjectにまとめたもの
      • eval "@x", b ← b: Binding
      • TOPLEVEL_BINDING
      • Pryの例
    • irbのe.g.
    • code 文字列 vs block
      • 基本はblockを使うべき
    • evalのproblem
      • code injection
      • 代用: dynamic dispatch
      • Object taintとsafe level
    • ERBのe.g.
      • safe levelがあるときは, sandboxが作られてそこで実行される.
    • load, requireとの比較
  • evalでの実装とevalの置き換え
    • classのscopeに入るためにclass_eval → 実行時まで分からないのでdynamic method
    • instance variableの読み書き: Object#instance_variable_set(/get)
  • blockでの置き換え
  • Kernel methodをClass macroに変更
    • あらゆるClass定義で使うために,ModuleまたはClassのinstance methodを作成する.
      • → class_evalも不要になる
  • hook method
    • Class#inheritedなどのmethod.defaultでは何もしない
    • 特異methodにはsingletonをつけないと動作しない
    • standard methodにplugin
      • superで元のincludeを呼び出す必要ある
    • VCRのe.g.
      • instance methodを特異Classにmix in → Class methodを追加できる
  • Class macroから,includeしたClassだけaccessできるように制限する
    • Moduleのincludedを上書きして,ClassMethodsを拡張する
  • まとめ

Ch07 epilogue

  • meta programmingも単なるprogramming

Part2 Railsにおけるmeta programming

Ch08 Rails tourの準備

  • Ruby on Rails
    • Active Record(applicationのObjectをDBのテーブルにmapping), Action Pack(Web frameworkの「Web」の部分を扱う), Active Support(時刻計算やloggingなどの汎用的な問題を扱うutility)
    • gem unpack activerecord -v=4.1.0

Ch09 Active Recordのdesign

  • Object Relational Mapping
    • Relational DB + Object Oriented Programming
  • Active Recordのまとめられ方
    • Active Support + Active Model
    • auto loading by ActiveSupport::Autoload
    • ActiveRecord::Base
      • Moduleの外側にある機能をまとめるClass. Moduleの集まり
    • Moduleのincludeで,instance methodとClass methodを手に入れる
    • history
      • Active RecordからActive Modelが分離
        • Active Record: DB操作, Active Module: Object Modelの操作
  • 学んだこと
    • ActiveRecord::Baseは,究極的なopen Class
    • 疎結合,simplicity, 重複の排除という基本的な設計原則を実現するための技法が,ほかの言語と大きく異なる

Ch10 Active SupportのConcern Module

  • history
    • Rails 2では,VCRの例と同じ形だった: includeとextendのtrick
      • 欠点: 複雑 + 連鎖のために柔軟性down
  • ActiveSupport::Concern
    • Module#append_features
    • Concern#append_features
      • concern(ActiveSupport::ConcernをextendしたModule)のなかで,別のconcernをincludeしない
      • 依存を管理する.最小主義の依存管理system
  • 学んだこと
    • 柔軟性のためのmeta programming
      • codeが複雑になったり,排除しにくい重複が見つかった時に使う.
    • Moduleの相互作用のような基本的な部分でも,meta programmingで変更できる

Ch11 alias_method_chainの盛衰

  • problem
    • around aliasの問題
    • rename, shuffleが繰り返され,実際に呼び出しているmethodがどのversionか追跡がdifficult
    • そもそも,存在自体が不要
      • 別のModuleに定義して,includeすればよい.
      • Classのmethodへの機能追加には,Module#prependを使うのが〇
        • Ruby1.9との互換性の問題がなくなれば,Railsや周辺でもalias_method_chainを使う理由がなくなる
  • 学んだこと
    • 素直なObject指向で解決できれば,meta programmingは使わない

Ch12 attribute methodの進化

  • どのようにmeta programmingを使うか
  • codeが複雑になり,微妙に意味が違ってくる中で起きたことを見る.
  • Rails 1: はじめはsimple
    • method_missing
  • Rails 2: performanceに注目
    • method_missingは遅い
    • → ghost method + dynamic method
      • 各Classで1度だけmethod_missingを呼ぶ
    • backにDBのカラムがない派生fieldなどのattributeへの対応.→ attribute accessorを定義しない
  • Rails 3, 4: もっと特殊なcase
    • Rails 4ではattribute accessorの定義時に,UnboundMethodに変更し,Method cacheに保存している. → ほかのClassが同じ名前のattributeを持ち,同じaccessorが必要な場合はcacheから取り出す.
      • performanceが目に見えて変わる.
      • ReaderMethodCacheの初期化処理にコメントがある
      • attribute methodがどれだけ深くて複雑なものになったか,どれだけの数の特殊ケースに対応しているか,最初はsimpleだったところからどれだけ変わったか,を示している.
      • Rubyのsafeなmethod nameにするための対応
  • 学んだこと
    • 「最初から正しくやる」よりも「進化的設計」に傾いている.
      • Rubyが柔軟性の高い言語であるため
      • 最初から完璧なmeta programmingのcodeを書くことは難しい
    • → codeはできるだけsimpleに保ち,必要になったら複雑にする

Ch13 最後の教訓

  • meta programming: simple, clean, and tested codeを書くための単なるtool

付録

A よくあるidiom

  • mimic method
    • mimicry: 擬態
    • 偽装method
    • Campingの例
      • class Help < R '/help' ← R('/help')と読み替えるとわかる
    • attributeの不具合
      • attributeのsetterは,privateでもselfをつけて呼び出せる
  • nil guard
    • ||=
      • OR と =
    • falseになりうるときは使わない
  • 自己yield
    • blockにObject自身を渡せる
    • Faradayのe.g.
      • 新しく生成したConnection Objectをselfとしてyieldに渡す
    • tapのe.g.
      • 呼び出しのchainを断ち切らずに,中間の作業をtap {} で差し込む
  • Symbol#to_proc
    • one call blockを短い記述に置き換える
    • inject(init)などで使える

B DSL

  • ←→ GSL(General)
  • e.g. UNIXのshell, VBA, make, Ant, ...
  • GPLを,自分の問題に特化したDSLにする.
  • 内部DSLと外部DSL
    • Markabyなどの,大きなGPLの内部にあるDSLは内部DSL.makeなどの独自のparserを持った言語は外部DSL
    • RubyGPLとしての構文の制約が小さい.
      • Rakeは内部DSL ←→ Ant(Java), make(C)は外部DSL

C 魔術書

  • 今までのものの短いsample

D から騒ぎ

  • nilについて
  • Null Object
    • 未初期化の参照をNull Objectにreplace
  • NilClassにmethod_missingを追加.
    • methodの連結にも対応可能
  • →black hole
    • nilを使ったNull Object
    • 未初期化の参照の問題を回避しつつ,method呼び出しを無限のNull Objectの穴に吸い込む
  • bugに気づきづらくなるというdemeritも考慮