エクストーン流ヒューリスティック評価の進め方

エクストーン ディレクターチームの藤川です。
今日はエクストーン流のヒューリスティック評価の進め方についてご紹介します。

弊社ではサイトやアプリといったサービスの新規の立ち上げの他、リニューアルのご依頼をいただく場合が多々あります。

そのような場合に、まずは現状のサービスの評価をしっかり行うことが重要になると考えています。
お客様から「デザインが古くなった」「使い勝手が悪い」「見づらい」といった漠然とした現状に対する不満を前提としていただくことは多いのですが、その漠然とした不満は念頭に入れつつも、一度立ち止まって多角的な視点から改めて現状を分析しなおし、課題を明確化するのが「ヒューリスティック評価」だと考えています。
すでに抱えている課題だけを鵜呑みにせず、また、性急に改善案を急がず、ユーザー視点から評価を行います。

今回はこうしたエクストーンにおけるヒューリスティック評価の手法をご紹介します。

※エクストーンでは、後述する従来型のヒューリスティック評価とは差別化するため、通常は「ユーザビリティ評価」と呼んでいます。

ヒューリスティック評価とは

古くは1990年代にユーザビリティ研究の第一人者「ヤコブ・ニールセン博士」によって提唱された「ヒューリスティック評価」に遡ります。UI/UXの専門家が、その経験則に基づいてサイトやアプリを評価する手法が確立され、長く活用されてきました。

このヒューリスティック評価の手法の詳細はここでは割愛しますが、確立された当初から30年以上経過しており、現代にマッチする新しい手法が必要と考えました。
私たちは、従来のヒューリスティック評価の基本的な考え方を踏襲しつつエクストーンでの経験を活かした新しい評価方法として再定義しました。

詳細は後述しますが、サイトやアプリを大きく以下の14のカテゴリで評価するものです。

①基本設計 ②一貫性 ③操作性 ④視認性 ⑤レイアウト
⑥想定ができない ⑦情報表示 ⑧コンテンツ ⑨ワーディング ⑩機能の最適化
⑪デザイン ⑫アニメーション ⑬パフォーマンス ⑭バグ

評価の進め方

評価・分析の視点確認

事前にどんな視点で評価をするのか?を明確にすることが重要です。
「デザインを新しくしたい」「使いやすくしたい」「色を変えたい」といった具体的な不満の解決が評価のゴールではありません。
また、それぞれの画面のパーツの良し悪しを評価することだけがゴールでもありません。

必要な視点とはつまり、

  • ユーザーがそのサイトやアプリにおける目的が達成できるか
  • 各画面の品質は問題がないか

この両方の視点から「潜在的な課題を抽出」し、改修に向けた「改善点を明らかに」していくことなのです。

評価参加者はこれを常に念頭に置き意識しながら評価を行います。

評価参加者の選定

より多くの角度から評価するため、異なる職種や立場の人を複数人集めます。

対象により構成は都度検討しますが、多くの場合は ディレクター、デザイナー、エンジニア が参加します。

それぞれの職種の経験や価値観から評価することで多角的な分析が可能になります。

評価項目

前述したように、14のカテゴリで評価を行います。

各画面における指摘が以下のどのカテゴリからの指摘なのか、後から分類することになります。

さらにそれぞれの指摘の優先度を後から3段階で分類します。

具体的な評価の仕方

評価にあたってはFigmaのコメント機能を使います。

対象となるアプリやサイトの画面スクリーンショットをFigmaに貼り付け、それぞれの画面に対して評価者が評価コメントを書いていきます。

Figmaで評価コメントを書き込む様子

Figmaでの共同作業によるメリット

  1. 個別に評価を行なってしまうと評価が重複してしまい、後からスクリーニングするのが大変になってしまいます。他の評価者のコメントを見ながら評価していくことでそれを避けることができます。
  2. 具体的に画面のどこの部分に対する評価なのかが一目瞭然です。

Figmaに書き込む時に気をつけるべきこと

評価作業が終わった後、Figmaの機能を使ってコメントの一覧をエクスポートし、集計します。

画面のスクリーンショットにはフレーム名を設定し、コメントは該当フレーム内に収まる位置に書き込んでください。出力された各コメントに該当フレームのURLが載るため、どの画面に対するコメントなのかが分かりやすくなります。

また、コメントの文章を読んだ時に「画面のどこのことを指摘しているのか?」がわかるように指摘箇所を書いておく必要があります。Figma上ではついついそれが抜けてしまうため、コメントを書く段階から注意しておきます。

評価の集計と結果出力

「Export Comments」というFigmaのプラグインを使用します。 https://www.figma.com/community/plugin/930702747188058634/Export-Comments

Access Tokenと対象のFigmaURLを入力することで、コメントをエクセル形式で出力することができるプラグインです。

Access TokenはFigmaのホーム:アカウントのSetting>Personal access tokensから、任意のプロジェクト名などを入力して発行してください。FigmaURLは、FigmaのシェアボタンからURLをコピーすることが出来ます。

エクスポートされたコメント一覧

このようにエクスポートされたスプレッドシートを見ながら、

  • 課題のカテゴリ(前述した14種類)
  • 優先度(前述した3段階)
  • 視点(目的達成に関して or 個別の画面品質に関して)

を分類していきます。

スプレッドシート上での分類の様子

課題カテゴリと優先度を集計し、課題の傾向を把握できるようにします

評価のサマリー①目的達成

評価の集計が終わったら、ここから優先度の高い課題を中心に、各画面に対する評価のサマリーを作成します。こちらが最終的な成果物になります。

もっとも重要なのはこの「目的達成」のための弊害になっている課題を浮き彫りにしつつ、改善につなげることです。

たとえば、レンタカーの予約サービスのようなものを例にとると

  • 概要を理解する
  • 会員登録/ログインする
  • 予約する
  • レンタカーを受け取る

といった、ユーザーのいくつかの行動「目的」があります。

それぞれの「目的」に紐づいた画面の課題箇所について、前述の「一貫性」「操作性」などカテゴリを整理しつつ指摘します。

※ここでは具体的なアウトプットの資料は割愛させていただきます

評価のサマリー②各画面の品質

各画面の品質に課題がある場合の指摘については、上記とは個別に行います。
たとえば「行間が狭い」「余白が狭い」「アイコンの位置がずれている」など、目的達成のための大きな弊害にはなっていないが、サービスの品質を担保する上で改善した方が良さそうな見た目上の課題について指摘することも重要です。

※ここでは具体的なアウトプットの資料は割愛させていただきます

以上が、エクストーン流ヒューリスティック評価の進め方になります。

漠然とした現状に対する不満を整理・構造化しながら、関係者の課題認識を共通化することができ、改善のための道標として大いに役立つ手法だと考えています。

k6による負荷試験やってみた

エクストーンの豊田です。先日、k6 (https://k6.io/) というツールを利用してWebサービスの負荷試験を行ったので、そちらの紹介をしたいと思います。

k6について

k6はオープンソースで提供されている負荷試験ツールで、負荷試験のシナリオをJavaScriptで記述できる特徴があります。もちろん並列にリクエストを送るクライアントの数や、リクエスト数、テストの時間等も柔軟に指定することが出来ます。

import http from 'k6/http'

export default function () {
  http.get('https://test.example.com')
}

上記はテストシナリオの記述例です。GETリクエストだけでなく、POSTやPUT等の他のHTTPメソッドも容易に記述できますし、レスポンスの値を取得することも出来るため、個人的にはAPIの負荷試験は特に楽にシナリオを作成できるという印象を受けました。

負荷試験のシナリオを作る

負荷試験のシナリオを作るためには、まず負荷試験の目的を整理する必要があります。

  • 想定されている負荷に対して、正常にサービスが運用できているかどうか(ロードテスト)
  • 高負荷をかけた際に、想定外の挙動が発生していないかどうか(ストレステスト)

他にも現状のシステムがどのくらいの負荷まで耐えられるのかをテストする等もありますが、基本的には「想定した負荷に対して一定のパフォーマンスが出せるか」「想定外の負荷に対して、異常な現象が発生しないか」の2つに分かれると思います。

どちらも、まずは実際のアプリケーションのユースケースに従ったシナリオを作成する必要があります。

例えばECサイトのAPIサーバーの負荷試験を行うケースを考えましょう。買いたいものが決まっているユーザーはおそらくテキスト検索等でほしい商品の検索を行い、その結果から商品の個別ページへ遷移し、その商品をカートに入れた後に決済ページで届け先の設定や支払処理等を行うことが想定されます。これらの一連の流れを組み合わせてシナリオを作成します。

import http from 'k6/http'

export default function () {
  // 検索APIの呼び出し
  http.get('<検索用APIのURL>')
  // 商品詳細APIの呼び出し
  // できればランダムな商品を取得できるようにする
  http.get('<商品小策取得APIのURL>')
  // 商品を30%の確率でカートに入れる
  if (Math.random() < 0.3) {
    // カートに入れるAPI
    http.post('<商品をカートに入れるAPI>')
    // カートに入れた商品を50%の確率で決済する
    if (Math.random() < 0.5) {
      // 表示用にカートの中身の情報を取得
      http.get('<カートの情報を取得するAPIのURL>')
      // 届け先一覧を取得
      http.get('<保存済み住所一覧を取得するAPIのURL>')
      // 決済実行
      http.post('<決済実行APIのURL>')
    }
  }
}

k6でシナリオを記述する場合、JavaScriptでシナリオが書けるので、上記の例のように確率に基づくシナリオが容易に記述できます。他にもAPIを叩いた結果からレスポンスを抜き出して、その結果をサンプリングして次のリクエストを投げるといったことが実現できます。

リクエストの結果の集計

リクエストを行い、意図した結果が取得できているかどうかは check 関数によって確認します。下記の例ではレスポンスのステータスコードが 200 OK を返しているかどうかチェックしています。

import http from 'k6/http'

export default function () {
  const res = http.get('https://test.example.com')
  check(res, { 'is status 200' : (r) => r.status === 200 })
}

上記のテストを実行すると以下のように成功したテストの数が表示されます。

checks.........................: 100.00% ✓ 1        ✗ 0

ロードテスト時には成功しているかどうかをチェックすればよいですが、ストレステストの場合は以下の観点が発生します。

  • 正しいレスポンスを返すかどうか
  • 負荷でレスポンス時間が長くなった際に、意図したエラーが発生するかどうか

上記に関してはシナリオの check の条件を変えることで対応できます。まずは正しいレスポンスを返すかどうかのテストのまま負荷をかけ、失敗するレスポンスが現れるくらい負荷をかけたら条件を変更します。例えば一定の負荷がかかると 503 Service Unavailable を返すような設計にしている場合はその挙動が正しく動いているかどうかを確認します。

import http from 'k6/http'

export default function () {
  const res = http.get('https://test.example.com')
  // 503も成功とみなす
  check(res, { 'is status 200' : (r) => r.status === 200 || r.status === 503 })
}

このテストを実行した場合、503が返った場合も正常に処理が終わったとみなすようになるため、高負荷時の意図していない挙動が起こっているかどうかを判断することが出来ます。上記の例ではステータスコードで判断していますが、レスポンスボディ等で判断することも出来ます。

負荷試験の実行と検証

シナリオが実装が出来たら実際に実行してみましょう。ロードテストとストレステストでは設定する負荷が変わってくるので、それぞれについてどのような負荷設定をすればいいかを以下で解説します。

ロードテストの負荷設定

k6では負荷の調整はVU (並列実行数) とiteration (繰り返し実行数) で行います。JavaScriptで記述したシナリオを同時にどのくらい実行するか、また何回繰り返して実行するかを設定します。

ロードテストでは事前に想定されているユーザー数やPV数を元に並列実行数を算出します。算出の方法は以前別の記事で書いたフェルミ推定等を利用して行います。

k6のシナリオ実行結果は以下のように出力されます。

     checks.........................: 100.00% ✓ 13735      ✗ 0    
     data_received..................: 20 MB   338 kB/s
     data_sent......................: 61 MB   1.0 MB/s
     http_req_blocked...............: avg=144.28µs min=185ns       med=497ns    max=82.01ms  p(90)=730ns    p(95)=857ns   
     http_req_connecting............: avg=25.86µs  min=0s          med=0s       max=17.73ms  p(90)=0s       p(95)=0s      
     http_req_duration..............: avg=29.73ms  min=3.96ms      med=27.51ms  max=162.72ms p(90)=42.49ms  p(95)=48.48ms 
       { expected_response:true }...: avg=29.73ms  min=3.96ms      med=27.51ms  max=162.72ms p(90)=42.49ms  p(95)=48.48ms 
     http_req_failed................: 0.00%   ✓ 0          ✗ 13755
     http_req_receiving.............: avg=674.03µs min=-15166344ns med=164.38µs max=40.09ms  p(90)=1.47ms   p(95)=2.83ms  
     http_req_sending...............: avg=154.25µs min=39.82µs     med=133.05µs max=11.19ms  p(90)=237.49µs p(95)=283.59µs
     http_req_tls_handshaking.......: avg=106.05µs min=0s          med=0s       max=66.31ms  p(90)=0s       p(95)=0s      
     http_req_waiting...............: avg=28.91ms  min=3.59ms      med=26.77ms  max=160.66ms p(90)=41.31ms  p(95)=47.11ms 
     http_reqs......................: 13755   229.378763/s
     vus............................: 30      min=30       max=30 
     vus_max........................: 30      min=30       max=30

上記のテスト結果のうち、特に注目してほしいのは checks , http_req_duration , http_reqs です。

checks については先ほど述べた通り、レスポンスに意図したとおりの結果が返ってきているかどうかを表します。こちらすべてのリクエストについて正しいレスポンスが返ってきていないと想定した負荷に対して対応できないことが予想されます。

http_req_duration については、HTTPリクエストを送ってからレスポンスが返ってくるまでの時間を表します。最小値、最大値、平均値、中間値、90%の値、95%の値がそれぞれ出力されています。例えば95%の値が48.48msというのは、全リクエストのうち95%が48.48ms以内にレスポンスを返していることを表しています。

http_reqs は総リクエスト数と秒間のスループットを表します。大事なのはスループットの方で、サイトの性能の指標になります。まだまだリソースに余裕がある場合は負荷を増やすとスループットもあわせて向上しますが、この値が頭打ちになると性能の限界がきたということが分かります。

想定した負荷をかけたうえで、異常なレスポンスが返っていないこと、レスポンスの時間が許容範囲であることを確認することがロードテストの目的となります。

ストレステストの負荷設定

ストレステストでは、想定以上の負荷をかけて、異常なレスポンスが返ってこないかどうか、またどのくらいの負荷でレスポンス速度が低下するか等を確認します。

基本的にはVUの値を増やしていくことで負荷を増やしますが、ある程度長時間負荷をかけ続けた際に発生する問題も存在するため、iterationの数も増やして長時間負荷をかけ続けるように設定します。

ストレステストを行う目的としては以下のものがあげられます。

  • 想定以上の負荷により、想定していないレスポンス等を返したりしないかを調べる
  • どのくらいの負荷でレスポンス速度が低下するかを調べる
  • レスポンス速度の低下や異常なレスポンスを返した場合、ボトルネックになっているリソースがどこかを調べる

例えばストレステストの結果、一定のリクエストでレスポンス速度の大幅な低下がみられた際、その際にどのリソースが飽和状態になっているかを確認することで、リクエスト数の上昇がみられた場合の対応方法を決めることが出来ます。

また、DBやAPIサーバーのメモリ使用率やCPU使用率を確認し、リソースの使用率がどのくらいになったらサービスのレスポンスが悪くなるかを調べることが出来るため、性能監視の指標を作ることが出来ます。

結果のレポート

k6では結果の出力に関して何も指定しない場合は標準出力にテスト結果のサマリーが出力されます。それに追加して、個々のリクエストに関するレポートを合わせて出力することも可能です。それにより、例えばストレステスト時に想定しないレスポンスがあった際、具体的にどのリクエストがどのようなレスポンスを返したかということを調べることが出来ます。

ローカルにCSVやJSON形式で出力できるほか、負荷試験実行中にリアルタイムで様々なサービスに実行ログをストリーミングすることが出来ます。これにより、長時間のストレステストを行う場合はその完了を待つことなくエラーが発生したリクエスト・レスポンスの情報を調査することが出来ます。

k6がサポートしているレポーティングのサービスは公式ドキュメントに一覧が記載されています。

おわりに

この記事では負荷試験ツールとしてk6の紹介と、それを利用してロードテスト、ストレステストを行う例について紹介しました。サービスを運用するにあたって、自分たちのサービスがどのくらいのユーザーを受け入れ可能なのかを知っておくことはとても重要です。また、通常のユニットテスト等では気づけないような「入力と出力は合ってるけど、実装方法に問題がありパフォーマンスが著しく悪い」処理を事前に発見することも出来ます。

皆様、ぜひ楽しい負荷試験ライフを!

エクストーン デザイナーチームの環境紹介

エクストーン デザイナーチームの原です。
デザイナーチームからの初投稿ですので、今回はどのような環境でデザイナーが働いているかを、ハード・ソフト面を中心に紹介いたします。

早速ですが、デザイナーチームの機材をまとめると以下のようになります。

デザイナーチームで利用している機材

  • PC: Apple MacBook Pro 16-inch 2019
    • CPU: 2.6GHz 6コア intel core i7
    • GPU: AMD Radeon Pro 5500M 4 GB
    • メモリ: 32 GB 2667 MHz DDR4
  • ディスプレイ: EIZO FlexScan EV2785(2台)
  • ペンタブレット
  • ヘッドセット: Jabra Evolve 20
  • Webカメラ: Logicool C922n

デザイナーチームで利用している主なソフトウェア

  • デザイン系
    • Figma
    • Adobe Creative Cloud
      • Photoshop
      • Illustrator
      • After Effects
      • XD
    • Sketch
  • バージョン管理、開発連携系
    • Abstract
    • Zeplin
    • Invision
  • その他
    • モリサワパスポート
    • Visual Studio Code

Apple MacBook Pro 16-inch 2019

出典:Apple MacBook Pro 16-inch 2019

2023年6月現在、デザイナーチームには16インチのMacBook Proが支給されています。
動画編集などパワーを必要とする作業もあるため、GPUとメモリをアップグレードしたカスタムモデルです。
2019年まではiMacが支給されていたのですが、コロナ禍により柔軟な働き方が必要になったことと、オフィスをフリーアドレス化したことからMacBook Proへと移行しました。

基本スペック以外で金額差が出ない要素については、個人でカスタマイズが可能です。
デザイナーの中にはUSキーボードに強いこだわりを持つ人も多く、チームの約半数がUSキーボードのMacBookを使っています。

USキーボードの方がAdobeをはじめとしたデザイン系ソフトウェアのショートカットキーが使いやすいということが主な理由のようです。
個人的にもUSキーボードの方が見た目もスッキリしていてかっこいいと感じるので、自前のMac製品を買うときもUSキーボードを選択しています。

PCは3年を目処にリプレースをしており、エンジニアチームと相談しながらスペックを選定します。
ちょうど今年度末にはAppleシリコン系のMacBook Proへの移行が計画されています。 デザイナーチームが使うソフトウェアの多くはAppleシリコンへの最適化が進んでいるので、移行後はさらに作業が捗りそうです。

EIZO FlexScan EV2785

EIZO FlexScan EV2785

MacBook Proと一緒に導入されたのが、EIZO製の27インチ4Kディスプレイです。
エクストーンでは全社員にデュアルディスプレイ環境が支給されます。
多くは27インチのDELL製が支給されるのですが、デザイナーチームは贅沢に27インチのEIZO製が2枚支給されます。

大きい画面というだけで作業効率がとても高まります。また、ベゼルも狭いので、2枚を並べても違和感なく作業できます。
EIZO製ということで発色も自然ですし、長時間の作業でも目が疲れにくい印象があります。

個人的に気に入っているのは、MacBook ProとUSB Type-C一本で繋がる点です。
映像の出力と同時に、60Wの給電もできるので、MacBook Pro側に電源ケーブルが不要です。
席の移動や在宅勤務への切り替え時に、あの重くて大きなMacBook用の電源タップを持ち歩かなくて済みます!

USB Type-Aのダウンストリームも2つ付いているので、USB Type-CしかポートがないMacBook Proの拡張性も高まります。
クラムシェルモードで作業するデザイナーが多いので、ディスプレイのUSBポートにWeb会議用のカメラやヘッドセットを繋いでいます。

ペンタブレット

https://wcm-cdn.wacom.com/-/media/images/products/slides/gallery-images/intuos-pro-overview/wacom-intuos-pro-gallery-small-g1.jpg?h=640&iar=0&w=960&rev=c207c7e6dcc540f7872105192fcfeb55&la=en&hash=F5A5CFCF4B8E18C0432CE9391C8E271B

出典:Wacom Intuos Pro

デザイナーチームにはペンタブレットに強いこだわりを持っている人も多く、希望すれば支給してもらうことが可能です。
中にはマウスやトラックパッドを使わず、ほぼすべての作業をペンタブレットでこなす人もいます。
エクストーンではワコム製のIntuosシリーズを使っている人が多いです。

ヘッドセット(Jabra Evolve 20)、Webカメラ(Logicool C922n)

出典:Evolve 20

コロナ禍からエクストーンでも一気にWeb会議が増えました。
対面で行っていたデザインのプレゼンや説明も、Web会議となると勝手が異なり、2019年当初は苦労したのを覚えています。

現在は出社する機会が増えましたが、それでもWeb会議の方が多い現状です。
オフィスに出社する社員も増えたことにより、Web会議中に雑音が入るなどして、相手が聞き取りづらくないように、全社員にヘッドセットとカメラが支給されました。
ヘッドセットはノイズキャンセリング機能が優秀で、社外の方にも声が聞き取りやすいと好評です。

Figma

出典:Figma

今やデザイナーチーム、いやエクストーンの業務において必要不可欠な存在となったのがデザインツールのFigmaです。
UIデザインやプロトタイピングはもちろん、ワイヤーフレームの作成やエンジニアチームとの連携でも使用しており、インフラと言っても過言ではないかもしれません。

エクストーンでは2021年の後半ごろから密かに使われ始め、2022年に爆発的に広がりました。
Figma導入前と後では、働き方が大きく変わったと言えるかもしれません。
それまでは、後述のSketchを使ってのデザインが多かったのですが、チーム体制で制作を進めるエクストーンとしては、同時編集や共有の難しさが長年の課題でした。
そんななか設計、デザイン、プロトタイピング、社外レビュー、実装者へのリソース提供が一貫して行えるFigmaの登場は衝撃的でした。

今までにないコラボレーション機能の登場で、デザイン途中のものや作業手順をチームメンバーに見られてしまうことに懸念を示す人もいましたが、社内勉強会などを通じて徐々に広まっていきました。
また、導入当初はオートレイアウトなどの操作に戸惑う人もいましたが、デザイナーチーム内でお互いのファイルを参照し合うなどして理解を深めていきました。
社内Slackでは良いプラグインを見つけると紹介しあうチャンネルも存在します。
エクストーンでは新しい技術やツールを積極的に使い、内部に発信する人が多くいます。案件内でも新しい技術にチャレンジしやすい風土がある気がします。

Adobe Creative Cloud

出典:Adobe Creative Cloud

デザインチームではメンバー全員がAdobe Creative Cloudを契約しており、Adobe製品の全機能が使える状態です。 よく使うのはPhotoshop、Illustrator、After Effects、XDあたりでしょうか。 PremiereやAuditionなんかも案件によっては使うこともあります。 しかし、Figmaの導入以後はだんだんとAdobe製品を起動する機会も減ってきているような気がします。 (FigmaもAdobe製品といえばそうかもしれませんが)

後述のSketchが導入される以前は、UIデザインをPhotoshopで行っていた時代もありました。懐かしいですが、もう戻れません。

そういえば、AdobeのデザインソフトがCSの買い切り型からCCのサブスクリプション型になってもう10年になるんですね。

Sketch

出典:Sketch

Figma導入前にUIデザインツールとして利用していたのがSketchです。 軽快な操作感とSymbolの概念などで、UIデザインのフローが劇的に変わったことを覚えています。 デザイナーチームでは2015年あたりまでWindowsを利用していたのですが、Sketchの導入をきっかけにMacへの移行が行われました。

多くのバージョンアップを経て、機能も追加されてより便利にはなったのですが、近年は動作もかなり重たくなった印象です。 コラボレーション機能やプロトタイピング機能など、Figmaと似たような機能アップデートもありましたが、業界全体の流れや使い勝手の面から、現在はメインツールとしては扱っていません。 運用案件などでFigmaへの移行が完了していない場合に使用しています。

Abstract

出典:Abstract

Git感覚でSketchデータを管理するためのサービスです。
Sketch導入当初から、デザイナー間での同時編集ができないという問題があったのですが、Abstractの登場でそれが解決しました。
エクストーンでは2018年頃からAbstractを使用しています。
GitのようにSketchファイルのブランチを作成し、デザインを修正後にマージするといった流れで運用します。
こちらもFigmaの登場後は起動の機会が減りました。

Zeplin、Invision

出典:Zeplin

Sketchで作成したデザインデータを外部の開発会社の方に提供する際にZeplinを、クライアントの方にレビューを頂く際にInvisonを利用しています。
どちらもFigmaの登場後に利用頻度が落ちましたが、案件によってはまだまだ利用中です。

今後、Sketch中心の開発環境からFigmaへの移行に際して、エクストーン内でどのようなことを行ったのかなども記事にできたらと考えています。

モリサワパスポート

出典:MORISAWA PASSPORT

デザインチーム全員にモリサワパスポートのライセンスが提供されています。
メインビジュアルでこだわりのキャッチコピーなどを入れたい時には、モリサワの高品質なフォントでキメます。
個人的に好きなフォントは「UD新ゴ」 と「リュウミン」です。

Visual Studio Code

出典:開発モード: デザインから開発へ | Figma

Webの案件でマークアップまで行うデザイナーはテキストエディターを使う機会も多いです。
こちらは指定などは特になく、各々好きなエディターを使っています。
デザイナーチームで人気なのは、Visual Studio CodeとSublime Textのようです。

Visual Studio Codeは6月末に発表されたプラグインを入れることで、FigmaのDevモードを参照できるようになりました。
実際使ってみたのですが、とても便利でマークアップが捗りました。
このあたりも、後日デザイナー視点で記事にしたいと考えています。

おわりに

以上、エクストーンのデザイナーチームが主に扱っている機材とソフトウェアの紹介でした。
紹介したもの以外にも、ハード・ソフト関係なく、デザイン業務に必要なものは、会社に申請することで支給してもらうことが可能です。

全体的に簡潔な紹介になってしまいましたが、エクストーンデザインチームの歴史とデザインフローが垣間見えたかと思います。
デザイナーの初投稿としては少々異質な感じになってしまったかもしれませんが、興味を持っていただけたら幸いです。
今後はよりデザイナー視点の記事も増やしていきたいと考えています。

Figmaでワイヤーフレームを書く様々なメリット

エクストーンの松本です。 ワイヤーフレームをどのツールを使って作るかについては、多様な意見があるところかと思います。昔はオフィス系ツール以外の選択肢があまりなかったように思いますが、最近ではデザイン系ツールやオンラインのコラボレーションツールなどが続々と登場し、かなり選択肢が増えてきました。

エクストーンでは以前はパワーポイントを主に使用していましたが、最近はFigmaを使うケースが増えてきました。今回はワイヤーフレームを作成する上で抑えるべきポイントと合わせて、Figmaを利用するメリットについて書いてみたいと思います。

ワイヤーフレームに求められること

まず大前提として、ワイヤーフレームは、ディレクター、デザイナー、エンジニア、QA担当者、クライアント、パートナー企業など、プロジェクトに関わるほぼ全員が目にする資料です。この資料を起点として、ビジュアルデザインやプログラム開発、テスト仕様書など、様々な成果物へと発展していくので、その役割はとても重要です。

「ワイヤーフレームを書くツール」を考える上で、重要なポイントは様々ありますが、特に重要なのは、以下の3点に集約できるのではないかと思います。

  • 関係者全員が資料にアクセスしやすいこと
  • 分かりやすい資料を作るための描画ツールが揃っていること
  • 資料がメンテナンスしやすいこと

他にも細かなポイントはあるかと思いますが、まずは上記のポイントに絞ってFigmaの特徴について書いていきたいと思います。

Figmaでワイヤーフレームを書くメリット〜基本編〜

関係者全員が資料にアクセスしやすいこと

ワイヤーフレームは多くの関係者が参照する資料なので、なるべく特殊なツールや環境を必要とせず、誰もが簡単に開けることが理想的です。

Figmaはデスクトップアプリ・モバイルアプリ・WEBアプリと、3通りのアクセス方法があります。前者2アプリについてはインストールをして利用する形になりますが、WEBアプリはブラウザさえあればアクセスできるため、アクセスのハードルはとても低いです。 Figmaのデザインファイルへのアクセス権限は、いつでも更新できるので、プロジェクトへのメンバーの参加、退出が発生した際も、アクセス権のコントロールが簡単に行える点も、オンラインベースのツールの利点と言えます。

クラウドベースのツールであるがゆえオフラインでアクセスできない点はデメリットかもしれませんが、ほぼ一日中オンライン接続している筆者のワークスタイルでは、この点を不便と感じたことはありません。

分かりやすい資料を作るための描画ツールが揃っていること

ワイヤーフレームはあくまで「設計図」なのでデザイン的な要素は不要ですが、画面を構成する要素はきちんと抜け漏れなく定義されている必要があります。また、状態変化に伴った要素の出し分けに関する定義や、画面同士の関係を示した遷移図・フローチャートなど、仕様が立体的かつ網羅的に定義されていると、より分かりやすい資料になります。

これらの情報を資料に落としていくには、図形やテキストブロック、コネクタ、表などの描画ツールを組み合わせて表現していきますが、Figmaはそもそもがデザインツールなので、描画周りのツールについて困ることはほとんどありません。 むしろ、コンポーネントやオートレイアウト、バリアントなどの機能を使いこなせるようになると、圧倒的に効率良く、時短でワイヤーフレームを書くこともできるようになります。このあたりの機能は、ドキュメント作成系のツールにはない利点です。 表現をする内容によっては、デフォルトの機能だけでは足りないこともありますが、豊富なプラグインを活用することで大抵のケースには対応が可能です。

非デザイナーにとっては、少々ラーニングコストはかかることも

デザインツールの扱いに慣れたデザイナーと比べて、非デザイナーの方々はもしかすると使い慣れるまで少々の期間が必要になるかもしれません。かくいう筆者もその一人ですが、使い慣れて来ると作業のスピードと効率が圧倒的に変わったので、チャレンジして損はないように思います。

資料がメンテナンスしやすいこと

実はワイヤーフレームを作るツールの機能の中でかなり重要なのが、「資料内のテキストの一括検索・置換ができること」です。 エクストーンでは、仕様を定義する資料はなるべく増やさずに、できるだけ一元管理するよう心がけています。多くのドキュメントに情報が分散してしまうと、探すことが大変だったり、資料のメンテナンス性が下がってしまうためです。

例えば、プロジェクトの途中で用語や文言ルールが変わったとします。 そうした際に、ドキュメントが一箇所で管理されていると、資料内を一括検索して変更が必要な箇所を網羅的に把握し、変更に対応ができるのでミニマムの手数で対応ができます。逆にそれができないと、複数の資料をチェックし、それぞれを修正をしなければならず、時間がかかるだけでなくミスも起きやすくなります。

実は最近までFigmaは公式の機能として「一括検索・置換」を提供しておらず、その点がネックとなり、一定以上の規模のプロジェクトではFigmaをワイヤーフレーム作成のツールとしては利用しない傾向がありました。 しかし、2022年10月のアップデートでFigmaが公式の機能として「検索・置換」をリリースし、これによりファイル内のフレーム名だけでなく、テキストやコンポーネントなども含めてファイル内を一括して検索ができるようになり、一気にメンテナンスがしやすくなりました。このタイミングから、弊社内の様々なプロジェクトでFigmaをビジュアル制作だけでなく、ワイヤーフレーム作るツールとして活用する機会が増えたように思います。

Figmaでワイヤーフレームを書くメリット〜応用編〜

複数のメンバーで共同作業ができる

Figmaはコラボレーションを前提として作られたデザインツールなので、チームのコラボレーションを促進するための様々な機能が提供されています。

オフラインのツールでは基本的に一人づつが作業を行い、どこかで統合するような方法が多かったですが、Figmaを利用すると、複数のメンバーで同時に共同作業ができます。そのため、特に集中的にディスカッションをしたいパートを検討する際などは、関係者が集まってWEB会議をしながら作業をするなど、スピーディーで効率的に共同作業を行えるようになりました。

作業の途中段階を見られたくないことも?

コラボレーション上のメリットは数多くある一方で「作業の途中段階の状態が、他のメンバーやクライアントに実況中継されてしまうことに抵抗がある」という声もたまに聞こえて来ます。このあたりの塩梅については、お互いが空気を察して配慮をするか、あるいはどうしても気になってしまう場合は、プライベートなデザインファイルで作業を行い、一定段階まで作ったら共有スペースに持ち込む、などの方法も有効かもしれません。

プロトタイプが簡単に作れる

Figmaには使いやすいプロトタイプ作成機能もあります。ビジュアルデザインからプロトタイプを作成し、完成イメージを掴むだけでなく、ワイヤーフレームの段階でも活用できます。ワイヤーフレームを基にプロトタイプを作成することで、全体的な画面遷移や遷移時のインタラクションの検討が容易になります。

圧倒的に広いキャンバス

縦横のサイズに制限があるツールと比べて、Figmaは圧倒的に広いキャンバスを活用して資料を作ることができます。縦長の画面や複数の画面を並べて検討する際に、広いキャンバスのメリットが発揮されます。 ドキュメント作成系ツールでは、紙のページ単位で制約があることが多く、画面の定義が複数のページにまたがる場合などに工夫が必要でしたが、Figmaではそのような問題はありません。

まとめ

ワイヤーフレームを作成するツールは様々ありますが、この記事で触れたようにFigmaには様々な利点があります。 一方で、Figmaはまだ新しいツールであるため、プロジェクトの中に使い慣れていないメンバーやパートナーがいる場合もあるかもしれません。そうした場合は、ツールがプロジェクトにマッチするかをきちんと見定めた上で使い始めた方が良いかもしれません。

ワイヤーフレームは、前述の通り多くの関係者が参照する資料なので、プロジェクトを構成するメンバーやコミュニケーション方法をきちんと見極めた上で、ツール選定をされると良いと思います。

Xtoneでのスマホアプリ開発時の技術選定

エクストーンの大久保です。以前の記事では主にWeb開発の技術スタックについて、豊田の方から話をさせていただきましたが、今回はスマートフォン向けのネイティブアプリ開発時の技術スタックや、選定理由について私の方から紹介いたします。

早速ですが、エクストーンにおけるスマホアプリ開発時の技術スタックは以下になります。

アプリ開発で主に利用している技術スタック

  • iOS
    • 言語: Swift
    • ライブラリ: Alamofire, Realm, Lottie, R.swift, LicensePlist
    • パッケージ管理: Swift Package Manager, CocoaPods, Carthage
  • Android
    • 言語: Kotlin
    • ライブラリ: Android Jetpack(LiveData, ViewModel, Navigation, etc.), Retrofit, OkHttp, Realm, Lottie, Koin
    • パッケージ管理(ビルドツール): Gradle
  • 共通
    • クロスプラットフォーム開発: Flutter, Unity
    • mBaaS: Firebase
    • CI/CD: Bitrise
    • デザイン: Figma, Zeplin

Swift / Kotlin

まずはアプリ開発のベースとなる言語やフレームワークですが、弊社では基本的にSwiftとKotlinを使用してネイティブアプリとして作ることが大半です。例外としては、ゲーム的なUIや演出が必要な場合はUnityを、クロスプラットフォーム開発がマッチするようなプロジェクトでは、Flutterを選択することがあります。
弊社では比較的に早くにObjective-CからSWift、JavaからKotlinに乗り換えてきました。特にSwiftの方は、バージョン1が出た直後から利用開始した結果、 Swift3でシンタックスが大きく変更されてしまい、移行に苦労したりもしました。しかし、早めにキャッチアップすることで、言語のコンセプトや変更された理由などにも理解が深まり、結果的にはメリットの方が多かったと考えています。
目に見える効果としては、Null Safetyの機能により、クラッシュが減ったことが挙げられます。

Flutter

前述したように、最近はFlutterの利用も検討段階ではよく挙がるようになってきています。
アプリの開発を行う際には基本的にiOS/Androidの両OS向けに作成するので、であれば1つのソースコードで複数のOS向けの開発が行えることは単純にメリットです。その他の利点としては、OS間の実装やそれに伴う挙動が一致することがあるかと思います。OSごとの流儀やその基になったコンセプトは尊重すべきだとは思いますが、OSによって挙動が違うと、プロジェクト内ではたびたびそれが混乱のもとになります。あえてやっている場合はよいのですが、大抵はiOS、Androidの実装担当者の認識のズレやコミュニケーション不足から、結果的に実装差分が生まれてしまっていることが大半な印象です。
Flutterを利用する場合は、チーム構成にもよりますが、弊社のエンジニアチームの規模だと両OSの担当者が力を合わせて1つのアプリを作成して行くことになるため、このギャップを埋めることができると感じています。
一方で、当然Flutterも万能ではなく、苦手な分野も多々あります。特にOSの機能をフル活用するようなアプリや細やかなチューニングが必要となるアプリでは向いていません。もちろん、必要な部分だけネイティブで書き、共通化できる部分はFlutterで実装するという組み合わせもありですが、その比重がネイティブ側に偏っていけばいくほど、Flutterを利用するメリットが失われていきます。
このように採用の判断は慎重に行う必要がありますが、アプリがOSの機能と密に連携しない場合は、十分選択肢になりえると状況になってきていると思いますので、今後も積極的に採用していきたいと考えています。

自動テスト

自動テストの導入具合については、正直なところプロジェクトを開始した時期やメンバーによってバラバラな印象です。特定の日時で発火するような機能など、実際に試験環境を用意しにくいケースについては、さすがにテストが書かれていることが多いですが、必要十分とは言い難い状況です。
必要なところにだけテストを書いている、という言い方もできるかもしれません。
最近のプロジェクトではMVPやMVVMなどテストを比較的行いやすいアーキテクチャを採用することが多いこともあって、古いプロジェクトに比べると比較的テストが充実しています。この辺は、そもそもテスト行うためにそういったアーキテクチャを採用していることもあって、卵と鶏な感じですが、やはり新しいプロジェクトのほうがテストが書かれている割合は多そうです。
またそれらの多くはユニットテストで、UIテストについては占める割合がさらに低くなります。
UIテストが相対的に少ないこと自体は、テストピラミッドの考え方には基づいているので、問題はないのですが、機会があればアプリでUIテストをがっつりやることも挑戦していきたいとは考えています(だって夢がありますよね?)。

CI/CD

CI/CDはBitriseを利用しています。テストは先に書いたとおり十分だとは思っていませんが、テストが存在するプロジェクトであればCI上でプルリクエスト作成時やマージされるタイミングで実行して、品質の担保に寄与されています。
その他では主に開発中のアプリの配布の利用されています。Androidの場合はFirebase App Distributionを、iOSの場合はTestFlightを用いて配布を行うことが多いです。
一方で、アプリストアへのリリースの自動化は、ほとんど行われていません。これは受託開発ではクライアント側でリリース作業を行っていただくことが多く、弊社側でリリースまで行うことが稀だからです。

パッケージ管理

最後に基本的にiOSのみの話になりますが、パッケージ管理の話です。CI/CDの項でも書きましたが、弊社は受託開発を基本としているので、自身がストアへのリリースを行うことは少なく、最終的なビルドもクライアント側で行うことが多いです。クライアント側にiOS開発に詳しい方がいるとは限らないので、ビルドを行い、アプリをストアへアップするまでの作業を減らすことが重要となります。現状でも、CocoaPodsで行うライブラリのインストールを事前に済ませるなどの工夫を行っています。
iOSでは近年Xcodeと統合されたSwift Package Managerが登場しました。これを利用するとXcode外でのビルド前の準備が必要なく、プロジェクトを開いた際に依存する外部ライブラリが自動取得されるので、クライアントへプロジェクトを渡す際の手間が省けたり作業ミスが減ることが期待されます。
現在のところ、フルでSwift Package Managerに移行したプロジェクトはまだないので、その効果の程を実感できていないですが、今後積極的に移行していきたいと考えています。

おわりに

いかがだったでしょうか。
本当はWeb側の技術スタックの記事が公開されてから、すぐにこの記事も公開できればよかったのですが、かなり間が空いてしまいました。各項目を掘り下げた話はできていませんが、読んでいただいている方の何かの参考になれば幸いです。
今はまだWeb開発の記事が多いですが、今後はアプリ開発の記事も増やしていきたいと考えています。

Firebase Authenticationを用いた「やってはいけない」システム設計の話

エクストーンの豊田です。先日、エクストーン社内で技術勉強会があり、そちらでFirebase Authenticationを利用してWebサービスを設計・運用した際に困った話をさせていただいたので、こちらでも紹介させていただきたいと思います。

Firebase Authentication

FirebaseはGoogleが提供しているモバイル・Webアプリケーション向けのプラットフォームで、認証やストレージ、関数実行等の機能を提供します。今回はFirebaseが提供する認証サービスであるAuthenticationについてお話しします。

Firebase Authenticationはユーザーの管理や認証を行うサービスで、メールアドレス・パスワードによる認証の他に、同じユーザーに対してGoogleアカウントやApple IDを利用した認証を紐づける等が可能です。ユーザーの管理自体をFirebase側で行うため、認証のための情報を開発するサービス側で保持しなくてもよくてFirebaseに任せることが出来るというのが設計上の最大のメリットです。

また、Webやアプリ等でFirebaseのログインを行うUIを提供するライブラリもあるため、これらを組み合わせることで認証の仕組みを少ない開発工数で実装することができます。

やってはいけない設計の話

Firebase Authenticationを利用して認証を行う際に、ちゃんと考慮せずに設計してしまうと後々の運用でトラブルになるケースがあるので、いくつか紹介したいと思います。

Case1. ユーザーアカウントを無条件に信頼する

Firebase AuthenticationではWebブラウザで実行するクライアント側のライブラリからユーザーアカウントを作成することが出来ます。FirebaseにおけるAPI Keyは機密情報ではないため、 curl コマンド等を利用することで直接実行してアカウントを作成することが出来ます。

「ログインしないと見られない情報」「限られたユーザーしかアカウントを作ることが出来ない」というような要件がある場合、Firebase Authenticationで作成されたユーザーというものは無条件に信頼することはできません。

この場合、以下のような設計を追加することで上記の要件を満たすシステムを実現できます。

  • 社内システム等、アカウントに利用されるメールアドレスのドメインが限られている場合、メールアドレスのドメインの検証を行う
  • カスタムクレームの設定を行う。サーバー側でのみ設定可能な情報を付与することで、その情報をもとにアカウントの検証を行う

必要なのはクライアント側で実行するユーザー作成APIで作成・更新できない情報に基づいたアカウント検証です。

Case2. Firebaseが提供するコンソールだけで実サービスの運用を行う

Firebaseでは利用しやすいようにWeb上でのコンソールがあり、Authenticationの場合ですとメールアドレスからユーザーの検索を行うこと等が出来ます。ただし提供されている機能が限定的で、実際にこのコンソールのみを利用して実際のサービスの運用を行うと困るケースがいくつか存在します。

Firebaseのユーザーを検索する際、コンソールから問い合わせの条件として利用できるのはFirebaseのUID、メールアドレス、電話番号の3つです。一番困るケースとして、SNSを利用したログインを行っているユーザーで、メールアドレスや電話番号の情報をFirebase側で保持していないケースが上げられます。例えばTwitterを利用したログインを行っている場合、Twitterアカウント情報が分かってもそれを利用してFirebaseのユーザーを検索することはコンソール上からは不可能です。

Firebase Authenticationのコンソール。出来ることは思ったより少ない

Firebase Admin SDKを利用すればAPI経由でFirebaseのユーザーをUID、メールアドレス、電話番号に加えてSNSのユーザーIDで検索することが出来ます。そのため、運用等を考えるならばユーザーをちゃんと追跡できる仕組みを構築する必要があり、SNSによるログインを許容する場合はFirebaseが提供するコンソールだけではユーザーが検索できない可能性があることを考慮する必要があります。

それに加えて、認証時に利用できるSNSにおいてユーザーIDを取得する方法をかならず確認しておく必要があります。Twitterの場合はユーザーIDの取得方法が結構面倒(APIを利用するか、ユーザーのページのソースコードから検索する等、どちらもいつまでその方法が利用できるか分からないという恐怖がありますw)なので、そのあたりも採用するかどうかの検討材料になります。

Case3. メールアドレスの検証をしない

Firebaseのパスワード認証ではユーザー名にメールアドレスを利用します。ただしこのメールアドレスが実際に有効なメールアドレスかどうかと言うことをログイン時に検証はしていません。そのため、疎通確認を行っていないメールアドレスではログインできないようにする、という処理はFirebase側で実現することは出来ません。

メールアドレスがユーザーの識別子として重要なサービスである場合(例えば登録しているメールアドレスにメールを送信する機能がある場合など)、攻撃したい対象のメールアドレスでアカウントを作ることで、サービス経由で大量のメールをそのメールアドレスに送ることが出来ます。

Firebase Authenticationではメールアドレスの検証で、Firebaseから実際にメールを送信し、そこに含まれるURLにアクセスすることで、そのアカウントを検証済み(email_verified)にすることが出来ます。

サービス側が検証の済んでないユーザーに対して機能を提供しないように適切に実装を行う必要があります。具体的には、Firebaseのユーザーの属性に email_verified という値が存在するため、この値が true であるかどうかのチェックを逐一行うようにします。メールアドレスの検証はFirebaseの機能でも行えますし、自前でメールアドレス検証の仕組みを実装したうえでFirebase Admin SDKを介して email_verified を更新することも出来ます。

また、Case1で言及したカスタムクレームについて検証を行いたい場合も同じタイミングで行うとよいかと思います。Firebaseから取得できる情報に基づき、サービス側で適切に有効なユーザーかどうか、有効でないユーザーからのアクセスの場合はどういうフローを実行するか、等を考慮する必要があります。

// ユーザーのemail_verifiedを取得する
const { initializeApp } = require('firebase-admin/app');
const { getAuth } = require('firebase-admin/auth');

const firebase_user_id = 'Firebase User ID'

getAuth().getUser(firebase_user_id).then((user) => {
    // emailが検証済みならtrueを返す
    console.log(user.emailVerified)
});

Case4. ユーザーからの問い合わせに対して本人確認をしない

Case1, Case3と近い話なのですが、Firebase Admin SDKを利用した管理画面を構築できているサービスにおいては、かなり柔軟な対応を行うことが出来ます。例えば「ログインできなくなりました」みたいな問い合わせに対して、メールアドレス・パスワードの再設定やSNSアカウントの紐づけ等を行うことで対応する等も可能となっています。

この際、メールアドレスやSNSアカウントの設定に関しては特に本人確認を行うことなく、任意のメールアドレスやSNSのユーザーIDを設定することが出来るため、もし問い合わせを行った人がアカウント所有者と別の人の場合、問い合わせ経由でアカウントの乗っ取りを行うことが出来てしまいます。

開発の設計とは異なるのですが、必ず問い合わせに対して対応前に本人確認を行うようにしましょう。メールアドレスでログインしているユーザーについてはメールが届くことを確認する(GoogleやApple IDについても同様の方法で確認を行えます)、Twitterアカウントの場合はDMを送信するなど、採用しているログイン方法ごとに本人確認の手段を事前に整理しておくといいと思います。

おわりに

Firebase Authenticationは認証サーバーを自前で構築しなくても手軽にサービスに認証の仕組みを追加できる便利なサービスです。一方でクライアント側から直接APIをリクエストするという設計上、ちゃんと仕組みを理解して構築しないとセキュリティ的な問題が生じます。

また、長期運用を考慮するとFirebaseが提供する管理画面だけでは機能が不足していて、ユーザーのトラッキングが不可能だったり、認証情報のアップデートができないという問題があります。この辺りを理解したうえでFirebaseを採用するのかどうか、採用する場合上記の問題をどのように解決するのかをちゃんと考えるようにするといいかと思います。

インターネット老人が泣いた HTTP/3 のはなし - RubyKaigi2023 詳報

エクストーンの金です。RubyKaigi2023 では多くの注目トピックスがありましたが、ここでは HTTP/3 のはなしを紹介します。

Unleashing the Power of Asynchronous HTTP with Ruby

というタイトルで、HTTP をめぐる33年の歴史と Ruby における HTTP/3 対応の紹介がありました。

rubykaigi.org

地味な題材ですが、Samuel Williams 氏によるすばらしいセッションでした。

登壇して HTTP の歴史を解説する Samuel 氏 - 個人的には RubyKaigi2023 でいちばん感銘を受けたセッションでした

HTTPの誕生と歴史

いま日常的に使われている HTTP は1990年に生まれました。 世の中でようやく Windows3.0 が発売された年です。 (筆者はまだ Windows すら知らず、MS-DOS を使っていました)

最初の HTTP は HTTP/0.9 というバージョンのシングルメソッドであり、扱えるメディアもテキストのみでした。いまから考えると信じられないほどシンプルで低機能です。

その後以下のような変遷を遂げます。

  • HTTP/0.9
    • GET のみ、扱えるメディアはテキストのみ
    • 1コネクションにつき1リクエストのみ
    • エラー検知もなし
  • HTTP/1.0
    • PUT, POST, DELETE などがサポートされマルチメソッド化
    • ステータスコードをサポート
    • 画像などMIMEコンテントをサポート
    • リクエスト/レスポンスヘッダをサポート
  • HTTP/1.1 (1999)
    • コネクションの永続化によりマルチリクエスト対応
    • Content-Length などもサポート

HTTP/1.1 の時点で現在に通じる HTTP の基礎形が固まったと言えます。 いまでも数々の Webサイト、Webアプリケーション が HTTP/1.1 を前提に設計・構築されています。

いやしかし、この時点でなつかしさがあふれます。

HTTP とそれを元にした WWW (World Wide Web) の世界は CERN (セルン : 欧州原子核研究機構) で生まれました。いま CERN と聞くと、ゲームやアニメでおなじみの『シュタインズ・ゲート』に登場する謎の組織を思い浮かべる人の方が多いかもしれません。しかし現実世界の CERN は HTTP と Web の発祥としてわたしたちの日常に深くかかわっています。

筆者も学生時代の計算機センターではじめて UNIX とインターネット *1 の世界に触れて、まだ数えるほどしかなかった *2 Webサイトを眺めたり、その後Webブラウザとして人気になった NCSA Mosaic をワークステーション上でコンパイルして動かしていました。*3

21世紀の HTTP へ

HTTP は本来シンプルに、かつ富豪的に、リクエストごとに通信してデータを取得するだけプロトコルでした。 しかし、シンプルさゆえにネットワークアプリケーションの基盤になってしまい、現代的な機能や動作を求められるようになります。

その後以下のような変遷を遂げます。

  • HTTP/2 (2015)
    • リクエストごとのリソース転送を多重化
    • ヘッダ圧縮

HTTP/2 は Google が Chrome で独自に拡張していた SPDY が後追いで標準化されたものですが、Webページやアプリケーションにおいて必要となった多重リクエスト *4 を意識して拡張されています。

これ自体はすばらしい進化だったのですが、こういった多重通信をするリクエストが貧弱な通信環境で行われると十分な結果が得られないという新しい弱点も認識されました。*5

こうした弱点を解消する最新形が HTTP/3 です。

  • HTTP/3 (2020)
    • 信頼性の低いネットワークでの動作向上
    • ストリームコントロール、TLS などのレイヤを UDP の QUIC でドライブ

HTTP/3 はトランスポート層として TCP でなく UDP を使うQUICをベースにしており、これにより信頼性の低いネットワークでも十分な動作を得られるように考えられています。*6

これまでは TCP ベースだったので、一連の通信レイヤのどこかで通信断などがあると後続の処理がすべて待たされてしまうことがあったのですが、通信断が起きたリクエストやレイヤ以外は非同期に進行できるようになりました。

Async::HTTP

こうして HTTP/3 は生まれましたが、Ruby においては HTTP/2 以降をサポートしているアダプタがほとんどありませんでした。 なぜなら、HTTP/3 をサポートするためには多重化モデルが必要であり、その点がハードルであったためです。

しかしようやく Async::HTTP が登場し、Ruby も HTTP における33年の歴史を受け止めました。

github.com

セッションでデモされたコードには、わずか10行の実装で HTTP/3 への対応ができていました。しかしここには「33年ぶんの蓄積」が入っていると強調されました。 おおざっぱに言ってしまうと、「node.js のような非同期実行を前提とした記述ができるようになった」と言えばイメージが伝わるでしょうか?  この Async::HTTP によって、共有インスタンスやファンアウト同時実行などが実現されます。

個人的には、この実装が HTTP::Async ではなく、Async::HTTP であるのは大きな意味があるように思います。「最初に非同期の Async という概念と動作があり、それをベースにドライブされる HTTP」という考え方を感じました。

おわりに

かくして Ruby においても HTTP/3 の時代がやってきたわけですが、Samuel 氏の発表は内容もすばらしく、話の構成も参加者を引き込む仕掛け満載で、しかもとても平易で聞きやすい英語でした。

アフターフォローとして本セッションに関連した資料・サンプルコードなども公開されていますので、興味を持った方はぜひ HTTP/3 の世界をのぞいてみてください。

github.com

github.com

*1:世間的にはまだインターネットという言葉も存在も普及しておらず、ネットと言えばパソコン通信という認識だった

*2:国内で新しく立ち上がったWebサイトを網羅的に紹介する "What's New in Japan" というサイトが成立するほどでした

*3:Netscape Navigator がブームになって界隈を席捲するのも後のはなしで、Googleにいたっては起業すらされていませんでした

*4:ひとつのコンテンツを取得するために画像、CSSなど複数のリクエストが必要になる

*5:単一のHTTPリクエストとしても暗号化を行うTLSなど、複数のセッションが必要となる

*6:移動体通信などにおいては、通信経路変更などによる接続回復が重要