随分前から少しづつ進めていたんですが、Menthasのアップデートを年末にひっそりと行いました。
以下今回のアップデート内容です。
- React移行
- VueからReactに移行した*1
- ニュースカテゴリをスワイプで切り替えられるように
- 最初はreact-slickを使っていたがライブラリを使わずにつくりたかったのでscroll-snap-typeなどcssを使って実装することに
- CSSの細かい調整
- 特にスマホで閲覧しているときにタイトルとか見にくいなと思ったので微調整
- タイトルのテキスト色を微妙に変えたり
- パフォーマンス改善
- 具体的なコードは https://github.com/ytanaka-/menthas/pull/69 を参照
ハマっていたところ
scroll-snapでカテゴリを切り替えたときに、navigationのインジケーターやurlの方も同期的に変えたかった。しかしスワイプによるDOMの移動はCSS側に状態があり、これによってReact側でのstateの制御が難しい。結局コンポーネントのonScrollからev.target.scrollLeft
で移動量を取得してカテゴリの長さ分動いたら切り替わったことにしている。しかしこのやり方だと完全に切り替わった後でないとインジケーターが動かないので完璧ではない(本当はスライドの量に応じてインジケーターも動いてほしい)。
IntersectionObserverでisIntersectingを使いながら監視するやり方も試したが、素早く動かすとうまく動作しなかったりして安定しなかった(特に2つ飛ばしくらいでチャンネル切り替えたりすぐ戻したりしたとき)。プロダクションレベルで同じことをやるなら、scroll-snapで制御するのでなく全てReact側で完結するような仕組みの方が良さそう*2。
あと /javascript
みたいなurlで直接特定のカテゴリに遷移したいときに scrollBehavior = "unset"
しつつscrollIntoViewでscrollさせて表示している。このやり方は後輩に教えてもらったんだけど、カルーセルみたいなUIを作るときには良いアイデアだなと感じた。
今後どうするか
ローディングを表示している部分で従来のuseStateを使う方法でなく、React.Suspenseを使う方式に変更したいと思っている。 Suspenseが提唱しているデータ層からのthrowをUIがcatchして表示するというパラダイムは面白いと思ったし、componentのコードが簡潔になる感じがして良い感触を得たため。
そういえば最近はてな社から企業技術ブログ: エンジニアの技術ブログコミュニティというキュレーションサービスがリリースされていて、こちらが結構良い感じにみえる。なのでそろそろ当初のMenthasの役割も終わりつつあるのかなーとも感じている*3。
自分的には新しいシステムなり、なんなりを来年は作れればいいかなと思っている。
それでは良いお年を!