2022年2月26日土曜日

手書きIME のメモ帳を作った

メモ帳として使える 手書き IME を作ってみました。



最初は一筆書き IME を作りたいと思ったのですが、画数が増えると精度が微妙でした。 ひらがな/カタカナはほぼ 100% 認識するので残念。 漢字は学習データを改良しないと思ったとおりに入力できなそうです。 すぐには無理そう。という訳で平凡な手書き IME のメモ帳にしました。

なるべくコンパクトな UI の IME を作りたいと思っていたので、 canvas の大きさを色々と実験しました。 結論としては、画数の多い漢字を小さな canvas で書くのは大変で、90px は必要でした。 iOS では canvas の外枠に触れると誤反応が起きるので、 やや大きめにしたほうが良さそうで 120px くらいが良さそうです。

120px という数値は IME としてはとても小さいです。 たとえばフリック入力や仮想キーボードは 200〜300px くらい専有して邪魔ですよね。 いつか使えるかもなあと思ったので、とりあえずコミットしときました。 まあ Android / iPhone の IME は JavaScript で書き換えられないので、限界はあります。

今はメモ帳として使うくらいが関の山ですが、現状でも割と便利な気はします。

2022年2月23日水曜日

英文法の並び替え学習アプリ Grament を作った

Sentency より日本英語ちっくに、平易な文法を学ぶアプリとして、Grament を作りました。 Sentency はふんわり口語の英文法を理解するのに使いやすいですが、小さな子が音声なしで学んだり、HARD モードで学ぶのはキツイです。 もう少し文法を固めるアプリも欲しいと思いました。 Grament では Sentency と異なり、平易な文法ごとにくり返し学習します。 例文は頑張って作ったので割と大変でしたが、ひとまず中1英語までサポートしました。 漢字はなるべく小学漢字の範囲に収めました。



わかりやすい学習順序で文法を学ぶ

文法を学ぶ順序については、結構色々な参考書を見て考えました。 中レベル向けの参考書って、どれも文法がごった煮で学んでいますね。 唐突に What が出たと思ったら、When はもっと後で学んだり、ぐちゃぐちゃです。 I / You はすぐ学ぶのに、We / They はずっと後で学んだり、次の学年のものが混在していたり、いまいちよくわかりません。 平均以上の子も想定して量を増やしているからと思いますが、そのような構成だと再利用性が低いですね。 もっとわかりやすい構成があると思うし、指導要領の改定を考えると、参考書の並び順はコストが掛かりすぎると思いました。 個人的には英語は基本的なルールを掴めば、覚えるべき文法も練習もほとんどないと思っているので、 文法はあっさり学んであとはひたすら演習のほうが、良いんじゃないか。

低レベル向けの参考書だと綺麗に体系化されていて、私もそちらのほうが絶対わかりやすいと思っているので真似しました。 低レベル向けの参考書では、いきなり SVOC をサラッと学んでいて、とても良いです。 そして人称代名詞をどーんとすべてまとめていて、とてもわかりやすい。 「これだよこれ」という気持ちになりました。 ただ低レベル向けの参考書だけだと足りないものも多いのです。 たとえば受験や英検を想定するなら、練習量が足りませんね。 Grament は低レベル向けの参考書の補完になる実践アプリになると思います。 中2以上はまだできていませんが、中1の英文法さえ押さえてしまえば、Sentency を活用しても良いし、何とかなるでしょう。 残りはじっくり作っていきます。

文法アプリって名前を考えるのが難しいね

どうでもいい話ですが、今回のアプリ名は結構色々と考えました。 Grammar という単語は長い上に代替案がないからです。 Grammarly や Grammy と被ると面倒なので大変でした。 最近は、なんちゃらgram という名前を付けるのが流行っている気がするので、そこを真似しようと考えました。 そもそも programming とか gram ってどういう意味か、私は考えたことがありませんでした。 語源は program → pro [前に/へ] + gram [書かれたもの/作品] らしいです。 文法の grammar は gram[書く] ar [性質] じゃないかな。 ar 以外の性質を示す接頭辞 ent / al / ive / or と gram を繋げた造語の中で、 grament は響きも良いと思ったので、これに決めました。 接尾辞 ment は [こと] の意味もあるので、まあまあわかりやすいかな、と。

2022年2月19日土曜日

drop-inline-css を作った

drop-inline-css というコマンドラインツールを作りました。 HTML ファイルを解析して不要な CSS を削除し、インライン化した HTML を生成するビルドツールです。 設定ゼロの超お手軽ツールです。

drop-inline-css

実のところ、私が真面目なサイトを作る時は、似たようなビルドツールを作って動かしていました。 いい加減なサイトにも同じ仕組みを適用したいと思い初めて、作り直しました。 作り直した理由は、esbuild のように、ツールチェインがだいぶ高速になってきたからです。 まず parcel/css が出てメンテの大変そうだった CSS Minify に決定版感が出てきました。 HTML Parser は中身を操作しようとすると選択肢が一気に減るのですが、 node-html-parser が早そうな上に、使い勝手が良かったので採用しました。 普通は jsdom あたりを使うのかな。 そこにみんな大好き DropCSS を組み合わせます。 現時点で最速/最高性能と思われるライブラリを組み合わせると、割といい感じです。

ボタン一つでサイト全体の Critical Path を最適化

さて drop-inline-css の使いどころですが、シンプルなページの Critical Path の最適化 (above the fold) に使えます。 ちなみにツールでは画面内に収まっているかのチェックなどはしておらず、HTML 全体の外部 CSS をインライン化しているだけです。 そのため簡易的なページにしか使えませんが、個人的にはそれで十分と思っています。 複雑なページなら他のライブラリを使えばよく、シンプルな大量のページをストレスなく最適化するほうが大半のニーズだからです。 また Critical Path を手作業で抽出した後に適用しても良いですよね。 わざわざ Critical Path の自動抽出のような、実行時間が極端に遅くなるような処理を実装する必要はないと思ってます。

drop-inline-css は、たとえば Bootstrap のインライン化には使いやすいです。 Bootstrap の CSS をそのまま読み込むサイト場合、160KB くらいロードしてからレンダリングが始まります。 drop-inline-css で不要な CSS を削除してインライン化すると、ほとんどのサイトは 5〜20KB でレンダリングを始めることができるようになります。 あとから元の Bootstrap を読み込むので 10KB くらい通信量は増えてますが、体感的にも Pagespeed Insights のスコア的にもかなり向上します。

最近は CSS in JS が流行っているので、Critical Path の最適化はやっている人のほうが少ないかな? 個人的には CSS in JS よりこちらのアプローチのほうがずっと楽だと思うんですよねえ。 Node.js や JavaScript Framework、そして Webpack に頼り過ぎると、設定とマニュアルに振り回されがちになり、逆に苦労が増えることのほうが多い気がします。

ローカルビルドでの利用例

drop-inline-css を使えば、何一つ悩むことなく、ボタン一つでサイト全体を高速に最適化できます。 tdewolff/minify と組み合わせると最強に思ってます。

ただ、Vercel / Netlify で使うにはどうするのが良いんだろう。minify コマンドとの組み合わせが難しいです。 ローカルビルドじゃないと苦労するかも。 まあ私はだいぶ前から基本的にはローカルビルドでやっているので、特に問題はないです。 デプロイサービス特有の設定を覚える必要がないので楽ですよ。 それが他の人に合うかはわからないですが、Hugo なら例えば以下のようにコマンドを打つだけでOKです。
hugo
drop-inline-css -r public -o public
minify -r public -o public
これだけで一番面倒な最適化が完了するので楽ちん。

2022年2月5日土曜日

Emoji Concentration を作った

Emoji Concentration を作りました。英語の神経衰弱ゲームです。 日本語版もあるので小さな子の語彙学習ゲームとしても使えます。



神経衰弱は英語学習では割とよく使われるみたいなのでササッと作ってみましたが、 覚えさせるフェーズが確実にあるので、確かに良い気はします。

一人でもプレイできるようにしましたが、何人かでプレイしたほうが面白いかも。 他のゲームと違ってスコア表示しにくいのが、唯一の欠点ですかね。