Wiz テックブログ

Wizは、最新のIoTやICTサービスをお客様に届ける「ITの総合商社」です。

イージングでスムーズなアニメーションを作ろう

こんにちは、フロントエンドの高野です。
皆さんはアニメーションは好きですか?
私は大好きです。

今日はド派手なアニメーションからUIのモーションまで、幅広く応用できるイージングについての記事を執筆しようと思います。

イージングとは?

アニメーションの速度に緩急をつけることで、物体の動きを滑らかに見せることをイージングと言います。 実際に動きをみてみましょう。

See the Pen easing-demo by iricocco3 (@iricocco3) on CodePen.

青い要素は常に動きの緩急が変わりませんが、灰色の要素は緩急があるので滑らかに見えます。

現実の物理法則に近い形でアニメーションのイージングを設定することで、よりリアルで直感的な動きとなります。
通常、上記青色の要素のような常に一定の速度を保つ動き、というのは現実世界ではレアなケースです。

こちらのイージングに関するUIアニメーション考察の記事が非常に面白かったので、
興味のある方は是非合わせてご確認ください。 note.com

CSSで実装できるイージング

イージングを語る上で欠かせない要素はベジェ曲線です。
...ですが、数学的な部分を正確に説明できる自信がないので、 ベジェ曲線という曲線でアニメーションの緩急を調整します、と軽い説明に留めて起き、参照のみを紹介します! 逃(・_・;

ja.javascript.info

CSSのアニメーションでイージングを設定するには、
animation-timing-function プロパティで指定します。
developer.mozilla.org

ここで指定できるいくつかの値は3次ベジェ曲線を指定するプロパティの糖衣構文になっています。 (cubic-bezier)

  • ease // cubic-bezier(0.25, 0.1, 0.25, 1.0)
  • ease-in // cubic-bezier(0.42, 0, 1.0, 1.0)
  • ease-out // cubic-bezier(0, 0, 0.58, 1.0)
  • ease-in-out // cubic-bezier(0.42, 0, 0.58, 1.0)
  • linear // cubic-bezier(0.0, 0.0, 1.0, 1.0)

それぞれの動きのサンプルと、グラフを用意しました。

See the Pen css-timing-demo by iricocco3 (@iricocco3) on CodePen.

f:id:iricocco:20210330164516p:plain
ease // cubic-bezier(.25,.1,.22,1)

easeは始まりは早く、終わりは遅いですね。

f:id:iricocco:20210330165310p:plain
ease-in // cubic-bezier(.42,0,1,1)

ease-inは始まりは遅く、終わりはゆっくり追い上げます。

f:id:iricocco:20210331095515p:plain
ease-out // cubic-bezier(0,0,.58,1)

ease-outゆっくり加速し、ゆっくり減速します。

f:id:iricocco:20210331095720p:plain
ease-in-out // cubic-bezier(.42,.01,.58,1)

ease-in-outease-inease-outの組み合わせです。

f:id:iricocco:20210330165537p:plain
linear // cubic-bezier(0,0,1,1)

linearは名前の通り直線的です。増加量が常に同じです。

上記のグラフは下記のベジェ曲線ジェネレーターのサイトで作成しました。 実際に手で動かしてシミュレートもできる優れものです。

cubic-bezier.com

anime.jsで実装できるイージング

CSS標準のもの以外にも、アニメーション系ライブラリを使用すればものが跳ねる動きやがたつく動きなど、色々なイージングを簡単に実現することができます。
次は、anime.jsで実装できるイージングを一部紹介していきます。

Robert Penner's Easing Functions

よく使うEasingのサンプルをまとめた素敵なサイトがあります。 便利なチートシートもあるので紹介します。

easings.net

f:id:iricocco:20210331110915p:plain
easing cheet sheet

このように色々なイージングを一括でサンプル付きで確認することができます。 ここで出てくるグラフの細かい計算式を確認したい場合は、GitHubにコードが載っているのですぐに確認できます。

github.com

なお、anime.jsでは上記のイージングを元にイージングの設定を調節することが可能です。

animejs.com

spring

重さ/剛性/減衰/速度などを指定して、物質の跳ねる動きをシミュレートできます。

See the Pen VwPmEJX by iricocco3 (@iricocco3) on CodePen.

最後に

物質の動きを完璧にシミュレートしようとすると物理学・数学が絡んで難しい!という印象があるかもしれませんが、特にそれらに詳しくなくても イージングを簡単に実装できる糖衣構文やライブラリの機能、チートシート・ジェネレーターが用意されていましたね。
是非みなさんもお気軽にイージングを楽しんでみましょう!

Wizではエンジニアを募集中です。

興味のある方は是非覗いてみてください!↓

careers.012grp.co.jp

コードレビュー会はじめました。

こんにちは。フロントエンドの仲本です。
3月からフロントエンドの一部チームでコードレビュー会をはじめました。
こちらの記事では、コードレビュー会に至った経緯、その内容、感想をこちらでご紹介したいと思います!

コードレビュー会の目的

最初入社したての頃は、基本的に全てのコードに対してレビューしていただいていたのですが、1人で業務を任せられるようになるとレビューをしていただく機会が徐々に減りました。

それにより以下のような不安要素を感じました。

  • コードを書き正しく動いたらそれが正になる。なのでそれ以外のベストプラクティスが思いつきづらい
  • 知見が広がりにくい

今回コードレビューを行うことで以下のようなメリットがあると思い提案いたしました。

  • より知見が広がる
  • レビューする側にとっても学習になる
  • 他人がみてくれるのでより正しい記述になりやすい

上記の不安要素とメリットを用いて提案を行なったら「来週からやろう!」となりました。良いと思ったことをすぐ行えるのはWizの良いところだと思います。

コードレビュー会の内容

開催内容

開催頻度:週1(基本的に週末。難しい場合はslackにて調整)

題材:自由(フロントエンドの領域であればなんでも可)

時間:30分

開催内容についての補足

題材について

今回題材を自由としたのは以下の理由があります。

  • 特に気にならないコードであっても他人が見ると発見がある

コードは読む側の視点ではなく書く側の視点になって書くことが多いと思います。

(引用元:O’Reilly Japan「リーダブルコード――より良いコードを書くためのシンプルで実践的なテクニック」https://www.oreilly.co.jp/books/9784873115658/”)

なので、自分の中で読みやすいと思っていても、他人からすれば読みづらいこともあると思うので、今回は自由にしました。

時間について

今回時間を設けた理由としては、複数人でコードをみた際に時間を特に設けず行うと何時間でもしゃべることができる可能性があったため、時間を設けました。

開催の様子

以下が開催の様子になります。

https://i.gyazo.com/12e78a836e3ed26d2fd85857b69cff13.png

上記画像のように一つの会に対して3~4人で行なっています。

少人数で行なっているので、発言がしやすいのでコードに対して意見をだしやすいです。

また普段のコードレビューだと、しっかりコードをみて「プラスになるように書かなきゃ」などどうしても敷居が高くなってしまいがちです。

ですが私たちが行なっているコードレビュー会では、雑談を含め、なんとなく気になったことをどんどん発言していくので、画像からは伝わりづらいですがかなりわいわいしています。なので敷居は低い状態で行えていると実感しています。

  • コメントを少し紹介

「全然関係ないですけど、みなさんコミットメッセージどうしてます?」

「なんか最近ttlとかの命名の省略話題になってますが、なんかルールとか決まってたりしますか?」

「data-target-tabcontentselectって単語つなげるときどうしている?」

などなど、コードをみてふと思ったことやコード関係なしのことでも話したりします。普段なかなか聞けるタイミングがなく聞けなかったことなどを話したりできるので、とても有意義な時間だったと思います。

コードレビュー会を行なっての感想

メリット

コードレビュー会を行うことで以下のようなメリットを感じました。

  • 他の人からの意見が聞けるので、よりリーダブルなコードを追求できる

  • レビューする/される側双方向に知見が増える

  • レビュー会が毎週あることで、他人に見られるという意識が高まりよりリーダブルなコードを意識して実装をすることができる

  • 毎回議事録をとっているのでこの知見がたまっていくと、自社のコーディングルール策定ができる可能性ができた

課題

  • 時間が短い

  • 時間が確保しづらい

課題についての補足

時間が短い

コードによっては、議論がもちろん長引きます。ただ30分で強制的に終わるようにしているので、明確な答えが出せずに終わってしまいます。

そもそもコードによっては、明確な答えというものはないというのもあると思いますが、議論に対する納得のいく区切りをつけるのが難しいという解釈をしていただけますと幸いです。

時間が確保しづらい

どうしても案件の都合により時間が確保しづらい時があります。そういった時に無理くり時間を確保してやるのがベストなのか、リスケするべきなのかというベストな判断が難しかったので、ここは意見をもらいつつベストな手段を見つけていきたいです。

おわり

以上がコードレビュー会の紹介でした!

現在は一部チームでしか開催していませんが、周りのチームにもこの開催をもとになにかしらの影響を与えられると良いなと思っています。

外部に公開しても良さそうなコードが題材であれば、外部公開して社員以外の方も参加できる形にするのも楽しそうですね!

Wizではエンジニアを募集中です。

興味のある方は是非覗いてみてください!↓

careers.012grp.co.jp

データベースの正規化(第1〜第3正規形)

こんにちは!バックエンドエンジニアの小室です。

先日、4月から入社予定の方に向け「データベース設計」について研修を行いました。

その中でもメイントピックであった「正規化」について改めてまとめてみました。

さっそくですが、データベースにおける正規化とは、
データベースで保持するデータの冗長性を排除し、
一貫性と効率性を確保するためのデータ形式へ変換することを指します。

一般的に第3正規形までで十分とされているため第3正規形までを取り上げます。

第1正規形

テーブルの行と列が交わる1つマスを「セル」と呼ぶことにします。

第1正規形の定義は「1つのセルには1つの値しか含まれない」です。

f:id:wiz012:20210331171106j:plain
社員テーブル

このように1つのセルに1つの値が含まれているとき、この値を「スカラ値」と言います。

f:id:wiz012:20210331171522j:plain
社員テーブル(非正規形)

上のようなテーブルがあった場合、1人の社員は複数の子を養っているので、このように表現したくなりますが、

リレーショナルデータベースでは規則違反になります。

以下のように第1正規形に変換する必要があります。

f:id:wiz012:20210331171900j:plain
社員テーブル(第1正規形)

子の数だけ行を増やしました。これで全てのセルがスカラ値となり、第1正規形となりました。

しかし、以下の問題が発生。

1. 主キーが決められない。

  • この場合1レコードを特定するには「社員ID、社員名、子」の3列を
    指定する必要があるが、主キーの定義上、その一部がNULLを保持してはならない。

1. テーブルの意味やレコードの単位がすぐに分からない。

  • このテーブルは「社員、扶養者」という2つのエンティティを含んでしまっている。

下記のように分割することで、この2つの問題を解決できます。

f:id:wiz012:20210331174252j:plain
社員・子テーブル(第1正規形)

「扶養者」テーブルに子を持っている社員レコードのみに限定でき、
かつ主キーがNULLになることを防げています。

なぜセルにはスカラ値でないとダメなのか?

セルに複数の値を入れてしまえば、主キーが各列の値を一意に特定できないからです。
ここで1つ大事な概念があります。「関数従属性」です。

関数「 y = f(x)」のように、入力(x)に対し出力(y)が一意に決まります。
この関係を「yはxに従属する」と表現し、「{x} → {y}」と表記したりします。

上の「社員テーブル(非正規形)」を見てみると、
「{社員ID} → {子}」という関数従属は不成立になります。

一方「社員テーブル(第1正規形)」は、

{社員ID} → {社員名}

{社員ID} → {子1}

{社員ID} → {子2}

という関数従属が成立しています。

第2正規形

f:id:wiz012:20210331174929j:plain
社員・会社テーブル(第1正規形)

このテーブルは全てスカラ値からなるため、第1正規形であると言えます。

しかし第2正規形ではありません。
このテーブルの主キーは「会社コード、社員ID」です。

したがって、主キー以外の他の列はこの主キーに従属するのに対し、
「会社名」だけは「会社コード」のみに従属しています。

このように主キーの一部に対して従属する列がある場合、
この関係を「部分関数従属」と言います。

これに対し主キーを構成する全ての列に従属性がある場合を「完全関数従属性」と言います。

第2正規形の定義は、「部分関数従属を排除し、完全関数従属にする」です。

f:id:wiz012:20210331175605j:plain
社員と会社が分割されたテーブル(第2正規形)

部分関数従属の関係にあったキー列と、従属列を独立させました。
これにより社員テーブルにおける全ての列が主キーに対して、完全関数従属関係となりました。

第2正規形でないと何がダメか?

「社員・会社テーブル(第1正規形)」に対し、社員情報が不明の会社を登録したくなった場合、
主キーの一部に社員IDが含まれているため、社員IDがNULLになり登録ができません。

しかし「社員と会社が分割されたテーブル(第2正規形)」では、
会社テーブルのみに登録する事で、社員情報が不明な会社も登録できます。

このように見ると第2正規形はエンティティ(実体)をテーブルごとに分割する作業
という見方もできますね。

第3正規形

f:id:wiz012:20210331175605j:plain
社員と会社が分割されたテーブル(第2正規形)

「部署コード」と「部署名」に注目してみます。
会社コードが「C0001」のA商事に関してテーブルからわかることは、
「営業、開発、人事」の3つの部署があるということです。

しかし実際には「広報」という部署も存在するかもしれません。

しかし「社員テーブル」には社員情報がないと登録できないため、
広報に社員が0人ならば広報部署は登録することができません。
理由は主キーがNULLになってしまうためです。

このような不都合が発生するのは、まだ隠れた従属が残っているからです。
注意深く「社員テーブル」を見てみると、

{部署コード} → {部署}

という従属関係が見えます。

{会社コード、社員ID} → {部署コード}

という従属関係も明らかです。つまりは、

{会社コード、社員ID} → {部署コード} → {部署}

ということが言えます。このように段階的な従属関係を、
「推移的関数従属」と言います。

下記のように社員テーブルと会社テーブルと部署テーブルに分割しました。

f:id:wiz012:20210331181223j:plain
社員と会社と部署を分割したテーブル(第3正規形)

これにより、非キー列は主キー列に対してのみ従属するようになり推移的関数従属もなくなりました。
これにより先ほど問題であった、社員情報なしに部署を登録することが可能となりました。

第3正規形の定義とは、
「第2正規形のテーブルから、推移的関数従属している列が切り出されたもの」です。

正規化の功罪

正規化のメリットとしては、
データを一元管理し、データの整合性を保ちやすくなります。

その反面、正規化によりテーブルの数が増える事で、結合操作がより必要になり
検索SQLのパフォーマンスが劣化すると言ったデメリットがあります。

検索SQLと正規化のパフォーマンス関係はトレードオフであり、
第1正規化、第2、第3 ... と正規化が進むにつれて、
検索パフォーマンスは低く、データの整合性は高くなります。

結論としては、正規化された方が良く、非正規化は最後の手段として考え、
他の手法によってパフォーマンスが向上されないか検討し切羽詰まった時にとる最終手段と言われています。

最後に〜

 Wizではエンジニアを募集中です。

興味のある方は是非覗いてみてください!↓

careers.012grp.co.jp

第3回LT会を行いました。

第3回LT会レポ

今回のLT会の内容は

発表者: 3名

制限時間: 自由

テーマ: 自由

コメントツール:CommentScreen

で行いました。

それでは1つずつ発表を紹介していきます。

「経験学習」について考える

「経験学習」について考える
「経験学習」について考える
1人目の方には「経験学習」について考える。という内容を発表していただきました!
人の成長は「経験」によるものが大きいことを7:2:1の法則から理解し、経験するだけで成長するのではなく

  1. 経験
  2. 内省:経験から学んだことの振り返り
  3. 概念化:内省から学んだことを抽象化・概念化
  4. 実践

上記項目をサイクルとして回すことで成長できることを紹介していただきました。1人では振り返りの限界があるので、積極的に上司からフィードバックをいただき成長速度を上げていきたいですね! 

PlantUMLを使おう 〜UMLは友達〜

PlantUMLを使おう 〜UMLは友達〜
PlantUMLを使おう 〜UMLは友達〜
2人目の方にはPlantUMLについて発表していただきました!
PlantUMLとはオープンソースUMLダイアグラム作成用の、テキストベースの言語でございます。

  • 特徴と良い点

  • 導入・使用方法

  • 活用例

といった内容を発表していただきました。PlantUMLはNotion Web Clipperと組み合わせてギャラリーとして残すこともできるので、使ってみたいですね。

情報セキュリティに関して

情報セキュリティに関して
情報セキュリティに関して
3人目の方には情報セキュリティについて発表していただきました!
情報セキュリティの基礎や、脆弱性種類の紹介からそれぞれの対策などを紹介していただきました。実務を行なっていると、セキュリティについて時間を使って学習する時間があまり確保できないので定期的にこういった内容の勉強会など行なっていきたいですね。

おわり

第3回はこのような内容でした。

この記事ではざっくりとした内容しか紹介できませんでしたが、

LT会の内容をもっと社外へ公開できるよう目指していきたいです。

Wizではエンジニアを募集中です。

興味のある方は是非覗いてみてください!↓

careers.012grp.co.jp  

Next.jsのCSR(SPA),SSR,SSG,ISRのまとめ&メリットデメリットについて

はじめまして。最近無性に海外旅行に行きたいと思っているフロントエンドエンジニアの内田です。

Next.jsってページごとに色々なレンダリング方法を柔軟に切り替える事が出来て便利ですよね。

ですが、利用する際にはきちんとそれらレンダリング方法のメリットとデメリットを理解する必要があるのでここにまとめておきたいと思います。

ではいってみましょー!!

f:id:romeoromen:20210325084701p:plain

CSR(Client Side Rendering)

そのままなんですが、クライアントサイドでレンダリングするフロントエンド技術手法のアーキテクチャのことを指します。

ブラウザからHTTPリクエストされると、サーバー側はビルドされたJSとCSS、中身ほぼ空っぽなHTMLファイルをHTTPレスポンスとして返却します。

初回アクセス時はHTMLファイルの中身はほぼ空なので何も表示されず、その後初期データを取得してブラウザがHTMLをレンダリングします。

f:id:romeoromen:20210325085054p:plain

メリット

  • ページ遷移によるユーザーストレス軽減。一度読み込んだページはその後必要な部分のコンテンツのみを描画させるため画面全体が再描画されるストレスがなくなる。 よってユーザには優れたUI/UXを提供出来る。

デメリット

  • 初回アクセス時にWebサイトのデータをまとめて読み込むので、初回の表示まで時間がかかる。
  • クライアントサイドのJavaScriptの処理が増えるので、CPUやメモリーが少ないスマホなどのデバイスでは、操作性が損なわれる可能性がある。
  • SEOで不利かもしれない。(初回アクセス時にサーバーから返されるHTMLがほぼ空のファイルなのでクローラーがコンテンツを認識できない場合がある)
  • 動的なOGPの設定ができない。OGPの設定はサーバーから返されるHTMLのhead内に情報がないと読み込めない為、動的にページごとにOGPを分ける対応が難しい。
  • 直帰率が高いサービスにCSRを採用してもあまりメリットはない。

適したサービス

ユーザーが頻繁にページ遷移やコンテンツの操作するような滞在時間の長いサービスに適している。 SEOをそこまで意識しなくてもいいなにかしらのサービスの管理画面などに利用するのがいいかもしれない。

SSR(Server Side Rendering)

こちらもそのままなのですが、ブラウザではなくサーバサイドでレンダリングして、クライアントサイドで描画(ペインティング)する手法です。

初回アクセス時はクライアント側からHTTPリクエストが送られて、APIからデータを取得します。

その後、サーバ内で動的にHTMLファイルを生成(Node.jsが実行される)しHTTPレスポンスとしてレンダリング済のHTMLを返します。

f:id:romeoromen:20210325085129p:plain

nextjs.org

メリット

  • 初回アクセス時はクライアント側でAPIを叩かないので描画が早い。
  • SEOに強い。
  • ユーザーの通信環境に左右されにくい。(サーバサイドでレンダリングするので、CPUやメモリーが少ないスマホなどのデバイスでも操作性に影響が少ない。)

デメリット

  • SSRするためのNode.jsを実行出来るWebサーバーが必要になる。
  • サーバ側の負荷が高い。(サーバのCPU負荷が増える。)
  • 上2つの結果、ホスティングサーバの課金がつらくなる。
  • 秘匿情報が含まれたページがCDNにキャッシュされた場合、個人情報の漏洩などに繋がる。(Aさんの情報がBさんにも見えちゃう場合が!!)その為、色々な事を考慮するとキャッシュ設定が面倒。

Web版メルカリの個人情報流出

適したサービス

コンテンツ更新頻度の高いサービスなど。動画投稿サービスやSNSサービスが例としてあげられる。 比較的に大規模向け。 サーバサイドの知見がある人がチーム内にいればフロントエンドとしては安心出来るかもしれない。

■SSG(Static Site Generator)

静的サイトジェネレーターの事です。 アプリケーションのビルド時に、APIなどからデータを取得し、HTMLを最初に生成(プリレンダリング)し、 サーバーへのリクエストがあった場合には、この生成されたHTMLファイルを返却します。 また、生成された各HTMLはそのページに必要最小限なJavaScriptコードと関連づけられ、ブラウザによってページが読み込まれると そのページに必要なJavaScriptコードが実行されます。

f:id:romeoromen:20210325085253p:plain

nextjs.org

メリット

  • SSRよりもレスポンスが高速。
  • SEOに強い。
  • 動的なOGP対応が可能。
  • キャッシュを気にしなくていい。
  • なんか全体的にいい感じにやってくれる。
  • VercelがSSGを推してる。

デメリット

  • ビルド以降、データが更新されてもページに反映されない。
  • ページの数やコンテンツの数が多くなるとビルド時間が長くなる。
  • 頻繁にデータ更新があるサイトには向かない。

適したサービス

更新頻度の少ないブログやコーポレートサイト等。 比較的に中規模向け。

■ISR(Incremental Static Regeneration)

ISRはインクリメンタル静的再生成という手法を指します。

基本的にはSSGの挙動と同じなのですが、クライアント側のリクエストに対しビルド時に生成された静的ページを返し、 尚且、バックグラウンドで一定期間ごとに静的ページの再生成をサーバー側で行うといったものです。

nextjs.org

具体例

export async function getStaticProps() {
  const res = await fetch('https://.../posts')
  const posts = await res.json()

  return {
    props: {
      posts,
    },
    revalidate: 20, // In seconds
  }
}

export default Blog

SSGで利用する際の非同期関数であるgetStaticPropsからreturnするオブジェクトの中で、revalidate指定を一行追加するだけです。 ここでは例として20秒を指定しました。

初回アクセス(CDNにキャッシュが存在していない状態)から20秒経過後、クライアント側からリクエストがあったら クライアントには既に生成されたページを見せつつ(CDNキャッシュ)、バックグラウンドでデータの再取得及び再レンダリングするページを再生成し、 次のリクエストに対しては再生成されたページを返します。

メリット

  • SSGのBuild時間を短縮できる。
  • SSRと比較したらDB負荷は軽め。

デメリット

  • 現段階ではVercel依存。脱Vercelとなった場合に困る。

適したサービス

常に最新の情報である必要性はないが適度な更新頻度のあるサービス。


■まとめ

Next.jsではページごとにご紹介したレンダリング方法をよしなに選択する事が出来るのでそのページに合った最適なWebパフォーマンスをユーザへ届ける事が出来る事でしょう!! 是非この機会にNext.jsに触れてみてはいかがでしょうか。

■感想

Next.jsは導入するサービスのビジネスモデルを理解してレンダリング選定を間違えなければ高いパフォーマンスを発揮するし便利だよってことー。

参考記事:

Next.js の zero-config の恩恵を受けて SPA を作る

Next.jsのプリレンダリング方式についてまとめてみた - Qiita

ブラウザレンダリングを理解するため簡単にまとめてみた - Qiita

最後に

Wizではエンジニアを募集中です!

興味のある方、ぜひご覧下さい。

careers.012grp.co.jp

コロナ禍での他職種とのコミュニケーションについて

f:id:rainymoment0616:20210315183413j:plain

こんにちは、フロントエンドエンジニアの柳田です。

2020年、新型コロナウイルスの影響で、リモートワーク環境になった方は少なくないと思います。

弊社も同様にリモートワークになり、当初はコミュニケーションが取りづらくなることを懸念していましたが、バーチャルオフィスのoViceを導入したことで、その不安も払拭できたように感じます。

加えて、今までは会議室を利用して行っていた会議や勉強会なども、バーチャルオフィスの利用により、頻繁に行われるようになりました。

このテックブログでも、LT会輪読会の様子を紹介してきましたが、今回はエンジニア以外の職種のメンバーと取り組んでいるコミュニケーション施策について、ご紹介したいと思います。

事の発端はデザイナーからの協力要請

昨年の秋頃、弊社デザイナーから相談を受けました。

「異職種間での連携がちゃんと取れているか気になったから、デザイナーチームとフロントエンドチームにヒアリングをしたんだけど、うまくいっていないという意見が多くて…」

「これを解決したいんだけど、もし良かったら協力してくれない?」

私自身、たまにデザイナーと連携がスムーズに取れないことがあり、どうにかして改善できないかなー、でも自分ひとりだとなー…と行動に起こせずにいたので、「私でやれることなら全然手伝うよ!」と引き受けることにしました。

雑談会チーム発足!

そこから、他職種間での連携を取りやすくするためにどうすればいいのか、二人で施策を練ることにしました。

当初は、両職種間での業務における課題解決を目的にしていたので、「みんなで課題に思ってることを言い合って、業務改善できるようなルールを決めていく場を作るか!」と考えていました。

しかし、

  • そもそも仕事以外で話す機会もあまりないのに、そんなにざっくばらんに意見を言い合えるのか
  • 数回話し合ったところで解決できるような問題なのか(その問題が解決しても、また別の問題が浮上する可能性あり)

となり詰んでしまったため、上長にも相談。

「まずは課題解決をするのではなく、コミュニケーションを取る場を設けたら?」とアドバイスをいただき、結果、他職種間でのコミュニケーションを促進させ、心理的安全性を高めることで、業務におけるコミュニケーションコストを減らすことを目的として、改めて施策を練ることに。

話しやすい雰囲気を作りたかったため、雑談会というあまり固くなく畏まらないようなネーミングで、コミュニケーションを取る場を設けることにしました。

雑談会開催!

雑談会という名前をつけたときにもあったように、畏まった雰囲気を作りたくなかったため、

  • どの職種でも話しやすいテーマを設ける(テーマなしで臨むと、話しにくいメンバーも出てくる可能性があったため)
  • リモートだと大人数では話しにくいため、複数チームに分けて行う(6〜8人程度)
  • 自己紹介などのアイスブレイクを入れることで、話しやすい雰囲気を作る
  • カメラをONにして、面と向かって話してます感を出す
  • 基本的には任意参加にする(強制感を出したくなかったため)

など内容を詰めながら、2020年11月に1回目の雑談会を開催しました。

雑談会への参加は任意ですが、毎回ほとんどのメンバーが参加してくれていて、とても嬉しく思います。

f:id:rainymoment0616:20210316170332p:plain
【雑談会の様子】

第1回雑談会

初開催の雑談会は、デザイナーチームおよびフロントエンドエンジニアチームで行いました。

テーマは下記2点にして、両職種とも話しやすいテーマになるようにしました。

  • 自身の職種に関する情報、自身の職種以外の情報をどのように収集しているか
  • エンジニアやデザイナーはどんな風に勉強してる?業務に活かすためにインプットしてることは?

エンジニアもデザイナーもアンテナを張っている情報や収集する際のアプローチ法など異なっていて、聞いていてとても新鮮かつ楽しかったです。

また、最初に自己紹介を行ってもらい、その雰囲気のままテーマの話をしてもらうように。

終始楽しい雰囲気で行うことができました。

第2回雑談会(技術寄り雑談会)

1回目と同様、デザイナーチームおよびフロントエンドチームで行いました。

テーマについては、以前ヒアリングした際に出てきた、両職種間で課題に思っていることの中で意見が多かったものをピックアップして、下記3つに絞って行いました。

  • タブレット問題(各デバイスの画面幅によって起こる表示崩れの対応についての認識合わせ)
  • SVG問題(SVG画像の取り扱いについての認識合わせ)
  • フィードバック問題(修正指示の共有方法。円滑に製作作業を進めていくための認識合わせ)

このときは、チームでそれぞれ違うテーマ内容について話してもらったので、議事録を残し、他チームで話し合った内容について確認してもらえるような状態を作りました。

どの職種もUI/UXをより良くしようと、限られた時間の中でベストを尽くして作業しているのに、互いの認識違いが原因で、確認や調整に時間がかかりスムーズに進めることができないことが多くありました。

しかし、この会で認識を合わせることができただけでなく、「このようなルールで制作を進めていこう!」という流れになったことも、とても良かったです。

【番外編】年忘れ雑談会

年末の業務時間後に、1つのチームが4〜5人になるように分け、業務のことも含め、自由なテーマで話をしてもらう場を作りました。

Smgr雑談会

Smgr(サブマネージャー)と呼ばれる、弊社の役職者のみで集まって行う雑談会です。

  • 情報収集および部下への情報共有の仕方
  • 教育体制について(既存メンバーや新人に向けて)

一般社員のみで行う雑談会とは異なり、上記のような少し固めのテーマを展開していますが、普段Smgr同士でも話す機会があまりないため、雑談を踏まえながら行っています。

第3回雑談会

ディレクターチーム・デザイナーチーム・フロントエンドチーム(一部バックエンドチーム)の職種間で開催しました。

それぞれの職種が普段どのような仕事をしているのか、それぞれの職種の業務内容について話してもらいました。

ちょうど、この雑談会を開催したときには、フロントエンドとバックエンドにインターン生が在籍していたため、インターン生にも参加してもらいました。

各職種がどのような業務を行っているか、どのような考えで業務に取り組んでいるかを深く知ることができ、とても良い機会でした。

参加後アンケート

雑談会開催後はいつもアンケートをとっています。

企画している側としては、毎回ドキドキしながら開催しているのですが、毎回「良かった!」という声をいただいて、安堵しています。

今回はアンケートの内容を一部抜粋して、ここでご紹介したいと思います。

第1回アンケート

  • 仕事でかかわる機会が少ない人の声が聞けたのがよかったです。意外な趣味とか聞けるのも楽しいです。(仕事関係なし!)
  • 同じ役職のメンバーと同時話すことができたのが初めてだったので、とても新鮮で面白かった。また、(情報収集の仕方が)職種ごとに違うアプローチをとっていたので、興味深かった。
  • 普段話さないような事が出来る(してもいい)環境が用意されている事がよかった。仕事の事以外はあまり話しかけたらいけないような環境は息がつまるのでたまにはいいですね。

第2回アンケート

  • お互いチーム同士で協力して問題点など解決しようとする動きが良かった
  • フロント、デザイナーがお互いに、SVGに関する不明点やフワッとなっている部分(フローも含め)について、具体的な対応策や意見交換をすることができたので良かった。
  • フィードバック対応時のデザイナーの考えが分かり、コミュニケーションが取りやすくなりました。
  • フロント側の具体的な懸念点を知れたのと、そこからこうして行くべきという解決案が出たこと(デザインする際のルールの統一など)が良かった
  • 場の雰囲気が良かった!また、長年気になっていた事が聞けて、スッキリしました。

第3回アンケート

  • 他チームの取り組みを聞けて、ディレクターもなにかやろうと思えた。
  • 業務内容の共有というわけでなく、ざっくばらんにプライベートの会話ができていた点がよかった
  • 各職種の方々が、顔を合わせて話をするということ自体が良いことだなと思いました。顔を合わせて話をすることで、業務においてもスムーズなコミュニケーションを作りやすくなると思いました!
  • シャッフルタイムがあると全体で話せたかも
  • こういった組織にしたいよね、こういった運営したよねっていうゴールから何ができるかを色々アイディア出しできたら楽しそうだなと思いました!

また、全体的なアンケートを通して、いつもいただく意見として

  • 1時間じゃ足りないから、もっと開催頻度を増やしてほしい
  • 1チームあたりの人数が多いから、もう少し少ないほうがいいかも
  • まだ雑談会に参加していない職種とも話したい!
  • もっと他職種のこと知りたい!

という意見もいただいています。

まだまだ改善の余地がたくさんある雑談会…これからもがんばって企画していきたいと思います!!

最後に

私自身、自分から率先して話しかける機会があまり多くないので、雑談会を通して、普段話すことのないメンバーの普段の様子を垣間見ることができたり、仕事に対する姿勢や考えを聞くことができたり、とても良い機会だったと感じています。

また、開催して話す機会を増やしたことで「なかなか聞けなかったけど、この場なら聞けそう」「みんな同じことで悩んでるんだったらこの機会を利用して解決策を考えたい!」と考えるメンバーが少しずつ増えてきているようで、雑談会の目的である心理的安全性が少しずつ高くなっているのではと思っています。

より良い仕事を行うには、個人のスキルももちろん大切ですが、一緒にがんばっていくメンバーとの結束を固めることも大事な要素だと、私は考えています。

この雑談会をきっかけに、少しずつメンバー同士がざっくばらんに話すことができるようになり、より良いチームで、より良いサービスをお客さまに提供することができればと思っています。

そんなチームで一緒に働いてみませんか?

Wizではエンジニアを募集しております。 興味のある方、ぜひご覧ください。

careers.012grp.co.jp

E2Eテストの取り組みについて

はじめまして、フロントエンドエンジニアの菅野です。

今回は、E2Eテスト自動化の取り組みについてお話ししたいと思います。  

E2Eテストとは

End to Endを略してE2Eと呼ばれています。

例えば、

  • CV(コンバージョン)ポイントやログイン機能の動作確認
  • VRT(ビジュアルレグレッションテスト)

など、システム全体が正しく動作するかを確認するものです。

なぜE2Eテストを導入するのかというと、以下のような目的とメリットが挙げられます。

リリース時の確認コストの削減と品質担保

LPや2P~3Pといった小規模なサイトだと確認コストはそんなにかかりませんが、中〜大規模になると人の手で一つ一つ確認していくと時間と手間がかかりとても大変です。

そこで人が手を動かさずに各ページのUIや挙動をチェックすることができればコスト削減が見込まれます。

また、例えばリリース後に表示崩れが起きていたとします。

これまでだとリリースしてから5日後に気づいていたのが、リリース時にテストを実行することで1〜2時間といった短時間で発見でき、品質担保としても有効な手段となります。  

ツールの選定

E2Eテストツールはいくつかあり、

はよく耳にするのではないでしょうか。

他にはマイクロソフト製のPlaywrightというライブラリが2020年5月にリリースされています。

そんな様々なツールがある中で今回選んだのが「TestCafe」です。  

TestCafeとは

アメリカのDeveloper Express Inc.という企業が開発しているE2Eテストツールで、ブラウザテストを自動化するためのフレームワークです。

2016年にリリースされており、比較的新しいツールといえます。

特徴

  • async/awaitの仕様を前提にAPI設計がされている
  • TypeScriptサポート
    • 通常のJSだけでなくTypeScriptで記述したテストコードをそのまま実行できる
  • 構築が簡単
    • SeleniumではWebDriverのクライアントとテストを実行する各ブラウザのWebDriverのインストールが必要だが、TestCafeはnpmでTestCafeをインストールするだけでOK。設定ファイルも必要なくテスト環境が整う。
  • 非WebDriver依存
    • 一昔前のE2Eテストツールは、各種ブラウザベンダ間の差異を吸収し、抽象化して操作するためにWebDriverを使うのが常識でしたが、現在はブラウザ側がサポートするようになり、テストツール側が意識しなくてよくなった。TestCafeもこれを前提に設計されている。
  • BDD(ビヘイベア駆動開発)に則ったテストコード
    • UIテスト手順をメソッドチェーン形式で記述。これにより、ユーザー操作や外部仕様をまるで自然言語のようにコードで表現できる。つまり、テストコードがそのままテスト仕様書となる。
  • サポートブラウザが豊富
  • TestCafeだけでなく、Node.jsすらインストールされていない環境であっても、テストを実行することが可能
    • その場合、TestCafeが出力するURLを対象の環境のブラウザで開くだけでテストが開始される。ただし、TestCafeがインストールされているホストと対象とするデバイスが同一ネットワーク上に存在する必要がある。
  • BrowserStackとの連携をサポート
    • E2Eテストの実行環境は開発マシンとは別に用意しておくことが望ましい。そうすることで開発(実装)と並行してテストを実行しやすくなる。

以上の特徴があり、

  • サポートブラウザが豊富
  • 構築が簡単
  • async/awaitとを含む最新のJS機能とTSをサポート

が大きな選定理由となります(あとTestCafeっていう名前が可愛かった)

テスト項目

  • VRTテスト
  • CVポイント(フォーム)の基本動作確認
  • metaやOGPの取得
  • マークアップチェック

この4項目のテストを行います。

VRTテスト

VRTとは、画像回帰テストと呼ばれており、画面のスクリーンショットをリリース前後で比較することで表示崩れを確認することができるテストです。

TestCafeとreg-cli*1を組み合わせて実装していきます。

  1. まずはTestCafeを使って、指定するページのスクリーンショットを撮影します。
  2. reg-cliを使って差分比較を行います。

reg-cliで生成されたHTMLを見てみると reg-cli

このように差分を確認できるようになります。

おまけ

スクリーンショットが複数枚ある場合は、それぞれを連結させて1枚の画像にすると1枚1枚開いて確認する手間が省けるのでおすすめです。

sharpという画像編集ライブラリを使うと実装できます。

スクリーンショット連結

CVポイント(フォーム)の基本動作確認

フォームが入力〜送信まで問題なく動作するかをチェックします。

バリデーションや様々なパターンを想定してテストが実行できると良いですが、テストケースがかなりのボリュームになり、コストがかかり過ぎてしまう可能性もあるので、どこに重点を置くかを決めてテストケースを絞るのが現実的かなあと思います。

fixture('FormTest Start');
  .page('https://example.com');
  test('必須項目を入力し送信', async (t: TestController) => {
    const dataTarget = await Selector('[data-target-input]');
    const name = dataTarget.withAttribute('name', 'name');
    const mail = dataTarget.withAttribute('name', 'email');
    const phone = dataTarget.withAttribute('name', 'phone');
    const submitBtn = await Selector("button");

    await t
      .typeText(name, 'テスト名前')
      .typeText(mail, 'test_sample@gmail.com')
      .typeText(phone, '0312345678')
      .click(submitBtn.withExactText('送信'))
}); 

   このように直感的に書けるので分かりやすいのではないでしょうか。  

metaやOGPの取得

ページを一つ一つ開き、デベロッパーツールや拡張機能を使ってmeta情報を確認するのはとても面倒です。

スクリーンショットを撮るタイミングで各ページのmeta情報を取得し、jsonに吐き出すことで確認コストを削減します。

og:imageは外部のOGP確認ツールにアクセスし、スクリーンショットを撮影します。

テキスト情報だけでなくog:imageを視覚的に確認できるようにしています。  

{
 "meta": [
  {
   "page": "/",
   "title": [
    {
     "text": "株式会社Sample",
     "最大29文字程度": true
    }
   ],
     "description": [
    {
     "text": "株式会社Sampleのdescriptionが入ります。",
     "最大110字程度": true
    }
   ],
   "keyword": [
    {
     "text": "株式会社Sample,サンプル,sample,北海道,東京,大阪,福岡",
     "5〜6個程度": false
    }
   ],
   "og:title": "株式会社Sample",
   "og:url": "https://example.com/",
   "og:image": "https://example.com/img/ogp.png?1603865417442",
   "og:site_name": "株式会社Sample",
   "og:description": "株式会社Sampleのog:descriptionが入ります。",
   "canonical": "",
   "robots": null
  }
 ]
}

ogp確認スクリーンショット

マークアップチェック

テスト実行時にチェック用のCSSを挿入し、スタイルが当たった状態のスクリーンショットを撮影してマークアップチェックを行います。 ディレクターやデザイナーはソースコードをあまり見慣れていないため、視覚的に確認できるようにすることで、マークアップについてもチーム全体で意識を持ち、品質担保を目指すことができます。

markupチェック

  • ul,olの子要素にli以外のタグが入っている
  • dlの子要素にdt,dd,div以外のタグが入っている
  • imgタグのaltがないもしくは空
  • リンクにname属性もしくはhref属性にjavascriptが使われている
  • target="_blank"がついている場合にrel="noopener"

といった項目がチェックできるようになっています。


以上、4つの項目のテストを実行し、チェックを行っています。

実案件での使い方

コーポレートサイトと新卒採用サイトでは新規コンテンツ制作時や複数ページに及ぶ修正が発生した際に必要なテストを実行し、結果をSlackでプロジェクトチームに共有して確認を行っています。 最近だとmetaを変更したのでjsonを共有して確認に使用してもらいました。

slack_共有

今後やりたいこと

Qiitaに詳しい実装方法は書いており、それを参考にWiz cloudにも導入してもらっていますが、他の案件にもスムーズに取り入れてもらえるようドキュメントを鋭意制作中です。

これで完成ではなく、アップデートして継続できるE2Eテストにしていけたらと思います!

最後に

Wizではエンジニアを募集中です!

興味のある方、ぜひご覧下さい。

careers.012grp.co.jp

*1:VRTのためのコマンドラインインターフェイスです。 画像は別途用意する必要がありますが、アサートする画像を指定するだけで現在の画像と以前の画像を比較し、差分のHTMLを作成してくれます。