🍃このブログは移転しました。
3秒後、自動的に移動します・・・。

#スーパーイカメーカー を支える技術

どうも、中のイカです。
昨日の15時頃に晴れてリリースしたコレですが、正直想定してなかったレベルで反響があって驚いてます。

leader22.github.io

さてさて、というわけで恒例の裏側紹介記事です。

近況

今のところの瞬間最大風速です。

初めて見たわこんな数字w

ホッテントリ入りもしたしredditでもスレ立ったり。


まさかのポストすしざんまい!すごいなーイカ・・。

ほんと、サーバー落ちないかどうかだけが心配でした。
そもそもどの程度で落ちるかの想定もできないくらいの素人ですけど!

フロントエンドについて

さてフロントエンドエンジニアな私なので、もちろんぜんぶフロントでやってます。
コードはいつもどおりGitHubに全部あるしこれが全てなので、よければ覗いてみてください。

github.com

そもそもの構造

  • 使用できるパーツ画像からjsonを用意
  • それを元にパーツセレクターを描画
  • セッティング状態を表すオブジェクトをポチポチ変更
  • ポチポチする度にcanvas.drawImage -> canvas.toDataURLして表示

たったこれだけです。
HTML Canvasをよく知らない人は、サーバーレスでなんでこんなことが・・・!って感じかもですね。

React x flumpt

完全にやってみたかったドリブン技術選定です。
前にReactだけを使って後は適当に書くスタイルでアプリを書いたことがあって、結局ReactはPubSub機構なしには(= そしてFlux的に上からステートを流す)うまく使えないなーという結論だったので、今回ははじめからそれに準ずるものを使おうと思ってました。

こないだの翻訳記事でFluxするならReduxがオススメ!だって使ってる人多いから!ってのを書いた直後ですが、採用したのはReduxではなくflumptというものです。

redux への 不満を解消する為に, flumptというFlux実装を作った - Qiita

↑の記事やサンプルコードを見てもわかる通り、ほんとに薄い実装でわかりやすーいライブラリです。
同じくEventEmitterだけあれば十分やろーって思ってましたが、他にも色々できてさすがの一品でございました。
おかげで迷うことなく(そもそも大した規模じゃないけど)使えて助かりました。

READMEの変数名にtypoがあったりイベント名が変わってたりするのはそのうちなおるでしょう( ˘ω˘)スヤァ

Reactのいいところ

この程度の規模でReact語ってんじゃねーよって言われそうですが、まぁ一応。

個人的には、コードの書き方が一定になるので後から読みやすいのが一番かなーと思います。

中の細かいstateとかlifecycleEventとかのお作法はあれど、Reactはコンポーネントしか返さないのでrenderだけに集中して、
あとのロジックをReactのいないところで全部やる!それだけ!

っていうのがコードレベルで統一できるのは大変よろしいと思います。

Reactのわるいところ

JSXのあと一歩足りない感。

<ul className="tab-header">
  // こういうループのためのmapとか
  {tabItems.map((item, idx) => {
    let isSelected = idx === selectedTabIdx;
    return (
      <li
        className={`
          tab-header__item
          tab-header__item--type-${item.group}
          // こういうクラス名のアレとか
          ${isSelected ? 'is-selected' : ''}
        `}
        onTouchTap={() => { this.onClickTab(idx); }}
        key={item.order}
      >
        <h2>{item.name}</h2>
      </li>
    );
  })}
</ul>

もうちょっと綺麗にならんもんかなー。
classNamesみたいなモジュール使ってもいいけど、なんだかなー。

スタイル当てる系のライブラリも、いつまでたってもbefore/afterの擬似クラスは使えるようにならんしー。
その点まだVue.jsとかVueifyは良かったなー。

react-tap-event-plugin

v1.xからはデフォルトでReactに入るんかな?
とりあえずtouchTapって書くだけでモバイルでもPCでも動くのには感動しました。

postcss

続・完全にやってみたかったドリブン技術選定です。
最近流行ってるだとかSassは死んだ!とかいろいろ聞く中、実際はどんなもんなんだろなーと。

結論としては、この程度の規模だとどっちでもいいです。
今回使ったのはこんな感じ。

{
  "use": [
    "postcss-import",
    "postcss-nested",
    "autoprefixer",
    "cssnano"
  ],
  "input": "./src/style/style.css",
  "output": "./dist/style.css",
  "autoprefixer": {
    "browsers": "last 2 versions"
  }
}

postcss-cliwatchの機能もついてるので、特に不満はないです。
ただSassならオールインワンな内容が、postcssだと自分でプラグインを探してこないといけなくて、そこだけ毎回ハマる感じ。
プラグインを探すのは手間ですが、だいたい見つかるし、カスタマイズできるって分だけnode-sass単体より便利かなーと。

身の丈にあった技術選定をしたいのでcss-nextなことはやってません。

UIUX

絵を描いてくださった(そしてそもそもの言い出しっぺ)のは@jenga_inkさんですが、デザインは私です。
なので至らない点は多々あるのであんまり参考にならんですが一応気にかけた点。

  • PCでもモバイルでもWebViewでも使える
  • 絶対にかわいい絵が主役
  • パーツのUIはネオンなイメージ

前もって全パーツ画像をフェッチする作りになってるので、確実に200リクエスト分くらい待つことになります。
ここの構造は最後まで迷ったんですけど、随時読み込みして遊んでる最中に待たされるのは嫌だったので、最初に間を持たせることにしました。

そこでみんな大好きジャッジくんさんです!これが意外に好反応で、やったった感があってちょっとニヤニヤしましたw

あとは最近のモバイルなら余裕だろうということで、overflow: scrollとかふんだんに。

WindowsAndroidで確認してないのでそこだけ心残りが・・。
まぁ特に何も聞こえてこないので、なんとかなってると信じることにします!

やっぱりWebViewが嫌い

WebView内では、画像を長押ししても画像保存できません!\(^o^)/

なのでこのサービスのTwitterへシェアするまわりの導線は正直微妙です。
まぁそれでもシェアするボタンがあれば最近の人はすぐシェアしてくれるってのは前回学んだので、いちおう設置。

あとはTwitterのWebIntentも嫌いです。
なんで画像の添付UI無いねん!

バックエンドについて

常時3000人がうちのサーバーに滞在するみたいなのが数時間あって、ほんとにひやひやでした。
何を隠そうサーバーサイドはなんとなーくでやってるので、今の構成でどれくらいまで耐えられるかとか、サーバー落ちたらどうするかとかノープランでした。
というか、今もノープランです。

サーバーはさくらVPSの3コア、メモリ2GBのスペックで、そこでNginxが一人でがんばってくれてます。キャッシュサーバーとかないです。

  • worker_processesはコア数と同じ3
  • worker_connectionsは安定の1024
  • gzip(html/css/jsのみ)

っても画像のレスポンスが一番多くてしんどいので、そこをなんとかしたいんですがノーアイデアで困ってます。
とりあえずTwitterのトレンドからは降りたのでもう大丈夫やろーと思ってますが、このあたり詳しい方・・リプでいいのでぜひにアドバイスください・・。

おわりに

正直このサービスがこれほどの反響を得たのは、@jenga_inkさんの絵ありきなので、改めて大きな拍手をお送りくださいって感じです。

ボーイ版がぜひ欲しいとか、あのギアがないとか、そのへんはきっと追々対応してくれると信じましょう、うん。

Twitter for Androidの仕様かバグかなんか知りませんが、in_reply_toな兼ね合いか無限にメンションがきて、皆様のマイイカがこれでもかと送られてくるのだけ少し煩わしいですが、まぁ良しとしましょ。

これでちょっとでもウデマエSとかS+くらいでタッグしてくれる人が増えたらいいな!