おいすブログ

random things

ブロック要素の縦横ど真ん中に要素を置くためのCSS

CSSに慣れてないころ、こういう感じで縦方向と横方向同時に中央揃えしたいだけなのに

f:id:oi5u:20181108140745p:plain

意外と出来なくて困った記憶があります。"縦横中央揃え css"みたいなキーワードで検索しても、「7つ方法があります!」って言って、順に説明してるページがトップに来るので、えっ、どれ…ってなると思う。

今はflexboxがあるから簡単で、その7つ目として紹介されている、

  display: flex;
  justify-content: center;
  align-items: center;

これを追加するだけでOK(IE9なんてもうサポートする必要無いし、サポートが求められるようなプロジェクトからは逃げ出そう)

こちらJSbinのサンプルコード。

JS Bin on jsbin.com

だけど結局これも、なんで3行も要るの?justifyってなに?ってなると思うし、正直そう思います...。なんでこんなネーミングになったんだろうflex

Reactとtoggle型UIの非同期処理問題

toggle型UIのユーザー体験

toggle型(ユーザーが切り替え可能なオン・オフの2つの状態を持つ)のUIを実装する場合、 通常、切り替え時に何らかの非同期処理を呼ぶことになると思います。

それがサーバ側での更新処理を伴う場合、通常はレスポンスを待ってからユーザーへのフィードバックをするかと思いますが、その間ユーザーを待たせてしまうことになり、またレスポンスタイムはユーザーの環境に左右されるため、特に頻繁に押されるボタンの場合にはUXを損ねてしまう可能性があります。

実際の動きを見てみます。

iOSでDeveloperメニューのNetwork Link Conditionerを使います。Very Bad Networkに設定し、通信状態が非常に悪い状況を作ります。

f:id:oi5u:20181105171619j:plain
Network Link Conditioner

この状態で、例えばDMM英会話の「お気に入り解除」ボタンを押すと、 ボタンを押してからハートマークが切り替わるまでに 秒単位のラグが生まれてしまいます。

f:id:oi5u:20181105190126g:plain
DMM英会話(iOS Web)

また、こちらはメルカリの設定画面ですが、二重送信や完了前の画面遷移を防ぐため、このように画面全体をブロックしてしまうのもよく見る実装です。

f:id:oi5u:20181106003014j:plain
メルカリ(iOS App)

ユーザーの操作をブロックせず、かつ、直ちにフィードバックする実装が望ましいと言えます。

Optimistic Updates

一方、TwitterFacebookInstagramのLikeボタンは、ボタンを押した瞬間に処理が成功したものと見なされて即座にフィードバックがあり、その後バックグラウンドでAPIコールをする実装になっていると思われます。これがもしLikeの更新処理に失敗すると、その場では成功したように見えていても、のちに画面を更新すると元に戻ってしまいます。

f:id:oi5u:20181105163259g:plain
TwitterでのLikeボタン(iOS App)

これは、そもそも端末がオフラインの状態でボタンを押した場合でも同様の動きになっており、特にアラートなどは出ません。その後リクエストがタイムアウトするまでにオンラインへ復帰すれば、pendingとなっていたリクエストが実行されるようです。楽観的に更新処理を行っていると言え、これをOptimistic (UI) Updatesと呼ぶようです。

また、サーバからのレスポンスをハンドリングするかどうかについては、toggleのUIが持つ意味によって対応が分かれているようです。

Twitter iOSアプリの場合、前述の通り、お気に入りは失敗しても無視、つまりサーバ上の状態とアプリ上の状態が異なったままで、他のアクションや画面遷移が許されていました。画面をリフレッシュしてサーバ上のデータと同期したタイミングで、暗黙的にズレが解消されることになりますが、これが問題になるケースは稀であるという判断で許容しているものと思われます。

しかし同じTwitter iOSアプリの設定画面のスイッチでは、押した瞬間に切り替わるOptimistic Updatesであるものの、リクエストが失敗したタイミングでUISwitchの状態を元に戻していました。画面上のLikeボタンが勝手に動くため、ユーザーにとって多少の違和感はありますが、設定の状態にズレが生じないことの方を重視した結果と思われます。

f:id:oi5u:20181105235524j:plain
Twitter設定画面のスイッチ(iOS App)

Optimistic Updatesにおいて、非同期処理の結果を画面に反映させるべきかどうかは、

  • 1セッションにおける実行頻度が高いかどうか
  • コンバージョンに直接影響するかどうか、またはユーザにとっての重要性が高いかどうか
  • サーバ側と状態が乖離していても、その後アプリ上で問題が起きないかどうか

といった点を考慮した上で決めるのが良さそうです。

Reactの実装

前述の同期的にレスポンスを待ってから更新するケースでは、Reduxのstore(もしくはcontext APIなど)から直接Like状態を取り出して、Likeボタンのコンポーネントにpropで渡しておけばよかったのですが、Optimistic Updatesの場合にはそうすることが出来ません。

これをReactで実装する上では、いくつかの方法が考えられます。Like状態の参照先をもとに、2つに分けます。

1. Like状態はcomponentの内部stateを使う

Like状態をcomponentの内部stateとして持ち、ボタンイベントに合わせてtoggleする方法です。initialStatecomponentWillMount 時に渡します。

const doAsyncRequest = () => {
  // do async request
}

class App extends React.Component{
  constructor(props) {
    super(props)
    this.state = {
      liked: false,
    }
  }
  
  componentWillMount() {
    const { initialLikedState } = this.props
    this.state = {
      liked: initialLikedState,
    }
  }
  
  onPressButton = () => {
    this.setState({liked: !this.state.liked})
    doAsyncRequest()
  }

  render() {
    return (
      <div className="app">
        <div className="title">
          { this.state.liked ? "👍" : "👎" }
        </div>
        <div className="button">
          <button onClick={this.onPressButton}>
            Toggle
          </button>
        </div>
      </div>
    )
  }
}

JS Bin

JS Bin - Collaborative JavaScript Debugging

サーバから返されるレスポンスについては一切責任を持たない、最もシンプルなやり方です。この方法の場合、Like状態の参照がstoreから切り離されてしまうので、componentがmountされたあとに別のトリガーによってstoreのLike状態が変わってしまうと、リアクティブに追随できなくなります。また、他の場所でも同じLike状態を表示しないといけないケースでは、何らかの方法で状態を共有しなければならなくなります。

2. Like状態はstoreを直接参照する

Like状態は、storeにあるstateを参照します。その上で、ボタンイベントがトリガーされた時点で、非同期処理の手前で、レスポンスを待たずにstoreのstateを更新してしまいます。レスポンスを受けてその後stateを再度更新するかどうかは、前述の通り、状況次第です。

もしレスポンスが失敗のケースでundoする場合、予めstateの履歴を保持しておく必要があるかもしれません。

以下のようなライブラリを使うと、stateにhistoryを持たせることができます。リクエストの成功/失敗時に、stateがcommit/revert可能になるようです。ただ、stateに更にstateを持たせている状態になってしまうのがちょっと複雑に思えて、個人的には気になるところです。

  • redux-optimistic-ui

GitHub - mattkrick/redux-optimistic-ui: a reducer enhancer to enable type-agnostic optimistic updates

  • redux-optimist

GitHub - ForbesLindesay/redux-optimist: Optimistically apply actions that can be later commited or reverted.

その他

この記事では「toggle型UI」という風に呼んでいますが、画面遷移を伴わずに更新処理が走るUI(例えばレーティングなど)であれば、状態が3種類以上あったとしても同じ議論になると思います。

またなにか気づいたら、追記しようと思います。

iPhoneの英英辞典がめちゃ便利

Spotlight検索(ホーム画面でswipe downして起動)で英単語を入力すると、suggestionにOxford Dictionaryが出てくると思うんですが、

f:id:oi5u:20180613181240p:plain

f:id:oi5u:20180613181241p:plain

これ、例文、派生語はもちろん語源まで載ってるし、 オフラインでも使えて早いので、かなり使える子です。 (ということにさっき気づきました。。)

ブラウザなどでテキストを長押し選択したときのコンテキストメニューからも、 この同じ辞書を呼び出すことが出来ますよね。 いつのまにか便利になったもんですなあ。

オンラインのときはSpotlightからそのままweb検索すれば Googleの辞書が表示されるので、

f:id:oi5u:20180613182058j:plain

より詳しい内容はここで見ることが出来るし、 音声を再生したい場合はここで再生できるし、 コロケーションを調べたい場合は検索結果を適当に眺めればOKだし、 スマホ最強ですね。

昔20$ぐらいで買ったCOBUILDの英英辞書アプリを起動する意味が ほぼなくなりました。。

COBUILD Advanced American

COBUILD Advanced American

  • 物書堂
  • Reference
  • $18.99

表丹沢 縦走の魅力

f:id:oi5u:20180611002418j:plain

時々山に登るんですが、 こないだは丹沢に行ってきました。

登山の目的

登山の目的には色々あると思うんですが、 自分は効率の良いトレーニングと気分転換を兼ねて登ってます。

荷物を持って歩くだけですが、超長時間の有酸素運動なので、 1回の登山で少なくとも3000kcalは消費してます。 時速8kmのジョギングを30分したところで240kcal、 もうちょっと強度を上げても400kcalぐらいでしょうから、 単純計算で、ジョギング7〜12回分の効果です。

でも山は危険

でももちろん山には危険がいっぱいなので、 調子が悪かったら無理せずペースを落としますし、 トレーニングの時はよく踏まれた登山道しか使いません。

山はワンチャンで遭難したり死んだりする可能性があるので、 自分の限界をしっかり把握し、事前準備と安全に留意することが重要ですね。 初心者のうちは、高尾山とか御岳山とかの初心者コースとかから始めるべきです。

登山の良いところ

私のような怠惰な人間だと、例えばジョギングを毎日の日課と決めても 「今日はやめとくか」となるポイントが毎日発生してしまうので、どうしても続きにくいのですが、 登山の特徴として、一度登り始めると下山まで基本的に逃げ場がなく、 そのポイントが基本的に発生しないので、とにかく最後までがんばれます。 他の人が登ってる姿を見ることによっても、励みになりますね。

しかも、景色の移り変わりや気持ち良い空気もボーナスでついてきます。 写真を撮ったり野花を愛でたりしても良いです。

意外とゲーム性がある

登山道にはコースタイムが大体決まっているので、 自分がどれくらいのペースで歩いたかとか、 同じコースを再度歩くのであればどれくらいタイムが縮まったかなどを励みにできます。 出発前にあれこれルートを考えるのも意外と楽しいし、 行動中も、浮き石があるガレ場とかザレ場でどう足を置いて登っていくか・下りていくかを 瞬間的かつ連続的に考えながら体を動かしていくのは、意外とゲーム性がある気が。

丹沢表尾根の魅力

丹沢はこれまでで一番多く登っているんですが、 中でも表尾根ルートが一番のお気に入りです。

おじいちゃんおばあちゃんが沢山登るコースではあるんですが、 距離も高度差もかなりあって、中級者以上向きの健脚コースです。

何が良いかと言うと、道中の変化がバラエティに富んでいて、 都心からのアクセスもそんなに悪くなく日帰りOKだし、 ピークハントの醍醐味が凝縮されたコースなんじゃないかと思います。

基本情報やルートはこちらを参照です。

秦野市観光協会−表丹沢登山ガイド:表尾根縦走コース

スタート地点であるヤビツ峠へは、秦野駅からバスで向かいます。 平日は朝1本しかないんですが、だいたい行列が出来てて積みきれずに臨時便が出ます。 バスはうねうねした山道を通っていくんですが、 ガードレールの外が切り立った崖になっていて、いつも怖いです…。

ヤビツ峠バス停から登山口までは平和な車道です。 この後いきなり始まる急登のための軽い準備運動ですね。 ヤビツ峠はバイク勢や自転車勢の人にも有名っぽいですね。

f:id:oi5u:20180611002603j:plain

これがヤビツ峠の登山口で、しばらくはきつい道が続きます。 それを乗り越えると、二ノ塔、三ノ塔とチェックポイント兼休憩地点が続き、 そのうち開けた場所に出て絶景が見れます。

f:id:oi5u:20180611004344j:plain

うっすら富士山もゲットできました。イケメンですね。

f:id:oi5u:20180611004505j:plain

道中、こんな木道があったり

f:id:oi5u:20180611002148j:plain

こんなハシゴがあったり

f:id:oi5u:20180611003820j:plain

こんなクサリがあったり

f:id:oi5u:20180611004047j:plain

こんな草ボーボーの区間(通称藪漕ぎ)があったりして、 ちょっとしたアスレチック感覚が楽しめます。 (安全には注意!)

上りのゴール地点である塔ノ岳での風景は、ぜひご自身の目で!

下りは、大倉尾根を通るのが一般的です。 通称バカ尾根と呼ばれていて、ひたすら長くてわりと単調...。

とはいえ、迷うことのない一本道でチェックポイントも多く、 安全で比較的歩きやすい道です。 疲れた体で頭をからっぽにしてひたすら下るのも乙です。

大倉バス停は登山者のターミナル的な場所で、バスの本数も多め。 トイレや靴を洗う場所があるので便利です。

その他

丹沢は山深くて、いろんなルートや楽しみ方が考えられますね。 鍋割山に行って鍋焼きうどん食べるのも美味しいし、 もっとストイックに行くならさらに足を伸ばして丹沢山蛭ヶ岳目指すとか。 蛭ヶ岳まではまだ行ったことがないので、近いうちチャレンジしたい!

クレジットカードの番号を暗記する

f:id:oi5u:20180607115312j:plain

オンラインショッピングとか、 サブスクリプション系のサービスを契約したりとかって、 みなさんどれくらいの頻度でしてますかね。

私は仕事柄、結構な頻度でしているので、 その度にクレジットカードの番号を入力させられます。 残念ながら、paypalその他の決済方法が使えることは少なく、 履歴を一箇所にまとめたいというのもあって、 だいたいクレジットカードです。

なので、クレジットカードの番号を暗記することを10年ぐらい前から始めたのですが、 これによってオンライン決済でのストレスが格段に減りました。

いちいち財布からカードを取り出して確認する必要がないので、 セキュアですし、職場から仕事中にちょこっと買い物するときとかも便利です😈

覚える要素としては

  • 16桁の番号
  • 有効期限(YYYY/MM)
  • 裏面の3桁の番号

と結構ボリュームがあるのですが、 暗記が苦手な私でも、適当に語呂合わせを作って 何も見ないで入力して分からなくなったら確認してってのを繰り返してると、 10回ぐらいで覚えられました。

途中で1回メインで使うカードを変えてて、 番号から何からすべて変わってしまって覚え直しになったのですが、 なんとかなっています。。

同じカードを使っていれば変わる部分は有効期限だけなので、 10年ぐらい余裕で役に立ちます。 クレカ使う機会が多いのであればやって損はないと思います🙂

エンジニアの転職について

f:id:oi5u:20180605174121j:plain

現場は深刻なエンジニア不足

2018年現在、ソフトウェアエンジニアの転職は完全に売り手市場だと思います。

というのも、数ヶ月前にいた会社では 同僚のエンジニアが辞めまくっていて慢性的な人手不足で、 エンジニアとして採用活動にも時々関わっていたので、 買い手側の立場としてもかなり苦労した経験があります。

大量の転職エージェント、フリーランス案件紹介会社の存在

その会社員時代、自分のところにもLinkedInやWantedly経由で 転職エージェントからのメッセージやフレンドリクエストが 頻繁に届いていました。

ヘッドハンティングのお知らせ」「魅力的な経歴が目に止まり」などと甘い言葉をかけてくるんですが、 これは別に自分がエンジニアとして何か特別だったからという訳ではなく、 単純に世の中の現場にエンジニアの数が足りておらず、 それに反して転職エージェントや紹介会社の数がめちゃくちゃ多いからです。

特にlinkedInにはびこるエージェントの多くは、 IT系の案件を担当していてもエンジニアリングの知識はほぼ無く、 手当たり次第にメッセージを送ってくるので、 スキルセット的に全然的はずれな会社に紹介しようとしてきます。 (フロントエンドやりたいって書いてるのに、サーバサイドのポジションを紹介してきたりとか)

もちろん、きっちりした仕事をされてる方もいるとは思いますが、 あまり専門知識や初期投資を必要としないビジネスなので、 これほどまでに人材会社が増えているのだと思います。

参考: 日本は狂ってる 派遣会社の会長=経済戦略会議の委員 | 黄金の金玉を知らないか?

転職エージェントがしてくれること

こんな感じでしょうか。

  • 応募先を人力検索してリストで送ってくれる
  • 志望動機などの作文の手伝いをしてくれる
  • 話し相手、面接の練習相手になってくれる
  • マージンを抜いてくれる

私も過去2度の転職をエージェント経由でやったことがあるんですが、 エンジニアの事情や適正は、正直、同じエンジニアにしか分からない部分が大きいので、 結局自分の目と耳と足で調べて探して考えるべきという結論に至りました。

もし現役エンジニアの転職エージェントがいて、 自分と専門分野や指向性が近いようだったら相談してみたいと思いますが、 そんなことはまず無いので…。

相手方のエンジニアや一緒に働くことになる方々とじっくり話をするのが当然の近道で、 よっぽど入りたい企業でもなければ、 エージェントと二人して小手先の準備を頑張ってもしょうがないかなと思います。 エンジニアに人気があって"イケてる"な企業って、 そういうことを重視しない傾向にあると思うので、なおさらですね。

私も今後もし会社員に戻るとしても、 受け身になって紹介メールを待つのではなく、 こちらから気になる企業に直接応募して、 相手の会社の方とじっくり話をすることに 時間をたくさん使いたいと思っています。

フリーランスの案件紹介会社

自分が関連ワードでよく検索してるからってものありますが、 最近Web広告でよく見かけるようになって、 急激に増えてきたなあっていう印象があります。

私自身は、昔に登録だけして実際に利用したことはないのですが、 やはりこれも転職エージェントと同じようなものだと思います。

紹介会社を介して契約を行うケースが多いと思うので、 クライアントさんとのお金や契約周りの手続きを代わりにやってくれるらしいですが、 彼らに支払う手数料がそれに見合った金額なのかどうかというのは きっちり吟味する必要がありますよね。

上の記事の情報では少なくとも20%とか30%とかっていう話なので、正直フェアではないですね。 自分が登録したところでは額面で日給2〜3万円みたいな相場だったので、 まあ相当抜かれてると思って良いかと思います。

また、わざわざ紹介してもらわなくても、エンジニアが不足している昨今なので、 気になる企業に自分から声をかけていけばすぐ案件が見つかると思いますし、 間に人を入れないほうがやり取りもスムーズでスピード感出ます。 自分の時は、週5日客先常駐みたいな案件が結構あって、 それってフリーランスで働く意味なくない...?って感じでした。

企業側にいた経験からも、担当者が受ける印象として、 「会社に紹介されたので来ました」っていう人より 自社に興味を持って自分から応募してきてくれた人のほうが志望度は強いはずですし、 自発的・能動的に動いてくれそうに思えて、あまり悪いことは無いと思います。

おわりに

テクノロジーの力で、あらゆることの中間マージンや取引コストは 昔に比べてもっと減らせるはずだし、減らすべきだと思うので、 テクノロジーに一番近いエンジニアからまずそれを変える動きが生まれたら良いなあと思います。

こういう、ブロックチェーンを使った働き方改革のプロジェクトみたいのもあったりしますしね。 Colony: A platform for open organizations

フリーランスになりました

f:id:oi5u:20180605161749j:plain

しばらくブログの更新をサボってしまっていたのですが、 3月に会社員エンジニアを辞め、 4月からいわゆるフリーランスのエンジニアになりました!

正直、会社員時代も比較的自由にやらせてもらってはいたのですが... 通勤時間や無駄な会社行事への強制参加が無くなり、 一緒に働く相手を選ぶことができるようになったので、 ざっくり言うと、とにかくストレスが減って使える時間が増えましたね。

会社を辞めてから2ヶ月ほど経ち、色々なことが落ち着いてきました。 家事や英語の勉強に使える時間が増えて、 自己投資や身の回りのことをしっかり出来ている安心感から、 仕事への集中力や効率も心なしか上がった気がします。

ただ、人と会う機会が激減したので、 これから社会性を失わずに健全に生きていけるのかどうかが今後の課題です。。 オフ会(勉強会という呼び方が嫌なのでこう呼ぶ)にももっと参加しようかなと思いつつ、 こういった情報発信にもある程度やっていきたい今日この頃です。

特に開業にあたっては、MF会計の使い方、青色申告のための会計処理、社会保険制度などなど、 色々と調べて学ぶことが多く、このあたり、また追って少しずつ情報発信していきたいです。