Discourse は、画面に表示されるすべての投稿の読了時間を追跡します。このシステムは年々進化しており、その仕組みや存在理由を理解するために、コードを振り返る必要があることがよくあります。
この投稿では、現在の実装に関する痛ましい技術的な詳細について説明します。
Discourse クライアントがタイミングを追跡する方法
投稿のタイミング追跡は、screen-track.js.es6 で実装されています。このモジュールは、投稿が画面に表示されてからどれくらいの時間が経過したか、およびトピックが画面に表示されてからどれくらいの時間が経過したかを追跡する役割を担っています。
トピックページが「スクロール」すると、画面トラッカーに対して、現在表示されている投稿と、その中で既読の投稿を通知します。部分的に表示されている投稿も「表示中」とみなします。
その後、screen track は毎秒「tick」を発火させ、サーバーに送信する必要があるデータを決定します。
画面トラッカーは、複数のリストを保持します。
a. サーバーにまだ送信されていない(投稿/その投稿に費やされた時間)のリスト
b. 既読であるとわかっている投稿のリスト
c. 現在画面に表示されているとわかっている投稿のリスト
タイクの開始時(毎秒)、(a) に投稿がある場合、それらをサーバーに送信することを検討します:
-
flush_timing_secs(デフォルト 60 秒)の SiteSetting が、最後にサーバーにデータを送信してから経過している場合。 -
投稿のいずれかがユーザーによって「未読」である場合、リスト全体をすぐに送信します。
タイクの終了時に Discourse がフォーカスされている場合:
「画面に表示されている投稿」がある場合、各投稿に対して「1 tick」の時間を記録します。
任意の時点でトピックから離れる場合(Discourse の別の場所へ移動する場合)
「進行中」の (a) のすべてをすぐにサーバーに送信します。
制限事項
-
トピックを表示するたびに、投稿あたりの読了時間は最大6 分まで記録されます(離れてから再度その投稿に戻るとリセットされます)。
-
3 分経過してもスクロールが一切行われなかった場合、再びスクロールが行われるまでこのサブシステムは無効になります。
-
匿名ユーザーに対しては最大5 トピックまでのタイミングを記録します(これはユーザーが登録した際に posts_timing テーブルのデータに変換されます)。
重要な観察事項
-
post_timingsテーブルはミリ秒単位で追跡していますが、tick が発火するタイミングに応じて、投稿あたり「0〜1000ms」の「未記録」時間が発生します。 -
トピックを見る「セッション」ごとに、投稿あたりの読了時間は最大 6 分まで記録されます。投稿あたりの読了時間に上限はなく、ユーザーがトピックに戻れば、数日間にわたって読了時間を記録し続けることができます。
このデータをどのように活用するか
最も重要な情報は「ユーザー X が投稿 Y を読んだかどうか」です。これはトピックの未読数や、その他多くの重要なデータを決定します。
この二元的な利用を除き、post_timings に記録された時間を使用して、投稿の avg_time を計算します。
投稿の平均時間は、時間の自然対数の平均の指数(幾何平均)として計算されます。
例えば:
投稿 1: sam、10 秒
投稿 2: jane、1 時間
avg_time = exp((log(3600000) + log(10000)) / 2)
=~ exp((15.09 + 9.2) / 2)
=~ 189094
=~ 189 秒
この avg_time は、スコア計算機において「投稿スコア」の 構成要素 として使用されます。
スコア = 5 * 返信数 + 15 * 評価スコア + 5 * 流入リンク数 + 2 * ブックマーク数 + 0.05 * avg_time + 0.2 * 投稿読了数
したがって、上記の例では、投稿の平均読了時間 189 秒は 37 ポイントに相当します。つまり、約 2 件の「いいね」に相当するか、あるいは 72 件の読了に相当します。
「投稿スコア」は「ベストオブ」において、トピック内の最高の投稿を特定するために使用されます。


