BASE BREAD 新作のシナモン味が完全食に革命を起した

注意

  • この怪文書は感情のままに書いているので過剰な表現が含まれます。みなさんは冷静な目で真実を判断してください
  • ステマや企業案件ではありません

結論

  • 一人暮らしで食事に手間をかけたくない人 (特にクリエイター) には完全食がオススメ
  • シナモン味がありえないくらい美味しいので興味があるなら買いましょう
  • メープル味も美味しいぞ!!

なぜ完全食なのか

食事には様々な役割があります。例えば、友達と行くご飯や飲み会などの「コミュニケーション」の役割、特別なイベントや嬉しいことがあったときなどの「お祝い」の役割、そして生きるための「栄養補給」の役割です。

私は人と楽しく食事をとることは好きですが、最後の栄養補給についてはあまり関心がありません。なぜなら私はプログラミングという行為を他の多くのことより大概は優先していて、他に劣らない高いモチベーションがあるからです。しかし、現実は非情で日常の中で最も多いのは「栄養補給」です。

困ってしまいました。これでは大好きなことを差し置いて、食事に時間をかけなければなりません。食事をとる行為にはスーパーに買い物に行って、レシピを考えて、調理をして、食べて、食器を片付けるという数多くのステップが存在します。こんなことをしていたら一日の中で書けるコードの数が少なくなってしまいます。

現在は幸いなことに対応策として外食やコンビニという素晴らしい文化が存在し、UberEats や出前館といった出前サービスも登場しました。しかし、どうしてもお金が割高になったり、栄養が偏ったりしてしまうため「栄養補給」への課題が残りました。この課題へのアンサーが今回のテーマの「完全食」です。

完全食とは

名前の通り、体に必要な栄養素を完全に (厳密には違うかも) 凝縮させた食事のことです。有名どころだと、COMP や BASE FOOD が提供している製品がこれに当たります。

これらは通販で購入できるためスーパーに行く時間を節約できますし、レシピを考える手間もほぼ省けます。更に外食や出前よりは明らかに安上がりです。(BASE BREAD は1食あたり300円程度)

完全食を選ばない理由はなくなりましたね!

BASE BREAD の良さ

ここまで良い言葉ばかりを並べましたが、もちろん完全食には悪い面もあります。結局完全食のいくつかは調理が必要でした。人類は粉を混ぜてシェイクする労力でキーボードを叩けますし、パスタを茹でる時間でバグを1つ潰せます。やっぱり完全食はわがままな僕の要望に答えられません。

BASE BREAD に出会うまではそう考えていました。

BASE BREAD は完全食の中でも特に面倒くさがりな僕にもってこいでした。なんとレンチン30秒でほかほかでふんわりとしたパンが食べられるのです。しかも、袋に入っている乾燥剤を取り出してそのままレンチンするので、皿が必要ありません。

勝ちました。

シナモン味が起した革命

ここまで読まれた賢いみなさんは BASE BREAD の魅力に気がついて、公式サイトでスターターセット (https://shop.basefood.co.jp/products/subscription) を購入しようとしていることでしょう。しかし、もう少しまってください!

実は BASE BREAD にも問題点があります。それは、「味」です。僕が食べていた普通の BASE BREAD は特徴がなく飽きっぽい味でした。さらに言えばアルコールに近い独特の風味があって毎日食べるのは難しいという人もいらっしゃると思います。(僕は毎日食べていましたが)

チョコレート味も食べましたが、「まあこんなものだよね」と言いたくなる味です。チョコパンとしては普通に美味しいレベルでも、毎日は食べられない味でした。(僕は毎日食べていましたが)

そんな中、最近「シナモン味」と「メープル味」という新作が登場しました。興味津々だった私はすぐに注文して数10分前にこれらを食べたのですが、その瞬間革命が起こりました。

「美味しい!!!!!!!!!!!!!!!!!!!!!!!!!!」

段ボールに一緒に入っていた冊子に書かれていたように、まずはレンチンをせずに食べたときの感想です。袋を開けた瞬間シナモンの香りが広がり、一口頬張るとシナモンのスイーツを食べているかのような錯覚に陥りました。メープル味もそこまで劣らず美味しいです。

次に30秒レンチンをしてからもう一度頬張りました。言うまでもありませんが、更に口いっぱいにシナモンの香りが広がって幸せな時間でした。メープルはレンチンするとシナモンに負けず劣らずというくらい美味しく化けました。冊子には「あたためるとホットケーキのような味わいにもなる」と書かれていましたが、正しくその通りだと思います。

まさか僕が完全食でここまで心を動かされて、ブログまで書いているとは思いもしませんでした。それくらい最高です。

まとめ

冒頭の結論で述べたように、食事に手間をかけたくない人には BASE BREAD のシナモン味とメープル味がオススメです。もし買って満足できたら僕の Twitter (https://twitter.com/saitolume) 宛に「お前のブログを読んで買ったけど、良かったぞ」と一言くれると嬉しいです。一緒に喜びます。

留年報告

はじめに

どうも、さぃと (@saitoeku3) です。
既に Twitter で報告したように、この度留年をしてしまったので詳しい事情をまとめておきます。

なぜ留年したのか

1 つ目の原因は、僕の優先順位の付け方が普通の人とズレていることです。

例えば

  • 学業よりクライアントが待っているタダ働きの仕事 (インターン) を優先
  • 学業より周囲の人が困っていることを解決することを優先

といった感じです。

この問題は以前から自覚をしていたのですが、自己犠牲で誰かにメリットを与えられるならそれでいいと思って放置していました。今までの大学3年間の中で B2 から B3 までは特にこれに囚われて自己犠牲を続けていました。

こんなことを書いていると「さぃとは留年を他人のせいにしている」と思われそうですが、これらは自己満足で勝手にやっていたことなので悪いのは僕です。(しかもメリットどころか迷惑をかけていたかもしれない)

2 つ目の原因は、プログラミングが楽しくてやりすぎたことです。

プログラミングに出会ったのは大学に入ったばかりのことでした。Web アプリケーションの受託開発をしている組織に加入したときに、HTML / CSSRuby を学びました。しかし、当時はグラブルと野球にドハマリしていたので、プログラミングは全くやらず RubyArray#each すらわかりませんでした。

転機は B2 の夏でした。相変わらず受託の案件はあるのに手をつける人がいなくなったので、仕方なく謎の優先順位の付け方で強引に 1 人で開発を始めました。技術的に頼れる人は周囲におらず、独学を始めると思ったより楽しくて、そこから JavaScript を学んで今の僕に至ります。

プログラミングは凡人だった僕をクリエイターにしてくれて、イベントやインターンに行くうちに多くの素敵な方と出会わせてくれました。 こんなものを知ってしまうとやめられなくなります。

3 つ目の原因は、僕の身体の弱さです。

知っている人は少ないと思いますが、僕は B2 の春から夏にかけて大学に通えなくなるくらいの頭痛に苦しめられていました。1ヶ月以上常に今まで感じたことがないほどの頭痛が消えず、頭痛専門の病院に行っても原因不明と判断されて完治はしませんでした。

今では寛解しましたが、時々偏頭痛の人と同じかそれ以上の頭痛が襲ってくることがあります。このときに落とした単位があれば進級できたというのは言い訳です。

懸念していること

留年したことによって、これまで築いた人間関係を失うことは避けたいです。
世代が変わることで、大学にいる限りは当然周りにいる人も変わります。そうやって交流が減ったり、距離を感じるようになったりするのは嫌なので今後も仲良くしてください。

あとは心が病まないか少しは気にしています。
「普通」から外れた経験は今までゼロだったわけではありませんが、やはり心配です。一緒に何か作ったり、ゲームしたり、ご飯に行ったりすると MP は回復しそうなので誘ってください。

今後の予定

ざっとまとめるとこんな感じです。

  • B3 前期: 休学、個人事業主として Gaiax 等の業務委託、内定先の内定者バイト
  • B3 後期: 復学して単位を取得して進級、個人事業主と内定者バイトを継続
  • B4 前期: 必修と取りこぼした単位の取得研究、個人事業主と内定者バイトを継続
  • B4 後期: 研究、個人事業主と内定者バイトを継続

本当はお金を貯めて海外に行ってみたかったのですが、コロナのせいで無理になりました。
せっかく 1 年猶予があるので、OSS 活動など他にも色々やっていきたいです。

Q&A

ここからは事前にマシュマロでいただいた質問を返していきます。

就職はどうするんですか?

2022年に pixiv に入社する予定です。
仮に他社から pixiv を上回るオファーがあってもこの気持ちは揺らぎません。

大学はどのくらいの頻度で行っていましたか?

先に挙げたタダ働きの仕事やインターン選考、就活、大きな技術イベント等があればそちらを優先していましたし、酷い頭痛に見舞われたときなどは休んでいました。

頭痛で通えなかった時期を除いて、単位取得を諦めた科目も含むと出席率は平均 80% 程度でした。

1年あるけどその間にしたいことはある?

個人事業主は始めましたが、まだ悩んでいます。
今後したいことを考える期間にするのもいいかもしれませんね。

金沢にずっといるつもり?

いるつもりです。
本当は東京で暮らしたいですが、コロナや生活費を考えると厳しそうです。金沢にも素敵な人はたくさんいるので、今まで通り楽しくやっていきたいです。

おわりに

留年を隠すために嘘を重ねるのは嫌だったので、正直に書きました。
ハッキリ言うと、今回の失敗は残念だけど現段階では後悔はしていません。1 年を失いましたが、得られるものや残せたものはたくさんあったからです。

しかし、両親や内定先で面倒を見てきくださった方々には本当に申し訳ないと思って反省しています。今後も失敗続きの人生だとしても、同じ過ちは繰り返さないように心がけます。

以上が、留年報告です。ここまで読んでいただきありがとうございました。
何か質問があれば、マシュマロ でお待ちしています。

『HOT PEPPER Beauty』Frontend スピードハッカソンに参加した

はじめに

こんにちは、さぃと (@saitoeku3) です。
今回はリクルートが主催するハッカソンに参加したので、振り返りや学びを残しておこうと思います。

ハッカソンなので最終的に順位がついて僕のチームは残念ながら 4 位でしたが、普段とは違う体験がたくさんできて最高のイベントでした。

イベントの内容

HOT PEPPER Beauty のあるページの速度改善を行いどれだけパフォーマンスを高められるかを競うハッカソンです。

レギュレーションは「Chrome Canary を使用する」「見た目の大きな変更をしてはならない」「機能の変更をしてはならない」というもので、Lighthouse の計測結果を参考にして順位を決定しました。

後に触れるのですが、参加者はフロントエンドだけではなくてバックエンドやインフラの領域まで自由に触ることができます。

やったこと

チームとしての施策は同じチームで大活躍してくれた @kaa_a_zuRecruit主催のスピードハッカソンに参加してきた にまとめているので、そこで確認してください。

僕の取り組みとどんな思いで取り組んだのかを書いていきます。

予習

行きの新幹線の中で超速本を読んだり、JSConf JP で行われたスピードハッカソンのリポジトリ を触ったりしていました。

実は以前超速本を読んだときに Scrapboxネットワーク処理の改善というメモを残しており、短い時間でこれを元に思い出しながら実践する時間を取れたのは良かったです。

アプリケーションの測定

1 番最初に環境構築が終わったので、すぐに Chrome Developer Tools で測定をしました。
よく使われるものとして思いつく施策はいくつかありましたが、アプリケーションによって抱える問題は変わってきます。がむしゃらにやっても効果は薄いので、最初に原因を明らかにしたのは正解だったと思います。

ネットワークタブのウォーターフォールの測定

DOM の描画を除けば初期描画までの時間の多くはネットワークが影響しています。
何が原因で通信に影響が出ているのか調べるためにネットワークタブのウォーターフォールを見ていました。

これは qiita.com のネットワークタブで時間がかかっている通信を順番に並べた様子です。
多くは画像の読み込みですよね。題材のページも同様に画像がボトルネックになっていました。

カバレッジの測定

これは pixiv.net の CSS と JS のカバレッジです。
Chrome Developer Tools を開いて Cmd + Shif + P の後に Show Coverage と入力すると表示されます。

トップを開いただけで全ての CSS や JS が適応されるわけではありませんが、使われていない赤色の部分が多いことがわかります。これらの多くは本来不要な通信を行ってパフォーマンスを下げていることになるので、理想を言うと削るべきです。

題材のページはもっと酷い状況でした。

施策の提案と実施

すぐ調べられる範囲では「無駄な CSS と JS が多い」「画像が大きすぎる」という課題を発見できたので、僕は次のことに取り組んでいました。

なお「題材のページが 1 ページのみで規模が小さいこと」や「全員が使い慣れているわけではないこと」を考慮して webpack は使用しませんでした

CSS の最適化

デッドコード (使われていない CSS) を削除するために PurgeCSSスクリプトを書きました。ただし、Qiita で見つけたサンプルはバージョンの違いによって期待する動作をしなかったので、途中でメンバーにパスして minify のスクリプトを書いていました。

minify には clean-css を使いました。ファイルの中身を渡すだけでシュッと簡単にやりたいことができて体験が良かったです。

JavaScript の最適化

uglify-js を使って minify をしました。選定理由は「題材のページは全て ES5 であるから」「使用した経験があるから」です。

webpack のプラグインとしてよく使われている (記憶が正しければ Webpacker に標準で搭載されている) terser でも minify ができるので候補としては考えていましたが、使い慣れていないので使いませんでした。(引き出しが少ないと窮屈で辛い)

画像の遅延読み込み

Chrome Canary を使っていたので最初は安心して loading="lazy" を採用しました。

しかし、行きの新幹線の中で標準の遅延読み込みよりも IntersectionObserverisIntersecting で画面に入ったか判定するほうがシビアに遅延読み込みを実現できることを確認していたので、途中からは lazysizes を使用しました。

※ 体感なので根拠は薄い

ここは自分で React 用のライブラリ を書いていたのことにも助けられて、スムーズに導入できました。

結果

これらに加えて画像の圧縮、HTTP2 化、リソースの gzip 化などを行ったところパフォーマンスは 97 まで改善させられました。
終了 30 分前までは他のチームに 300P 差をつけた 1位だったので優勝を確信しましたが、最終的には 4位 で終わってしまい悔しかったです。

タネ明かし

優勝チームは静的ファイルを Express から配信するのは遅いことを知っていたので、Nginx から直接配信することで高いパフォーマンスを実現していました。
Why is it not recommended to serve static files from Node.js?

そもそも Express は Node.js フレームワークの中でも遅い部類です。
fastify によるベンチ https://github.com/fastify/benchmarks

そして、主催者の 1 人である古川さんが次のように仰っていました。

実際にパフォーマンスタブを見ないと気づけない問題もあったので、もっと使えるものはフルで使って測定するべきだと思いました。

おわりに

今回のイベントでは、これまで僕がフォーカスを当ててこなかったパフォーマンスのチューニング方法とその重要性を学ぶことができました。

業務だとパフォーマンスとプロダクトの成長や DX はトレードオフだと思われがちかもしれませんが、今後はユーザーにとって本当に良いアプリケーションを開発できるように気を配りながら実装していきたいです。

最後にこのような素晴らしいイベントを開催してくださったリクルートと一緒に取り組んだ最高のチームメンバー、競い合ったライバルに感謝を述べて締めます。ありがとうございました。(またやりたい)

CLIP STUDIO の .clip ファイルを読み取れる JavaScript ライブラリを公開した

はじめに

こんにちは、さぃと (@saitoeku3) です。
コロナの影響で春休みの予定がことごとくなくなり、暇な大学生です。

ずっと引きこもっていてあまりにも暇だったので、何かしたいという気持ちが高ぶり、以下のツイート思い出して .clip ファイルの解析をしていました。

そこから色々考えた結果、Photoshop や CLIP STUDIO を持っていなくても .psd や .clip を見て楽しめるといいなと思い始めてサービスを作りたくなりました。

最近は FANBOX などの支援型プラットフォームを通して、多くの方がプロのイラストデータを入手できるようになりましたが、その全員が有料のイラストソフトを持っているわけではないため、楽しめるのは一部の限られた方です。もし、今考えているサービスが完成すると新しい楽しみ方が生まれそうで良くないですか。

ということで、下準備としてライブラリを書きました。

作ったもの

clipstudio.js - 📎A JavaScript library for using CLIP STUDIO .clip file on browsers and Node.js

ブラウザでも Node.js でも同様の API で .clip ファイルを読み取れるライブラリです。
既に実装されている機能について使用例を紹介します。

Node.js でサムネイル画像を生成する

Node.js は ClipStudio.load にファイルの Buffer を渡すことで初期化できます。 改行を含めて 8 行で .clip ファイルのサムネイル画像を生成できます。便利ですね。

import { ClipStudio } from 'clipstudio'
import { promises as fs } from 'fs'

const file = await fs.readFile('path/to/clip-file')
const clip = await ClipStudio.load(file)

const thumbnail = clip.getThumbnail()
await fs.writeFile('thumbnail.png', thumbnail)

ブラウザでレイヤーの情報を取り出す

ブラウザでは ClipStudio.load に input で受け取った File オブジェクトを渡すことで初期化できます。 インスタンスに生えている getLayers() でレイヤーの情報を取り出せます。

import { ClipStudio } from 'clipstudio'

const input = document.querySelector('input')

input.onchange = event => {
  const [file] = event.target.files
  const clip = await ClipStudio.load(file)
  const layers = clip.getLayers()
  console.log(layers)
}

レイヤーの型

残念ながら各レイヤーの画像データは .clip 上には保存されていない?ので、現在はちょっとしたデータしか扱えません。

type Layer = {
    id: string // uuid
    index: number
    name: string
    opacity: number
    isVisible: boolean
    isFolder: boolean
}

課題と展望

実は .clip ファイルを読み取るために SQLite を使用しているのですが、ブラウザでも動作させるために sql.js というライブラリを使っています。これは「SQLite を Wasm にしてブラウザでも動くようにした」という頭のおかしいもの (褒め言葉) なので、以下のような少々面倒なことがあります。

  • そもそもの実行速度が遅い
  • Jest でテストをすると .wasm の読み込みに失敗する

今後は処理を Worker に逃したり、Jest や Node.js と Wasm の関係について学んだりする必要がありそうです。このままだとテスト環境を自作する必要がありそうで面倒です(何か解決策はあるはず)。

また、ライブラリを充実させたくても僕一人で .clip を解析して API の仕様を考えるのはかなり大変です。将来的にドキュメントや議論の場を整備して複数人でやっていけると嬉しいです。

おわりに

今回は CLIP STUDIO の .clip ファイルを読み取れる JavaScript ライブラリの紹介をしました。

機能はまだまだ少ないので用途は限られてきますが、このライブラリの登場によって可能性は広がったと思います。今後も開発は続けていくので興味のある方は watch やスターをして暖かく見守っていただけると励みになります。

mixi の Bug Shooting Challenge #4 に参加しました

はじめに

どうも、さぃと (@saitoeku3) です。
今回は「周りの人はみんな行ってる。行ってないの僕だけ。」になっていた mixi のイベントに行ってきました。 mixi 主催のイベントは TDD や Git、Unity など様々なトピックに分かれていますが、僕が参加したのは Bug Shooting Challenge #4 (#mixi_BSC) でした。

イベントについて

僕とペアのさんぽしさん (@sanpo_shiho) が CRE (Customer Reliability Engineer) に配属されたという設定で、仮想のユーザーからの問い合わせに対してバグを調査して改善するという内容のイベントでした。

流れはざっと次のような感じです。

  • 環境構築
  • 使用技術の説明
  • ランチ
  • 問題1 - 3 (各問題ごとにヒントと答え合わせあり)
  • 懇親会

最初はガチでやるというより普段使わない筋肉を使って楽しもうという気持ちでしたが、想定より内容が面白くて競技形式ということで気がついたら夢中になっていました。

やったこと

参加者は最初に Rails + MySQL + Redis 等を docker-compose で立ち上げる環境とログを確認するための Amazon EMR が与えられます。

そこからは基本的どの問題もやることは同じで、ひたすら EMR 上のログを Hive で調べたり、Rails Console で問題に関係するレコードを調べたりしていました。僕は Rails には慣れていましたが、SQL (今回は Hive SQL) を叩いて調査するのは初めてで勝手を掴むのに苦労したのを覚えています。

ペアで行うので見つけたバグの情報や修正はすぐ GitHub や Slack で共有してお互いの共通理解を作るのが大切でした。

結果

3問中の1つで優秀賞をいただくことができました :tada: 正直もう少しできたという気持ちが強いですが、最初から最後までペアと楽しくやれたので割と満足できました。

おわりに

mixi さんにはイベントの準備・運営だけではなく、交通費の補助 (東京までの往復の半額) や素敵な懇親会の食事までいただけて感謝でいっぱいです。また、世代が近い学生と交流する場にもなったので多くの刺激を得られました。

mixi さんは毎年何度かイベントを主催しています。楽しいイベントだったので、このエントリを読んで興味を持った方は機会を見つけて申し込んでみてはいかがでしょうか。