ゆとり日記

心にゆとりを持って生きたいプログラマーの雑記です。気が向いたら書きます。

anime.jsを導入する

「なんかこう・・シュッって感じでスクロールアニメーションさせたい」

随分前にReact/Reduxの開発をやっていた時期にも同じ台詞を聞いたのですが、この台詞を再度聞く事になるとは思いませんでした。

自分が関わっているプロダクトではjQuery2系が余裕で現役です。手早く実装しようとすると「animateメソッドで特定の箇所までbodyを動かす」という実装に走りがちなのですが・・案の定パフォーマンス上で問題が生じたので対策を考えることにしました。

考えた対策

  • requestAnimationFrameを駆使して、自力で実装。
  • Web Animations API導入ワンチャン・・?
  • いい感じのライブラリを探す。

思い浮かんだのはこの3つです。

タイトルで言っちゃってますが、結果的には3つ目の方法を選択しました。 とはいえ、せっかくなので他の2つにも触れようと思います。

requestAnimationFrameで自力実装

僕は基本的に自力フルスクラッチを好む人間なので、まず自力実装を検討してみました。しかし、今回は自力実装はしない方針にしました。理由は以下の通りです。

動きのバリエーションを増やすのが大変

今回実現したい要件として「イージングをつけたスクロールをしたい」があります。

イージングの動きを自力で実装するのはなかなか大変です。多くの人が一度は耳にした事があるであろうベジェ曲線との戦いは避けられません。イージングの種類を増やしたいという要望が増えれば、自力実装は雪だるま式に増えていく未来が今から見えています。

メンテしていくのも面倒だし、他の誰かにそれをメンテナンスさせるのも嫌だったので、今回は自力実装はしない方針にしました。

※余談ですが、ベジェ曲線に入門したい方は以下のリンクがおすすめです。

blog.sigbus.info

Web Animations API

個人的興味はあったんですが、これも早々に諦めました。ブラウザ互換性がまだまだで、Safariの対応が無かったことが大きな理由です。

弊社プロダクトのユーザの半分がiPhone、つまりSafariユーザなのでPolyfillは絶対に必要です。Polyfill併用の運用もなかなかに手間だと考え、導入は見送りました。

いい感じのライブラリを探す

選んだ手段はこれでした。選定基準は以下の通り。

  • ブラウザサポートがそこそこ。
    • Android > 4.4、iOS Safari > 9を満たせてればOK。
    • IE11で動けばベター。
  • ドキュメントがある程度整っている。
  • ライブラリ本体が軽量である。
  • ライセンスはなるべくMIT。
    • プロダクト内で使う範囲を広げた時、ライセンスが足枷にならないようにするのが目的。

この辺りを踏まえつつ、↓のリンクを参考に選定したのがanime.jsでした。

The Top 9 Animation Libraries for UI Designers in 2017 — SitePoint

実装例のサンプルがやけに充実しているので、興味のある方は是非に。

animejs.com

デモ

ボタンを押すと画面最上部まで戻るだけのデモです。

codepen.io

jQueryに依存しないコードを書いたら、古めのChromeSafariで動かない地雷を踏み抜いたので、その辺の対応が入っています。

「動かなくない??」という方がいれば、コメントして頂ければ幸いです。

参考にしたリンク

新しいChromeでスクロールが取れない? scrollingElement? | Ginpen.com

古めのChromeSafariで動かなかった時に参考にしました。

結局のところ、比較的新しいのモバイル環境であれば「scrollingElement」をつかうで良いと思います。PCの場合がIE11を想定した分岐処理が必要にはなるでしょう。

ServiceWorker導入を一旦諦めようと思った話

自分が関わっているプロダクトにServiceWorkerを入れる試みを4月中盤からやっていたのですが、直近でやり切るのは無理そうな気がしてきたので一旦諦めました。(完全に諦めるわけではなく、地道に研究は続けます。)

その過程で検討した事を記録に書いておくことにします。

やり始めた経緯

社内で技術投資枠(業務時間の10%を使い、実業務に活きるチャレンジングな事をする仕組み)を設ける取り組みが始まったので、前から興味があったServiceWorkerを試してみたくなったのがきっかけです。

Safariで使えないしなー」という言い訳も通用しなくなりつつあるので、本格的に触らなければと思っていたのも理由の一つです。

入れようとしたプロダクトはどんなもの?

僕は今、リブセンスという会社でアルバイトを探すサービスの開発を担当しているのですが、ユーザの行動は以下の3つに絞れると思っています。

  • アルバイトの求人情報を探す。
  • アルバイトの求人情報の詳細を見る。
  • アルバイトに応募する。

ユーザに応募してもらわないことにはお金が生まれないビジネスモデルなので、応募率をいかに増やすかを考えなければなりません。

ということで、応募に辿り着くまでの体験を良くするためにServiceWorkerを活用する余地はあるかどうかを検討していきました。

実際に試してみる

検討したものは以下の通り

  • 静的リソースのキャッシュ
  • ページそのもののキャッシュ
  • プッシュ通知

静的リソースのキャッシュ

これはそこまで難しい話ではありません。

  • 何のファイルをいつキャッシュするか?
  • 運用フローをどうするか?

決めるのはこれくらいです。

ServiceWorkerのインストール成功時に、更新頻度の少ないファイルを選択してキャッシュしておく・・くらいの事なら楽にやれると思います。

とはいえ、今回の場合はキャッシュできるファイルが存外少なく、大した効果が見込めないことがわかりました。(手早くキャッシュに回せるのはロゴのが画像や、フォントファイルくらい)

リソースの更新が発生した場合のServiceWorkerの更新が煩雑になるだけな気がしたので、今回は一旦見送っています。

ページそのもののキャッシュ

どのページをキャッシュして、そのキャッシュをいつ破棄するのかが難題だなと感じています。

ニュースサイトやブログサービスであれば、TOP画面に出ている直近のコンテンツを幾つかキャッシュしておくのは良さそうと思っているのですが、今回の場合はどうすべきなのか非常に悩みました。(やたらとキャッシュしまくって通信料を食いすぎたら意味がないですし)

イデアベースで今回考えられたのは、以下の2つくらいでした。

  • 求人情報にレコメンドされて表示される求人をいくつかキャッシュ
  • 「後で読む」的な機能が存在するので、それに追加された求人情報をキャッシュ

イデアとしては悪くない気がするものの、一人で先走って実装するのは早計なので周りへの相談が必須かなというところに落ち着いています。

(ここ半年、一人で先走って失敗した経験があるので大分慎重になっています・・)

プッシュ通知

悪名高いアレです。

ページを初訪問した途端、「ども!!自分、通知いいすか??」と許可を求めてくるサービスも多く、辟易している方も少なくないと思います。

Rebuild.fmのように配信を通知してくれる使い方は素敵だと思うので、ああいうユーザ体験が増えるといいのですが・・。

というわけで、本番運用するまでの準備は相当慎重に運ぶ事に留意しつつ、アイデアを練ってみました。

「後で読む」している求人の掲載期限が切れそうになったら通知を飛ばす

弊社サービスでは「キープ」と呼んでいる機能があります。

「気になるし、とりあえず保存しておくか」という時に使う機能ですね。 キープしている求人の掲載期限が終わりそうになったら、キープしているユーザにお知らせ通知を飛ばそうという話です。

自分はTwitterの「いいね」を「後で読む」と同じような使い方で使っているのですが、自分でいいねした事を忘れてしまうことがよくあります。 (毎週末、整理するようにはしているのですが)

これと同じ話で、「キープ」されただけで応募されずに埋もれてしまっている求人は多いんじゃないかなーと、個人的に思うわけです。 (書いてる内に気になってきたので、分析したくなりました)

自分一人で進められる話でもないので、これも周りとの相談が必須ですけどね。

試してみた感想

技術的にも興味深い領域で面白くもあり、導入の検討を進める内にプロダクトへの理解も深まったのでやってよかったと思いました。

事業会社に転職して8ヶ月ほど経ちましたが、事業そのものへの理解を深める事への重要性を再認識しました。

「成果を爆速でリリース!」といかなかったのが残念ではありますが、地道にやっていこうと思います。

※手元のメモが消えていたので、参考にしたサイトのURLなどは後で発掘して書きます。

余談

PWAの研究も並行して進めていたのですが、manifest.jsonでフルスクリーン指定にする場合はUIをアプリと親しい構造にしないと逆に使いづらくなるという知見がありました。

Google I/Oのセッションは全然チェックしてないのですが、PWAのセッションはあるんですかね・・?

Railsを始めて一ヶ月半経ったので振り返りをする

「Webアプリケーションエンジニアになるぞ!」という意気込みで事業会社に転職し、Railsのプロダクトコードを書き始めて少し経ったので現状を振り返ってみる。

プロダクトコードでRailsを書いてみての感想

なかなかに楽しい。

設計を本格的に考えると答えは出てこないし、プロダクトコードはがそもそも複雑だし、PullRequestのレビューは厳しいし・・といった感じで頭を抱える事案は多いものの、自分の血肉となっているので良しとする。

実戦に入るにあたってやったこと・やっていること

定番のサイト達

  • Railsチュートリアル

    • Railsにもなかなか慣れなかったけど、Rubyの文化になかなか慣れることが出来ずに苦戦。
    • 1回の挫折を挟み、完走まで1ヶ月以上かかった。
  • Railsの教科書

    • Railsチュートリアルよりも内容がコンパクトだったので、一時期こっちに逃げていた。
    • 感覚をつかむには、まずこっちをやった方が良かったかなと今では思っている。
  • Ruby on Railsガイド

    • ActiveRecordがイミフ過ぎたので、ここのActiveRecordの基礎を何度も読んでいた。
    • ルーティングの書き方が分からなくなった時も戻ってきている。

この辺りの定番をやりつつ、最初はRailsの感覚を養うことから始めた。適当にググった情報を拾い読みしていると、断片的な知識が混ざって混乱してしまうので、しばらくは情報を意図的にシャットアウトしていた。

その他にやったこと

  • プロになるためのRuby入門

    • Railsを理解するにはRubyを理解しないといけないと感じたので、この本で入門していた。
    • moduleとclassの使い分けなど、モヤモヤしていた部分を解消出来て非常に助かっている。
    • Railsを始める人はとりあえず買った方が良いと思う。
  • Everyday Rails

    • rspecの記法に全然慣れることが出来ず、この本を見つつrspecの練習をやった。
    • contextの粒度を大きく過ぎてしまったり、subjectの挙動に毎回混乱させられたり、コードをDRYにしすぎてしまったりと苦戦はしているが、少しは慣れた気がする・・。
    • 困ったときは、とりあえずQiitaの参考リンクを見ている。

使えるRSpec入門・その1「RSpecの基本的な構文や便利な機能を理解する」 - Qiita

実戦に入ってみて感じていること

とにかく設計に悩む事が多い。

特に最近悩んでいるのが「controllerがファットになった時の対処法」。Viewに渡す情報が多い画面を作っていると、あっという間にcontrollerの処理が膨らんでしまい、対処法で毎回悩んでいる。

techracho.bpsinc.jp

迷った時は、ひとまず↑を見つつ考えることにしている。とはいえ、「View Objectでどこまでの事をやっていいのか」を理解できずに現在進行形で悩んでいる。

設計の話で進展があれば、またブログに纏めてみようと思う。

新しくみかけたビールを普通に呑む

はい。Beer Advent Calendar 2017の8日目です。

30歳になってからというものの、1日に2缶空けて晩酌するのが当たり前になってしまった僕が8日目を担当します。

本日のビール

今日はたまたまコンビニで見かけた「キリン ブラウマイスター」というビールを飲みました。

f:id:rukiadia0401:20171207204657j:plain

どうやら、セブン&アイグループで限定発売らしいですね。

感想

普通の一番搾りと比べると少し苦め。味はサッポロ黒ラベルに近い印象で個人的には好きな味です。

程々の重厚さで飲み飽きないので、今週はこればかり飲んでる未来が見えます。

オチは

ないです。酔っ払いの駄文です。

webpackでjQueryに依存したライブラリを含めてビルドする

概要

jQueryに依存したライブラリを含めつつ、webpackでよしなにbundleする必要があったのでやってみた。

試した環境は以下の通り。

webpackは「npm install --save-dev」で、jQuery系は「npm install --save」でインストールしておく。

configとかを簡単に書く。

webpack.config.js

const webpack = require('webpack');

const config = {
  entry: './src/index.js',
  output: {
    path: `${__dirname}/`,
    filename: 'bundle.js'   
  },
  plugins: [
    new webpack.ProvidePlugin({
      $: 'jquery'
    })
  ]
};

module.exports = config;

pluginsの箇所にProvidePluginの記述を追加。$にjQueryを入れてもらうように設定する。 bundle.jsの吐き出し先は好きに変えちゃってください。

index.js

// ProvidePluginで$に入れているので
// import $ from 'jquery'; の指定は不要
import 'jquery.cookie';

$(function(){
  // $にjquery.cookie.jsの処理が入っているか試す
  $.cookie("name", "myname", { expires: 7 });
});

これをwebpackでビルドし、htmlを適当に作って、bundle.jsを読み込めばcookieが書き込まれているのを確認出来ると思います。

参考にしたページ

https://webpack.js.org/plugins/provide-plugin/

公式のドキュメント読むのが一番手っ取り早かったです。

転職してしばらく経ったし、手元の開発環境を少しずつ見直す

事業会社に転職して3ヶ月弱が経った。

相変わらずフロントエンドエンジニアをやっているわけですが、PHPとかRubyとかも触る機会が増えたり iTerm2を開いている時間が増えたりしていたので、普段使っている道具を見直す事にした。

WebStormからIntelliJ IDEAに乗り換え

前職でReact +Reduxをやっている時はWebStormで良かったわけですが、そうもいかなくなった。 そういうわけで、入社のタイミングで個人ライセンスを購入した。

※会社で買ってもらえなかったわけではなく、申請とかが色々面倒だったです。

Railsの勉強が落ち着いたら、これでKotlinの勉強も円滑に始められるのでサイコー!って感じです。

bashを使うのを止めた

会社が変わったら、周りにbashを使っている人が全然いなかったので変えることにしました。

周りの人にはzshを勧められたのですが、「ここはあえてfish shelklかな・・」という反抗的な精神が働いたのでfish shellを入れました。 クラスメソッドさんの参考記事を見つつ、fishermanとzを入れて使ってみている感じです。

三連休でちょくちょく手を動かしている内に徐々に慣れてきたので、仕事で使うのが今から楽しみで仕方ないですね。

メモアプリをInkDropに変えた

  • 仕様に関するちょっとしたメモを残す
  • ちょっとしたサンプルコードを書き残す

業務でコードを書く上でメモを残すことが欠かせなくなりつつあるのですが、しっくり来るメモアプリに出会えずにいました。

Macの標準メモアプリを使っても良いのですが、それだとコードを書くには微妙です。 ちょっとした事を書くために、社内のconfluenceを開くのもだるいです。

悩んだ結果、「やはりマークダウンだよね」ってことでInkDropを使うことにしました。

使い始めて2日しか経ってないですが、今のところ何の不満もなく快適に使えているので、トライアル期間の60日が過ぎたら普通に課金すると思います。

自分でmarkdownエディタを作るモチベはない

感想

不要なストレスが減り、快適に開発が出来ているなーという印象です。

今後も理想の開発環境を目指して、色々とチューン・アップしていこうと思っています。

Rubyの練習のためにProject Eulerを始めた。

  • 今いる会社がRailsメインだけど、Rubyに関してはド素人過ぎる。
  • 「週一でProject Eulerの問題を解く」みたいな集まりが会社で始まったが、何の言語でやるか悩んでた。

↑のような背景があって、Project EulerRubyの練習の場とすることにした。 どこにコードを載せていくかは決めていないが、qiitaかGitHub辺りにひっそりと載せていくつもり。

進捗

周りからRubyのアドバイスを貰いつつ、4問目を解き終わった辺り。とはいえ、ただ解いただけで処理速度とかは全然考慮できてない。

一応、ここに問題とコードを載せてみることにする。

左右どちらから読んでも同じ値になる数を回文数という. 2桁の数の積で表される回文数のうち, 最大のものは 9009 = 91 × 99 である. では, 3桁の数の積で表される回文数の最大値を求めよ.

def palindrome? (number)
  number.to_s == number.to_s.reverse
end

palindrome_array = []
(100..999).each do |i|
  (i..999).each do |j|
    result = i * j  
    palindrome_array << result if palindrome?(result)
  end
end

puts palindrome_array.max

重複した計算を排除したり、eachの繰り返しを降順にするだけでも大分変わってくる気はするものの・・正直苦戦している。

目標

20問目まで解くのを、とりあえずの目標にしておく。頑張っていくぞ。