SessionStorageで快適な無限スクロールUXを実現!

ClubCloudのタイムラインでも無限スクロール(Twitterのように下にスクロールすると、もっと以前の投稿が追加されていく)を採用しています。

ところが問題があります。

無限スクロール、戻ると追加分消えてる問題

スクロールして新たに追加していった投稿が、他のページに行って戻ってくると消えてしまう
遡るためにまた取得し直さなければいけない!

当然っちゃ当然ですね。
また新たにタイムラインを読み込んでいるわけですので。
最初の読み込みで20件取得する設定ならば、追加で何十件取得していても、また最新の20件の表示になります。

とはいえ、ユーザビリティも悪いし、サーバーへのアクセスも増えて良いとこなし!
直したいですねこれは。

SessionStorageに保存!

SessionStorageはHTML5から登場したブラウザのストレージ。
Stringfyしてしまえばほぼ何でも保存できます

【解決法】
1. スクロールで投稿をタイムラインに追加するたびに、SessonStorageにタイムラインを丸ごと文字列として保存

2. 再びタイムラインのページに戻ってきたら、サーバーにリクエストせず、SessionStorageからタイムラインに埋め込む

3. その後AjaxでサーバーにSessionStorageに保存した以降の投稿をリクエストし、タイムラインに追加

といった流れで問題解決です。
jQueryだと、

#保存
sessionStorage.setItem('post_list', $('#timeline').html())

#埋め込み
$(sessionStorage.getItem('post_list')).appendTo('#timeline')

で簡単にSessionStorageとDOMの行き来が出来るので楽です。

SessionStorageにタイムラインの保存がなければ、通常通り最新の投稿を既定の数リクエストします。 

SessionStorageの書き換え

例えば自分の投稿に変更を加えたときに、自分のタイムライン上で反映されている必要がありますね。
しかし、SessionStorageにあるタイムラインを埋め込んでいる限りでは反映できません。
ある投稿を削除してもSessionStorageには残っているので、タイムラインにまた現れます(もちろんアクセスしようとすると404は出ます)。

そこで、投稿を編集/削除するタイミングで、SessionStorageのタイムラインを一度HTMLに埋め込みDOM化します(display:noneをあて、ユーザーには見えないようにする)。
DOMになったらあとは書き換え/削除は簡単なので、変更を反映させて、再びstringfyしてSessionStorageに保存します。

こういった処理を行うために、投稿の編集/削除はAjaxで行い、変更に成功したら、SessionStorageをブラウザで書き換え、その後特定のページに遷移させます(変更即サーバー側でリダイレクトだとクライアントでの処理をする隙間がない)。

SesssionStorage削除のタイミング

 ちなみに同じことがLocalStorageでも出来ます。
が、永続的に残ってしまうため、ブラウザを閉じると揮発するSessionStorageにしています(ユーザーもブラウザを閉じた後もタイムラインが残っていることを期待していないはずです)。

あとはログイン時、ログアウト時にも消すようにしています。
前のアカウントのタイムラインが現ログイン中のアカウントのタイムラインに埋め込まれてしまうのはマズいので。

まとめ

ちなみにClubCloudでは、タイムラインだけでなく、マイページの自分の投稿一覧も同じ設計になっております。
タイムラインで削除したらマイページの投稿からも削除したり、投稿範囲をいじったらマイページはいじらずにタイムラインからだけ削除したりといった処理も行っています。

ほぼ何でも保存できるsessionStorage、便利です。
DOM保存も楽々なのでみなさん工夫して使ってみては!


今日もお読みくださりありがとうございます。
ほぼ毎日、アプリ開発や事業に関する日記を書いておりますので是非またお読みになってください!

この記事が気に入ったらサポートをしてみませんか?