読者です 読者をやめる 読者になる 読者になる

tom.mgzl.jpを作りなおしました

なんかメタブタワーそのものが燃えるという珍しい現象が起きていたので、前々からやるやる言っていたTower of Metab(ToM)を作りなおしました。

メタブタワーのコメントを一覧で見れるサービスです。基本的にIDコール合戦をほっこり眺める為のツールなので、IDコールがあるコメントのみを表示したりできます。

技術的な話

bh.mgzl.jpとほぼ同じES2015+Babel+Reactで作りました。前のバージョンはAngularJSを使っていたけれどReactの方が使ってて楽しいので良かった(小並)。

仕組みは単にはてブAPIをぐるぐる回しているだけです。サーバーへの保存もなし、以前はsettionStorageに一時的に検索結果を保存したりしていたけれど止めました。

あとメタブページのURLを入れても地上階から登ることが出来るようになりました。ただ、はてブの仕様上オリジナルのURLが途切れてしまっている場合は上手く行きません。

メタブの頂上

気がついたらまたメタブの頂上が変わってました。実は以前のバージョンは頂上だけは決め打ちだったので、今回のバージョンからは純粋に到達可能な頂上が表示されるようになりました。IDコール合戦の残骸が見られて楽しいですね。

デザイン

実はブコメ欄ははてブのコメント一覧にだいたい揃えてあります。大体なのは面倒くさいからです。

感想

物を作るのは楽しいですね。実はReactってこういうライトなサービスでも作るのは楽なんじゃないかと思います。この程度のサービスでES2015+Babel+Reactってのは大仰なんじゃないかって気もしますが。趣味サイトなんで、その辺の手段と目的論は余り意味が無いですね。

追記

細かい所結構抜けてるのを見つけてしまったけど、明日以降にしよう。

本当のベターなホットエントリーのアイディア

bookmark.hatenastaff.com

これを読んでふと思ったのだが、「お気に入られ数の上位X%がブクマしているホットエントリの記事」を出したら良さそうな気がしている。

実装の実現性

各ユーザーのブックマークはRSSATOMで取得ができる。(参考

ただ、どのくらいのユーザーを収集対象にするかが問題で、bh.mgzl.jpではだいたい27,000ユーザーくらいを捕捉している。これは、ホットエントリーや新着でブックマークをしたことがあるユーザーだ。例えばこれの1%となると、270ユーザーのフィードを監視することになる。

270ユーザーのフィードを毎回パースするのは辛いので、どこかでフィードを統合したい。複数のフィードを束ねる方法として以前はYahoo!Pipesがあったが今はないし、代替サービスも微妙だし、自前でやったほうがいいだろう。

厳密に言うとパースして統合するのは難しくないが、フェッチするのが辛いかな。はてななら検索クエリってわけでもないので、5分毎に270リクエストぐらい送っても大丈夫だとは思うが。

問題点など

お気に入られ数上位ユーザーがブクマしている記事ってほぼホットエントリーと同じじゃないかという気がひしひしとする。或いははてブのお気に入り機能を使えばいいじゃんというね。

上位ユーザーの新着、つまり上位ユーザーのブクマからホットエントリー入りしているものを除いたものは割りと有用性がありそう。

やるの?

実はbh.mglz.jpについてはいま根本的にクソ記事を上げない方法に行き詰っていて悩んでいる。かといってこれが「いいアイディアだぜ!!!!」という気もしていない。うーむ。

Reactに心酔してjQueryを捨てるべきか、或いはいつ古道具を売り払うかの話

React.js界隈の人に聞きたい

はてなブックマーク - ReactJS界隈の人に聞きたい

この辺を読んでbh.mgzl.jpでもReactを使っているので思ったことなどを書いてみる。雰囲気的には増田に概ね同意したい。

SPA前夜

SPAが使える道具になったのはlocation.hashを使ったテクニックやHistoryAPIが実際にモダンブラウザで動くようになったこの数年の話で、それまではそういう選択肢すらなかった。あったとしても、URLが変わらない不完全なものだった。 だから、1つのURLで1つの状態を表現するためには実際にページ遷移をさせるしか無かった。もちろんGmailとか例外的な物はあったけれど誰にでも実装できるようなものではなかった。

それが誰にでも使えるようになったのは、jQuery.pjaxのようなライブラリ(のプラグイン)が出てきてからだったと思う。だがjQueryのDOM書き換えは単純であまり効率的ではないので、例えば1000行あるリストをテキストボックスに入力した文字で逐次絞り込むみたいな機能はパフォーマンスが出なかった。特にCPUとメモリの限られるスマホでは。

だからこそ、SPAという選択肢は非常に限られたものだったし、jQueryMobileで巨大なWebアプリケーションを作るのは色々な面で難しかった。

我々は新たな道具を手に入れた

そこにAngularJSやReact.jsが登場したことによって、誰もが選びうる選択肢の1つとしてSPAが加わった。今まで自分のような凡人が作れなかった物が作れるようになったのだ。歓喜以外の何物でもない。

だがライブラリは道具だ。道具は必要な時に必要な物を選んで使わなければならない。4tトラックを手に入れたからといって原付きバイクが不要にはならないだろう。

AngularJS 1.xの失望もあり、もしかするとReact.jsが空飛ぶ車ではないかという希望を持ちたい気持ちは分かる。実際にjQueryは空飛ぶ車だったし、それに乗ることができたことに感謝もしている。

React.jsに乗るべきか

今はまだReact.jsが空飛ぶ車であるかは分からない。だが少しぐらい乗っておいて損はない。JavaScriptを書ける(≠jQueryを書ける)人間にとっては学習コストも大したことが無いし、今乗っておくことに損はない。

だが実際にその道具を使うかどうかはまた別の話だ。SPAという概念やReact.jsといったライブラリは単に選択すべき道具の1つに過ぎない。

新たな道具を手に入れたからと言って、古道具を捨てて新しいものしか使わないのは愚かである。ことさら技術という道具においては、実際に場所をとるわけでもないのだから本当に不要になったその時に捨てればいい話だ。

「5年後のビジョンは何だ?」「あ?ねぇよそんなもん。」

しかしフロントエンドをやっている人間で、5年後のビジョンを持っている人は少ないだろう。それを持っている人は非常に優れたエンジニアとして賞賛していい。

昔から(当時は単にWebデザイナーやコーダーと呼ばれていた)フロントエンドエンジニアは常に「今」と戦ってきた。ブラウザは更新され続け、新たな概念のデバイスが誕生する。

そもそも「今どきのアプリケーション」は環境の変化によって5年も持たない。どうせ5年後には作りなおすことになるので、だったらいま使える道具は使っても構わないだろう。そういう意味でReact.jsはよい道具である。

つまり5年後のビジョンなどくそ食らえだ。これだけ環境の変化が激しいと5年後の保守コストを見積もることなど不可能に近い。少なくとも自分は諦めた。5年後の話は5年後にしよう。まずは明日の納期の話だ。

(そう言って5年後にまた受注する、というのは別のお話。)

bh.mgzl.jpがv4.2.0になりました

更新内容

  • フィルタリング機能の追加
  • UIの調整、一部項目を「詳細設定」の中に移動
  • 更新情報を表示

フィルタリング機能

先日の記事に書いたとおりスコアなどが低い記事をフィルタリングして表示しないようにする機能を追加しました。
フィルタリングは「なし」「スマート」「ユーザー」の3種類で、ホットエントリと新着の両方それぞれに設定することができます。
「スマート」は主に直近50件(表示されている記事)の偏差値によってフィルタリングします。人気と新着でパラメーターを変えてあります。
「ユーザー」は任意に設定したブクマ数・スコア・スコアブクマ比によってそれ未満の記事を表示しなくなります。お好みの設定が可能です。

UIの調整

フィルタリング機能追加によって必要なインターフェイスが増えたので、詳細設定という項目にまとめました。 それに伴い内部的にも設定は1つのlocalStrageのitemに保存するようにしました。(これは単純に管理の問題。)
また、表示の設定も詳細設定の中に移動しました。

更新情報を表示

このブログに書いた更新情報が自動的に表示されるようになりました。

追記
書き忘れていましたが、詳細設定の中で記事を開く時に新しいウィンドウで開くかどうかが選べるようになりました。

更に追記
文章がグダグダすぎたので直しました。

bh.mgzl.jpの今後の更新予定

上に書いたものほど優先度が高いです。

フィルタリング機能(作業中、次回公開予定)

スコア・ブックマーク数・スコアブクマ比でフィルタリングする機能を実装中

  • フィルタリングは「なし」「オススメ(仮称)」「ユーザー(仮称)」の3種類
  • 「ユーザー」は任意にスコア未満の記事は表示しないようにしたりできる機能
  • 「オススメ」はわりと真面目に計算して、いい感じ(当社比)に低質な記事を非表示にする機能

記事スコアの炎上対策(上記が終わったら実装予定)

ブックマークが遅いユーザーほど記事スコアに対する影響を少なくしたい。 恐らく案1で上手く行かなかったら案2にすると思う。

  • 案1)現在既に実装済みだが、パラメーター等の調整で済ませる
  • 案2)3ブクマ目からの時間差によって調整する

任意のカルマ表示機能(そのうち)

カルマを見たいという要望があったのと、自分だけが把握できるのは少しずるいという気がするのでやりたい。

  • 入力したはてなIDのカルマを表示
  • 現在の補足済みユーザー数、統計等を表示

著しく質の悪いサイトの排除(やりたくないので多分やらない)

これを実装するということは記事スコアによる評価の敗北に他ならないので、これを実装するぐらいならサイトを閉じるかも。気が変わる可能性はある。

  • 案1)ドメインに対してヘイト値を貯めて、ヘイト値によってスコアに補正をかける
  • 案2)はてなフィルターみたいな単純なフィルタリングと、それをサーバー上で集計してよいデフォルトフィルタにする(AdBlock的な発想)

bh.mgzl.jpについて(v4.1.2)

はてなブックマークのホットエントリーにブックマークしたユーザーから独自に計算した記事のスコアを表示しています。 新着エントリーも見れますし、ブコメもその場で表示できます。 ブコメもスターの多い順にソートしたいのですが、ブコメパーマリンクごとにはてなスターAPIを叩かないといけないのでやめました。 (はてブAPIのレスポンスに含めて欲しい)

対応OSはGoogleChromeiOS Safariです。他は面倒なので確認してませんが、まともなモダンブラウザならきっと動きます。

あと実験的なサービスなので、私の気分次第で仕様が変わります。

技術的なこと

さくらのレンタルサーバーでフロントエンドはReact+jQuery、バックエンドはPHP+MySQLで動いています。 Gulp、Browserify、Bable、LessCssあたりを使ってES6(JSX)で書いてます。 バックエンドでは特にフレームワークは使っていません。 RSSや各ユーザーの情報はcronで定期的に収集しています。

記事のスコアの計算方法

スコアは主にブックマークしているユーザーに基いて計算しています。 バックエンドで各ユーザーの独自に計算したユーザースコア(カルマ)を保持していています。

ユーザーのカルマの計算方法

はてブお気に入られ数とスター数などから計算しています。

記事の並び順

選択した並び順は、localstrage内に保存されます。

はてな

はてなRSSそのままの順番です。人気エントリーや新着エントリーとほぼ同じ並び順です。 "ほぼ"なのは、はてなのサイト上には表示されずRSSには表示されるものがあったり無かったりするという噂を聞いたことがあるからです。(曖昧)

スコア+日時

記事のスコアと日時をから計算した並び順です。Redditで利用されているアルゴリズムに、スコア・ブクマ比を足して算出した数値を元に並べています。 新しいものは上の方に表示され、スコアが高いものは上に留まりやすい、と考えて下さい。 詳しくはHow Reddit ranking algorithms workを見てください。 また後にブックマークしたユーザーほどスコアに対する影響力が減っていくような補正がはいっています。 オススメの並び順です。

スコア

計算したスコア順です。 当初スコア順だけ実装するつもりだったのですが、微妙に使いづらいのであまりオススメできません。

日時

はてなRSSは記事の時間ではなく、観測された時間(ホットエントリーに入った or 3ブクマついた)時点の時間が記述されているようなのですが、 何故かRSSの個々のアイテム自体は別の順番で並んでいます。(はてブ7不思議の1つ)