2020年2月23日日曜日

フリゲ紹介: タコバブル (Tako Bubble)

タコバブル (Tako Bubble) は、夢現iPhone / Android で遊べるパズルゲーム。

60 ステージもあり、頭を使って楽しめるタイプのパズルゲームです。 フリゲ界だとあまり広まらなかったけど、iPhone / Android では人気もあるみたい。 実際、サクサクプレイできて面白いと思う。



ゲームの仕組みは単純で上下左右キーでタコを操作し、バブルを集めるというシンプルなもの。 すべてのバブルを集める必要はなく、キラキラ光ってるバブルをぜんぶ集めるとステージクリアになる (左下)。 敵キャラの動きにも注意しないといけないですが、動くとやられる場所は×が表示されるのでわかりやすい (右下)。



ステージ 10 くらいから結構なレベルになってきます。 私もクリアには程遠いのですが、ときどき息抜きにプレイしています。 Android アプリの紹介だと「ほかの生物を気を付けて倒して、バブルの中に閉じ込められたビートルをすべて取り戻せ!」と書いてあり、確かにバブルを集めているとたまーにビートルが手に入る。

敵キャラはかなり色々な種類がいて (左下)、ステージ 10 からはうまく倒さないと先に進めなくなる。 他にも足場が崩れたりするようにもなって (右下)、すべてのバブルを集めるにはどうするか、結構考えさせられる。 難易度は高めのパズルゲームだと思う。 とは言え何度でもリトライできるので、良い感じに頭を使える難しさかも知れない。



難易度が高めの頭を使うパズルゲームをしたい人には良い作品と思いました。

2020年2月2日日曜日

uWebSockets が高速 Web Framework の新定番になるかも

巷で有名な Web Framework、例えば Rails は激遅です。速度が必要な場合には、高速な HTTP/HTTPS のルーティングができる Web Framework が必要となります。 しかし高速 Web Framework にはこれまで決定打がありませんでした。

ベンチマークの基盤自体は結構前から整っていて とても参考になるサイトがある のですが、 少し考えてみればわかるように、速度だけを重視すれば機能を小さくするべきであり、サポートが落ちて採用が不安になってくる。 結果、速度は早いけどサポートが甘いフレームワークは 先ほどのベンチマークサイト からも消される状態になってました。 速度を重視しつつサポートも手厚いフレームワークは、これまでなかったのです。 探すのも大変になり困っていたのが、少し前の状態でした。


ところが最近、このベンチマークのランキングの「裏」にやたら名前が出てくる基盤フレームワークがあることに気付きました。 それが µWebSockets というもの。 WebSocket もできるけど、HTTP のルーティングもできる基盤フレームワークで、ものすごく早い。 2016年にリリースされていたようで、なんと HTTP/HTTPS サーバの h2o より早いらしい、凄いな。 じゃあなぜ名前が直接載っていないのかというと、Web Framework ではないから…なのだろうけど、Node.js で高速 Web Framework として有名な Fastify よりずっと早いことが報告されている。 なんかもんにょりする話だけど、Web Framework Benchmarks ではよくあることなので、あまり考えないことにする。


引用: uWebSockets


C/C++ で実装されており、2016 年からあったのですが、Node.js、Python へのバインディングがつい最近リリースされました。 主要言語で利用しやすくなってきた。 仮想通貨系の企業のサポートを受けているようで、既に結構な量の採用があるらしい。 新規採用にも安心感があるように感じる。 Python 版の µWebSockets.py は、昔から爆速 (だけど alpha stage) なフレームワークとして有名な Japronto より早いらしい。 Node.js 版は µWebSockets.js が本家だけど、Web Framework っぽく作り変えたサードパーティ実装が高速 Web Framework のランキング上位にある。 Express 寄りの実装になっているとのことで速度は落ちてそうで、本家で実装すればそれより早いのではないかな。

使いやすさを改良してサードパーティ実装を作り始めるとサポートの問題が出てきてしまうと思いますが、処理の根幹部分は µWebSockets で変わらない。 事実上これを利用すれば良いのではないかと思うし、言語ごとのバインディングがもっと作られるようになれば、一気に広まる気がする。

高速 Web Framework もついに定番ができたのかも知れません。

2020年2月1日土曜日

Web components の最適化プロセスへの考察

新しい Microsoft Edge がリリースされ、template / slot タグがついに IE 以外でサポートされました。 いずれ死にゆく IE は polyfill で十分とするなら、ついに Web components で事足りるかも知れない時代が来ている。

これまでは Web components という概念がなかったので、jQuery で DOM を簡単に弄ることから始まり、 テンプレートとして Virtual DOM という概念が生まれました。 Virtual DOM だけなら Vanilla で実装すれば良いと私は思うのですが、 簡便性を求めて数多くの JavaScript Framework が生まれました。

しかし今や JavaScript Framework を使わずに Web components だけで作れます。 まずは容量がすごく減ります。 どれくらい減るかは、web-components-todo というわかりやすいサイトがあるので引用すると、単純な ToDo アプリでは いま人気の React / Vue / Angular の 1/10 以下になります。 ついでに 速度も早くなる引用したサイトは、様々な JavaScript Framework の実装例も載っているので、とても参考になる。 このような利点はわかっているのですが、実際に実装するとどんな欠点があるか、少しだけ考えてみました。


レンダリングブロックに注意

template / slot の仕組みは、真っ先に気付いた問題点が 1 つあります。 それは template / slot で定義するのは良いけど、JavaScript のパースを伴うので遅くないかということです。 既存のシステムは first view (above the fold) は CSS のパースだけで済ませ、JavaScript は body の最後に実行することで速度を早めます。 template / slot に完全依存するとレンダリングブロックされてしまうので遅くなるのではないか、と思いました。

ゼロから検証するのは面倒なので色々探してみると、Bootstrap の機能を Web components でほぼ実装できているっぽいフレームワーク smart-bootstrap (当時の話で今は機能が変わっている) というものを見つけたので、これを使って検証しました。 サンプルページ を、ローカルサーバ上で確認したところ…案の定、遅い! head で 480KB (圧縮して 70KB) の CSS/JavaScript があり、明らかにレンダリングブロックしています。 未使用部分は削除できるとしても、JavaScript のブロックがキツ過ぎる。 つまり、Bootstrap のような CSS フレームワークの Web components 化は、思っているよりは簡単ではないです。 ガチガチにメンテするなら何とかなるかもだけど、フレームワークや手法がメジャーになる前にはやりたくはないかなあ。

特に above the fold との行き来をどうするかの問題はあると思います。 Web components に完全に頼ると、最適化してもレンダリングはおそらく遅くなるでしょうから、 above the fold はベタ書きして上書きするのが間違いなく最速でしょう。

no-JavaScript な人のためには多用は良くない

JavaScript 動かないようにしている人を最低限サポートするなら、Web components は多用し過ぎないほうが良いかと思います。 そのためあらゆるタグを Web components 化するのはあまり現実的ではない。 SPA はガン無視してるとこ多いけど、あんま良くない。

CSS は管理しやすくなるが肥大化しやすくなるかも

Web Components ベースのコンポーネントはページすべてに使うのは速度的にアレな感じがするけど、思想自体はとても良いものです。 例えばブログに Bootstrap のコードを載せたいなと思っても、CSS リセットが入っているから、ライブラリをロードするとページが崩壊してしまうんですよね。 使うとこだけ make して style で貼り付けて…とか、変なことを色々やって、ようやく使えます。 Web components ベースなら CSS のスコープが閉じているので、コードを載せたいコンポーネント部分をインポートするだけで使えます。 これは超絶に楽です。

ただよくよく考えてみると、そんなに話は簡単じゃない。 Shadow DOM もドキュメントレベルのスタイルから継承を利用するため、 様々なライブラリを組み合わせるときには、CSS リセットを想定しないといけない。

完璧な汎用性を目指すために世の中の CSS は CSS リセットを想定します。 しかし CSS リセットをしてしまうと、コンポーネントとしての完全性が失われる。 色々なリセットが混在したコンポーネントの同一性を担保するのは、限界がある。 そして Shadow DOM 内のスコープが閉じているから CSS の使いまわしが効かない以上、うまくやらないと CSS が肥大化することが予想できます。 最適化の観点からは基本的にかなり不利になりそう。

JavaScript Framework は Native が戦場に

Web components は真面目に考えるなら遅延表示されるコンテンツにのみ使うべきものとわかりました。 遅延表示されるコンテンツならフレームワークはそれほど問題ではなく、React, Vue, Svelte, Angular、Web components、何を使っても実際良いように感じる。 というのもレンダリングブロックにさえ気を付ければ、template 内に style, script が遅延ロードされるからです。 フレームワークのラップの読み込み時間くらいの差しかない。 とはいえ機能差がないなら速度を求めるのが信条なので、私は Web components を使うと思う。

JavaScript Framework はどちらかと言えばラップのほうが重要で、ラップするからこそ Native 方面を抽象化できている意味合いがある。 だからこそ巷では Vue Native, React Native, Flutter, Blazor がみんなの興味の気がする。 ただ Flutter をなんとなーく触ってみようとしたのですが、フレームワークがでかいでかい。 アップデートをかけようとしたらメモリ 4GB のマシンが落ちました。 現状では Native のための仕組みだなと痛感しました。

あくまで Web の世界から Native の世界を見るなら、分厚いラップをかけた後に頑張って Web に変換し直すのは、そんなにいいかなあ、という感じ。 Native 側も乱立してきて考えるのが面倒だし、まだまだ大きな変化はありそうです。 どちらかと言えば CSS Framework の柔軟性をそのままに、 Web components からお手軽に変換できるような bindings を作って欲しいなと思ってる。