LDRに代わる新しいRSSリーダーFeedponを開発した

f:id:emonkak:20170929225749p:plain

はじめに

LDRが終了するということで、FeedlyをバックエンドにしたWebブラウザ上で動作する新しいRSSリーダーFeedponを開発した。 現在の所FirefoxのアドオンChromeの拡張として配布している。 他にモバイル版として、CordovaでパッケージングしたAndroidiOSアプリがあるものの、ストアでは配布していない(お金がかかるので)。 モバイル版を利用する場合は各自でビルドしてインストールする必要がある。

本稿は今回開発したFeedponの設計思想とその特徴を語るものである。

背景

自分が長年愛用していたRSSリーダーLDR(Live Dowango Reader)が2017年8月31日をもって終了と告知された。 終了の告知はLivedoor時代から数えると2度目で、今回はいよいよ本当に終了した。

実は、一度目の2014年10月の終了告知から、新しいRSSリーダーを作ることを構想し実装を進めていた。 LDRが終了するということで代替手段が必要になったが、他のサービスでは満足いくものが見付からなかったからだ。

しかし、この時はLDRの権利がドワンゴに譲渡されることになり、サービスの再開が決まった。 ここで一旦、新しいRSSリーダーの開発は止まっていた。 それを今年(2017年)に入ってから再開して、同年7月に一応の完成を迎えた。 その後すぐ、ある意味タイミング良くLDRの2度目の終了が告知され、公開に至るという流れだ。

バックエンドとフロントエンド

RSSリーダーの機能はバックエンドとフロントエンドに大別することができる。 フィードの巡回、購読や未読の状態を管理するのがバックエンド、対してフィードを読むためのUIを提供するのがフロントエンドだ。

バックエンドの機能についてはサーバーに実装されることが多い。 バックエンドがサーバー、フロントエンドがWebで提供されるのが、Webベースのサーバー・クライアント型のRSSリーダーだ。 サーバー・クライアント型は、購読・未読の情報をサーバー上に保存するので、それらの情報を複数の端末で共有できる。 また、フィードの巡回はサーバー上で自動的に行うので、ユーザーの端末に負担は掛からない。

一方、バックエンドとフロントエンドが一体となったスタンドアローン型のRSSリーダーも存在するが、現在の主流ではない。 複数端末で情報を共有できないし、巡回を自動で行なってはくれないので、使い勝手として劣るからだろう。

以上のことから、今回開発するFeedponについてはWebべースのサーバー・クライアント型を採用することにした。

バックエンドサーバー

Feedponでは外部サービスのAPI(Feedly)を利用しており、自前のバックエンドサーバーは用意していない。 ここではその理由について説明する。

ます、バックエンドサーバーの具体的機能を整理してみる。

  • 購読管理
  • 未読管理
  • フィードの巡回
  • エントリのお気に入り
  • フィードの検索

機能数は少なく、どの機能もシンプルで、実装上の工夫を挟む余地は少ない。 このことから、異なる実装のバックエンド同士を差別化するのは難しい。 差別化が難しいのであれば、サーバーを自前で用意するメリットも少ないだろう。

唯一差別化が容易な点としては、API応答時間や、フィードの巡回間隔などの、パフォーマンスに関する部分だろう。 パフォーマンスを最適化するのであれば、高スペックのサーバーと、効率的なサーバーアプリケーションの実装を用意するのはもちろんのことだが、サーバーにアクセスするユーザー数を制限するのが最も効率的だ。 今はコンテナ技術や各種自動化技術によりサーバー実装を配布することも容易なので、そのために自分専用のサーバーを立ち上げるというのはそう難しくないだろう。 しかしながら、難しくなはいといっても誰でもできるほど簡単とは言えないし、サーバーの稼働コストが掛かってしまうという難点もある。

現時点ではFeedlyをバックエンドサーバーとして利用しているが、特に不満はなく、サーバー実装を自前で用意するつもりはない。 しかし、LDRGoogle ReaderがそうであったようにFeedlyもいつかは終了してしまうかもしれない。 それに備えてバックエンドを交換可能にできるようにクライアントを実装している。 もしFeedlyのサービスが終了したとしても、別のサービスに移行してもいいし、自前で用意してもいい。 RSSリーダーのような日常的に使うツールは長く使えるべきだと考えているので、特定の外部サービスに密結合することは避けている。 LDRは10年近く使っていたので、Feedponについても同じくらいは使うことを考えている。

クライアント

クライアントはRSSリーダーの使い勝手に大きく影響するUIを提供するものである。 ではこのUIに表示するものは具体的に何かと言うと、RSSあるいはATOMの形式で配信されたXML文章である。 そして、このXML文章の中にはエントリの本文がHTML文章がとして含まれる。 このことから、RSSリーダーのUI上にはHTML文章を表示する必要があり、そのためにはブラウザエンジン(HTMLレンダラー)が必要である。

そのため、UIをネイティブ部品を使ってネイティブアプリケーションとして作成するよりも、ブラウザ上で動作するWebアプリケーションとして実装するのがシンプルだ。 ネイティブアプリケーションとして実装しても、本文の表示にはブラウザエンジンが必要になるので、ネイティブのUIにWebViewを載せる形になるからだ。 それよりも一貫してすべてWebベースで実装してしまうのがシンプルだろう。

もちろんパフォーマンスについてはネイティブの方がいくらかは優位だろうが、クロスプラットフォーム展開が容易という点からも、Webアプリケーションの方がいいと考えた。

Webアプリケーションとして実装するのであれば、LDRがそうであるように純粋なWebサービスとしてドメインを取って配信することがまず考えられる。 しかし、Feedponはバックエンド(Feedly)との通信の他、エントリの全文取得、ブックマーク数の取得など様々な箇所でクロスドメイン通信を利用するので、これは不可能だ。 これらすべての通信でCORS(Cross-Origin Resource Sharing)が利用できれば良いが、当然そうはいかない。 そのため、Webサービスとしてドメインを取って運用するという手段は取れない。

では、Webアプリケーションを動かすためのプラットフォームが必要となる。 まず最近流行しているElectronが思い付くが、これは選択肢として入れることはなかった。 何故かというと、自分の使い方だとRSSリーダーでエントリを読んでいる最中に大量のリンクを開くからだ。 リンクを開く度にElectronとブラウザを行き来するのではとても使いづらい。 同じブラウザウィンドウのタブ上で開いて欲しいのだ。 そのために、普段使っているブラウザ上で動作するのが望ましいだろう。

ブラウザ上で動作するWebアプリケーションであれば、ブラウザ拡張(Extension)がある。 幸いにもブラウザ拡張はGoogle ChromeAPIをベースに標準化されつつあるので、Chromeの拡張を作れば対応ブラウザでであればそのまま動作させることができるようになりつつある。 Feedponは始めChorme拡張として開発していたが、実際にコード改変なしでChrome拡張をFirefox拡張として動作させることができた。

モバイル対応

前述のクライアントの項はPCを対象としたものだったが、今の時代モバイル対応も必須だろう。 LDRには使いやすいスマホアプリがなく、レスポンシブの考え方がなかった時代のものなので直接Web経由で見るのも困難で、スマホ利用がしづらかったのが不満だった。

Feedponは、モバイル版もPCと全く同様のWebベースの実装にして、レスポンシブデザインで表示を切り替えるようにした。 実装が同じなのでメンテンスコストが抑えられるとともに、手間を掛けずとも同じ操作感を実現できるものもメリットだ。 もちろんモバイルならではの工夫でより使いやすくすることもできるだろうが、違和感なくモバイル版とPC版を使い分けたかったので、同じ操作感を実現する方向に舵を切った。

モバイルであれば、ネイティブアプリケーションでの実装はパフォーマンスの観点では圧倒的に有利だろう。 しかし、実装に大きな手間が掛かってしまうのであえて避けた。 また、モバイルのネイティブアプリケーションは開発環境の変化がとても大きいので、メンテナンスコストも馬鹿にできない。 対して、Web標準技術で実装すれば大きくメンテナンスの頻度を抑えることができる。 現にLDRは10年以上も稼動していたが、サービスの終了さえなければまだまだ使うことができた。 長く使うツールだからこそ、メンテンナンスの頻度は極力抑えたい。 そのためにもモバイル版もWebアプリケーションとして実装している。

モバイル版のアプリケーションのパッケージングにはApache Cordovaを利用した。 CordovaでiOSAndroid、Window Phone等様々なプラットフォームに対応しているので、マルチプラットフォーム対応も難なく可能だ。 現在の所FeedponはiOSAndroidに対応している。

UIデザイン

f:id:emonkak:20170929224156p:plain

UIデザインはLDRのものを参考にして、モダンでシンプルなデザインを心掛けた。 コンセプトとしては印刷物としても成り立つデザインということで、Vertical Rhythmにも気を使っている。

印刷物としても成り立つデザインというのは、いわゆるフラットデザインにも通ずる所がある。 フラットデザインというのはWebデザインが紙媒体のデザインに近付いていく仮定だと考えている。 これは高DPIのディスプレイが普及してきたことと無関係ではない。 DPIが限りなく印刷物に近づけばWebデザインも当然のことながら紙媒体のデザインに近付いて行くという訳だ。 そうであれば、これからのWebデザインはDTPのノウハウを活かす機会が多くなるだろう。

フラットデザインについてよく議論の対象となるのは、ボタンなどの操作可能なUI部品のデザインをどうするのかというものがある。 操作可能なUIかどうかが分かりづらいという批判がまさにそれだ。

ここでレイヤーという概念を導入して、操作可能な部品には影を付けるというアイディアがマテリアルデザインだろう。 操作可能な部品に影を付けることで、そうではない部分との違いが明確になって分かり易くなる。

Feedponの場合、RSSリーダーという日常的に使うツールなので、操作可能な部品がそう分かり易い必要はないと考えている。 少々分かりづらくても日常的に使っている内に操作を覚えて慣れてしまうからだ。 それよりも、デザインとしての一貫性と可読性を重視して、一貫してフラットなデザインにした。

レスポンシブデザイン

モバイル向けのデザインについてはレスポンシブにして、共通化を図っている。 デザインはモバイルのものがベースで、そこから微調整をしてデスクトップ向けのデザインが存在する。 デスクトップのデザインをベースにしてしまうと、ボタンなどの操作可能な部品が小さくなってしまい、ディスプレイの小さなモバイル端末でタップすることが困難になってしまうからだ。 そのため、モバイル端末での表示を考慮したデザインでは余白を大く取る傾向にある。 余白を多く取ることでモバイルでの操作性や、可読性も向上するが、一方で一画面に表示できる情報量については劣ってしまう。 デザインリニューアルで一画面に表示される情報量が減ってしまって不評を買うというのは度々ある話だ。

Feedponでは余白を比較的広く取ってはいるが、情報量が減りすぎないように微妙な所で調整している。

特徴

ここではLDRにはないFeedponならではの特徴的な機能について述べる。

文展

f:id:emonkak:20170929224219g:plain

フィードに含まれるエントリの情報にエントリの全文が含まれいないことが度々ある。 これでは使い勝手が悪いので、様々なRSSリーダーでエントリの全文を取得できるようにするユーザースクリプトが往々にして提供されている。 LDRで言えばLDR Full FeedFeedlyであればFeedly Full Feedだ。

Feedponではこの機能を初めから本体に内蔵している。 仕組みとしては前述のユーザースクリプトと同様にWedata上で管理されているSiteinfo情報を利用している。 この仕組みは古くからあるもので、今となってはWebではあまり使われないXPathを使ってエントリ本文のノードを特定している。 それこそ今だと流行りのAIを使って本文を抽出するというアプローチもありうるのかもしれないが、この古い仕組みでも十分に機能する。 むしろこの仕組みだと直接本文のあるウェブサイトに直接クライアントからアクセスするので、外部APIに本文の抽出を依頼するのに比べ、ラウンドトリップタイムを最小に抑えられるというのがメリットだ(APIでキャッシュが効いていればその限りではないが)。

キーボードショートカット

f:id:emonkak:20170929224218p:plain

Feedponでは多数のキーボードショートカットが提供される。 そしてそのすべてをカスタマイズすることが可能だ。

現時点ではデフォルトのキーボードショートカットは以下のようになっている。 マッピングVimライクな記法で行い、マルチキーストロークマッピングも可能だ。

Key Command
/ Search subscriptions
<Escape> Close sidebar
<S-Space> Scroll page up
<Space> Scroll page down
? Show help
A Select previous category
G Go to last line
R Reload stream
S Select next category
V Visit website
a Select previous subscription
b Toggle comments
c Toggle stream view
f Fetch full content
gc Clear read entries
gg Go to first line
gm Mark all entries as read
h Close entry
i Open URL
j Select next entry
k Select previous entry
l Expand entry
p Pin/Unpin entry
r Reload subscriptions
s Select next subscription
v Visit website
z Toggle sidebar

はてなブックマーク連携

f:id:emonkak:20170929224217p:plain

RSSリーダーには人それぞれ様々な使い方があると思うが、配信されるすべてのエントリを読むという人は少ないだろう。 自分の場合、エントリを読むかどうかはタイトルと、そのエントリのはてブの被ブックマーク件数で判断している。

Feedponではエントリごとにはてぶの件数が表示され、件数の多い場合は件数の表示が目立つようになるので、注目されているエントリが一目瞭然だ。 また、エントリのパーマリンクRSS用のトラッキングURLが設定されている場合、はてブの件数を正常に取得できないので、トラッキングURLを展開する機能も内蔵している。 さらに、はてブのコメントを表示する機能も内蔵しているので、コメントもシームレスに読むことができる。

もちろん、はてブを使わない人もいるだろうし、そんな人にとっては不要な機能だろう。 しかし、そもそものコンセプトはLDRの代替として「自分のために作るRSSリーダー」ということなので、この機能を入れている。 はてブの件数を、Facebookのいいねの件数にするだとか、はてブのコメントをエントリに関するツイートの一覧にするなど考えられるが、自分が使わないという理由で、はてブ決め打ちとなっている。 もしかすると、今後そのようにカスタマイズできるようにするかもしれないが今の所その必要を感じていない。

おわりに

今回LDRに代わる新しいRSSリーダーFeedponを開発した。 個人的にはとても便利に使っていて、もうこれなしではいられないというくらい毎日使っている。 そもそも自分が使うために作ったプロダクトなので万人に使い易いとは限らないものの、自分と同じように気に入る人がいればいいとの思いで公開した。

もし、何か要望や問題があった場合はGithubIssuesにて受け付けている(日本人ユーザーしかいないと思うので日本語OK)。