0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

PDFビューアの「読了率・閲覧時間・離脱ページ」をどう設計するか考えた

0
Posted at

はじめに

最近、PDFを単純にダウンロードさせるのではなく、

  • ブラウザ上で読む
  • どこまで読まれたかを見る
  • どのページで離脱したかを見る
  • 実際にアクティブだった時間を見る

という仕組みについて考える機会がありました。

きっかけは、PDFを共有用のWebページとして公開する PDF to Link という小さなSaaSを作ったことです。

最初は、

PDFをアップロード
↓
URLを発行
↓
共有

だけで十分だと思っていました。

しかし、実際にPDFを営業資料・提案書・Pitch Deck・ホワイトペーパーとして使うことを考えると、単純なView数だけでは足りません。

たとえば、20ページの提案書が100回開かれたとしても、

  • 100人が最後まで読んだ
  • 100人が1ページだけ見た

では意味が全く違います。

そこで今回は、PDFビューアのAnalyticsを設計するときに考えたポイントを整理します。


1. まず「PDFを共有する」の意味を分ける

PDFリンクには、大きく2種類あると考えています。

Raw PDF URL

たとえば、

https://example.com/files/report.pdf

のように、URLがそのままPDFファイルを指す形です。

これはかなりシンプルです。

向いている用途

  • APIから直接取得したい
  • iframeや別システムから参照したい
  • 単純にダウンロードさせたい
  • .pdf で終わるURLが必要

一方で、人間がどう読んだかを細かく分析するには少し不向きです。


Viewer URL

もう一つは、

https://example.com/page/abc123

のようなWebページを作り、その中でPDFを表示する方式です。

こちらは、

Web Page
  ├─ PDF Viewer
  ├─ Analytics
  ├─ Password
  ├─ CTA
  └─ Branding

のように、PDFの周辺にWeb機能を追加できます。

PDF to Linkもこちらの方式です。

公式サイトでも、発行されるURLはPDFそのものではなくブラウザ上のreading pageであり、PDF自体をHTMLへ変換するわけではないと説明しています。

この2つの違いは、PDF to URL の考え方としても重要です。


2. View数だけではほとんど分からない

一番簡単なAnalyticsはこれです。

viewer_open

つまり、

閲覧ページが開かれた

というイベントです。

これだけでも、

Views: 248

のような数字は作れます。

しかし、実際にはかなり情報量が少ないです。

100人が開いたとしても、

Page 1だけ見て閉じた人: 80人
最後まで読んだ人: 20人

かもしれません。

そこで次に必要になるのが、

  • Page Reach
  • Active Time
  • Reading Depth
  • Exit Page

です。


3. Active Timeをどう考えるか

最初に思いつく実装は、

const startedAt = Date.now()

window.addEventListener("beforeunload", () => {
  const duration = Date.now() - startedAt
})

のようなものです。

ですが、これだとかなり問題があります。

ユーザーがPDFを開いたまま、

  • 別タブへ移動
  • 別アプリへ移動
  • PCを放置

しても時間が増え続けます。

例えば、

PDFを開く
↓
30秒読む
↓
別タブで30分作業
↓
戻る
↓
閉じる

とすると、

Session Duration ≒ 30分30秒

になってしまいます。

実際の閲覧時間とはかなり違います。


4. visibilityState を使う

Webページで最低限見るべきなのは、

document.visibilityState

です。

例えば、

document.addEventListener("visibilitychange", () => {
  if (document.visibilityState === "visible") {
    // active start
  } else {
    // active stop
  }
})

という考え方です。

これで、

visible
→ active

hidden
→ inactive

のように分けられます。

PDF to Linkでも現在、Active Timeは「documentがvisibleかつfocusedな状態」を基準として表示しています。公式ページにも Visible and focused と明記されています。


5. visibilityState だけでも完全ではない

ここが難しいところです。

たとえば、

ブラウザはactive
PDFページもvisible
でもユーザーは席を離れている

という場合があります。

この場合、visibility APIだけでは「読んでいる」と判断してしまいます。

そのため、実際にはユーザーイベントも組み合わせる方法があります。

例えば、

const activityEvents = [
  "mousemove",
  "keydown",
  "scroll",
  "touchstart",
  "pointerdown"
]

などです。

概念的には、

Page Visible
AND
Window Focused
AND
Recently Active

ならActive Timeとして数える、という考え方です。

もちろんこれも完璧ではありません。

長い文章を静かに読んでいる人はマウスを動かさないこともあります。

つまり、

Active Time = Reading Time

ではありません。

正確には、

Active Time = 読んでいる可能性が比較的高い時間

くらいに考える方が安全です。


6. Reading Depthは何を意味する?

次にReading Depthです。

例えば20ページのPDFを考えます。

あるユーザーが、

1 → 2 → 3 → 4 → 5

と読んだ場合、

furthest_page = 5

とできます。

すると、

reading_depth = 5 / 20
              = 25%

です。

かなり単純です。


7. しかしページジャンプがある

PDFビューアでは、ユーザーがいきなり、

Page 1 → Page 20

へジャンプする可能性があります。

この場合、

furthest_page = 20

だけを見ると、

100% reached

になります。

しかし、

全ページを読んだ

とは言えません。

PDF to Linkの現在のAnalyticsでも、この点について、

Based on the furthest page reached; jumping ahead can affect the curve.

と明示しています。

この説明はかなり大事だと思っています。

Analyticsは数字を出すだけでなく、

その数字が何を意味し、何を意味しないのか

を伝える必要があります。


8. 「Reached last page」を「Completed read」と呼ばない

ここも設計時に気をつけたいポイントです。

例えば、

Reached last page: 41%

という数字があったとしても、

Completed reading: 41%

とは言えません。

理由は単純で、

Page 1
↓
Page 32

とジャンプしただけかもしれないからです。

そのため、現在のPDF to Linkでも最終ページ到達率の近くに、

Not a completed read

という注意を入れています。

このようにAnalytics UIでは、

強い言葉を使いすぎない

ことも重要だと思います。


9. Page Engagementはどう取るか

Page Engagementでは、各ページについて例えば、

Page
Readers
Active Time

を持てます。

概念的なイベントは、

{
  "session_id": "xxx",
  "page": 4,
  "event": "page_view",
  "timestamp": 123456789
}

のようになります。

さらに、

{
  "session_id": "xxx",
  "page": 4,
  "active_ms": 12000
}

のようにページ単位のactive timeを積算します。

集計すると、

Page 1   248 readers   26m02s
Page 2   235 readers   26m03s
Page 3   227 readers   26m29s
Page 4   220 readers   26m57s

のような形になります。

PDF to LinkのデモAnalyticsも現在この形式でページ別ReadersとActive Timeを表示しています。


10. Page Heatmapにすると分かりやすい

数字だけ並べても分かりづらいので、

1–4     ██████████
5–8     █████████
9–12    ████████
13–16   ███████
17–20   ██████

のようなHeatmapにすると、

どこから読者が減っているか

が視覚的に分かります。

ただし、ここでも注意が必要です。

読者数が減ったからといって、

そのページが悪い

とは限りません。

例えば価格表のページを見て目的を達成して離脱した可能性もあります。

Analyticsは原因を説明しません。

Analyticsが教えてくれるのは、

どこを調べるべきか

です。


11. Exit Pageは意外と難しい

次に、

どのページで離脱したか

です。

一見、

window.addEventListener("beforeunload", ...)

で取得できそうに見えます。

しかしWebでは、終了イベントは保証されません。

例えば、

  • ブラウザ強制終了
  • スマホでアプリをkill
  • ネットワーク切断
  • OSによる終了
  • タブ破棄

などがあります。

そのため、

Exit Page = 必ず取れる

と考えるのは危険です。


12. Exit Unknown を残す

個人的には、

Page 1: 38 exits
Page 4: 25 exits
Page 8: 22 exits
Unknown: 52 sessions

のように、

unknown

を残す方が正直です。

現在のPDF to Linkのデモでも、

Exit page unknown

を別枠として表示しています。

これはデータ設計としてかなり大切だと思っています。

無理に100%分類すると、見た目は綺麗でもデータの意味が怪しくなります。


13. セッションデータはどう持つ?

簡略化すると、例えば以下のような構造が考えられます。

reading_session
---------------
id
document_id
visitor_id
started_at
last_seen_at
max_page
active_ms
exit_page
country
downloaded
cta_clicked

ページ単位は別テーブルです。

page_engagement
---------------
session_id
page_number
first_seen_at
last_seen_at
active_ms
view_count

すると、

Document
  ↓
Sessions
  ↓
Page Engagement

という関係になります。


14. VisitorとSessionは分ける

ここもよく混同しやすいです。

例えば同じ人が、

10:00 PDFを開く
15:00 もう一度開く

場合、

Visitors = 1
Sessions = 2

と考える方が自然です。

そのため、

Views
Visitors
Reading Sessions

は同じ数字にはなりません。

ブラウザidentifierなどを使えばある程度Visitorを推定できますが、

  • Cookie削除
  • Private Mode
  • 別ブラウザ
  • 別端末

などで同一人物判定は崩れます。

ここでも、

Unique Person

ではなく、

Browser Identifier

くらいの表現の方が安全です。

PDF to Linkでも現在Visitorsについて Browser identifiers と説明しています。


15. Country情報も100%正確ではない

Reader Locationも同じです。

IPベースで国を推定できても、

  • VPN
  • Proxy
  • Corporate Network
  • Cloud Network

などがあります。

したがって、

Country = User's actual physical location

ではありません。

分析用途では、

セッションに対して報告された国

程度の扱いが適切です。

現在のPDF to Linkでも、

Country reported for each reading session

という表現になっています。


16. DownloadとCTAは比較的分かりやすい

一方で、

Download Click
CTA Click

は比較的扱いやすいイベントです。

例えば、

track("download_clicked", {
  documentId,
  sessionId
})

や、

track("cta_clicked", {
  documentId,
  sessionId,
  destination
})

のように記録できます。

営業資料なら、

PDFを開いた
↓
15ページまで到達
↓
CTAをクリック

という流れを見ることができます。

これは単なるファイルダウンロードよりも、かなり文脈のあるデータになります。


17. PDF Analyticsで「やらない方がいい表現」

今回考えていて、特に避けた方がいいと思ったのが以下です。

❌「ユーザーは3分読んだ」

実際には、

Active Time ≠ 精読時間

です。


❌「41%が最後まで読んだ」

正しくは、

41%が最終ページに到達した

です。


❌「Page 8で離脱した」

終了イベントが取れなければ、

Exit Unknown

もあります。


❌「186人が閲覧した」

Browser Identifierベースなら、

186 visitors

と、

186 human beings

は必ずしも同じではありません。


18. では何を表示するのがいいか

今のところ、自分は以下くらいが分かりやすいと思っています。

Views
Visitors
Avg. Active Time
Reached Last Page
Reading Depth
Page Engagement
Reader Locations
Exit Pages
Downloads
CTA Clicks

PDF to Linkでも現在この考え方に近いDashboardにしています。


19. PDF Viewer URLが向いているユースケース

このようなAnalyticsは、すべてのPDFに必要なわけではありません。

例えば、

請求書を自分に送る

だけなら不要です。

一方で、

Sales Proposal

相手がどこまで見たか

が気になります。

Pitch Deck

投資家が最後まで到達したか

が気になります。

White Paper

ダウンロード数ではなく、実際に読まれたか

が気になります。

Product Catalog

どのページがよく見られているか

が気になります。

こういうケースでは、Raw PDF URLよりViewer URLの方が適しています。


20. PDF共有方法を整理すると

個人的には以下のように分けています。

目的 向いている方法
ファイル保管 Google Drive / Dropbox
チーム共同作業 Google Drive / OneDrive
APIで直接取得 Raw PDF URL
単純ダウンロード Raw PDF URL
読者行動の分析 Viewer URL
Pitch Deck Viewer URL
Proposal Viewer URL
Branding Viewer URL
Password Viewer URL
CTA Viewer URL

どれか一つが優れているというより、

目的が違う

と考えています。


21. 実際にPDFをリンク化する流れ

一般ユーザー向けには、あまり複雑にしない方がよいと思っています。

基本的には、

1. PDFを選択
2. アップロード
3. Reading Pageを生成
4. URLをコピー
5. 必要ならPassword/Brandingを設定
6. Analyticsを見る

です。

具体的なユーザー向け手順は PDFをリンクにする方法 にまとめています。


22. 今後やりたいこと

PDF Analyticsを作っていると、次に欲しくなるのは、

Source × Reader Engagement

です。

例えば、

LinkedIn
  Avg Depth: 72%

Email
  Avg Depth: 48%

QR Code
  Avg Depth: 31%

のように、

どこから来た人がよく読むのか

まで分かると面白いと思っています。

また、

Proposal opened
↓
Reader reached pricing page
↓
Slack / Webhook notification

のような通知も、営業用途では価値がありそうです。

ただ、機能を増やしすぎるとPDF共有ツールではなくCRMになってしまうので、その境界は悩んでいます。


まとめ

PDFビューアのAnalyticsを実装するとき、難しいのはイベントを取ることより、

そのイベントをどう解釈するか

だと思いました。

今回特に重要だと感じたのは以下です。

  • Session DurationとActive Timeを分ける
  • 最終ページ到達を「読了」と呼ばない
  • Furthest Pageだけではページジャンプを区別できない
  • Exit Pageは100%取得できない
  • VisitorとHumanを同一視しない
  • Analyticsは行動を示すが、意図までは分からない

つまり、

Analytics = Truth

ではなく、

Analytics = Behavioral Signals

です。

数字を増やすよりも、

その数字が何を意味するかを正しく説明する方が重要

だと感じています。

今回作っているPDF共有サービスはこちらです。

PDF to Link
https://pdf-to-link.com/

PDFを共有用のReading Pageとして公開し、Active Time、Reading Depth、Page Engagement、Exit Pageなどを確認できるようにしています。

同じようにPDFビューアやドキュメント分析機能を作ったことがある方がいれば、

  • Active Timeをどう定義しているか
  • Exit判定をどうしているか
  • Reading Depth以外に見るべき指標があるか

あたりはぜひ知りたいです。

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?