UV告诉你"来了多少人",但UV不告诉你"来了之后干了什么"。
用户打开小程序,是看了一页就走?还是逛了5个页面才走?
这篇文章,我会教你分析微信小程序的浏览深度、页面停留、浏览路径。
一、浏览深度的3个核心指标
| 指标 | 定义 | 计算方式 | 业务含义 |
|---|---|---|---|
| 人均浏览页数 | 单次会话平均浏览的页面数 | 总PV ÷ 会话数 | 用户逛了多深 |
| 平均停留时长 | 单次会话的平均时长 | 总停留时长 ÷ 会话数 | 用户待了多久 |
| 跳出率 | 只看1页就离开的比例 | 单页会话数 ÷ 总会话数 | 内容吸引力 |
微信小程序的浏览特点
| 特点 | 说明 |
|---|---|
| 单页栈限制 | 小程序页面栈最多10层,深度天然受限 |
| 导航方式有限 | TabBar + navigateTo + redirectTo,没有浏览器前进后退 |
| 场景驱动 | 用户从特定场景值进入,路径相对固定 |
| 分享跳转 | 可以直接跳转到小程序内任意页面 |
| 下拉刷新 | 微信特有的下拉交互 |
| 胶囊按钮 | 右上角"..."菜单可以分享/收藏/回到首页 |
二、浏览深度统计实现
2.1 会话追踪
javascript复制
// 微信小程序会话定义:基于onLaunch(每次启动算新会话)
class SessionTracker {
constructor() {
this.sessionStore = new Map(); // userId -> session
}
// App.onLaunch 时创建新会话
onLaunch(options) {
const userId = this.getUserId();
const session = {
sessionId: this.generateSessionId(),
launchTime: Date.now(),
scene: options.scene, // 微信场景值
path: options.path || '', // 启动路径
query: options.query || {}, // 启动参数
shareTicket: options.shareTicket || '',
pageStack: [],
pvCount: 0,
};
this.sessionStore.set(userId, session);
return session;
}
// Page.onShow 时记录页面浏览
onShow(page) {
const userId = this.getUserId();
const session = this.sessionStore.get(userId);
if (!session) return;
session.pageStack.push({
path: page.route || page.__route__,
showTime: Date.now(),
hideTime: null,
});
session.pvCount++;
}
// Page.onHide 时记录页面离开
onHide(page) {
const userId = this.getUserId();
const session = this.sessionStore.get(userId);
if (!session) return;
const currentPage = session.pageStack.findLast(p => p.hideTime === null);
if (currentPage) {
currentPage.hideTime = Date.now();
currentPage.stayDuration = currentPage.hideTime - currentPage.showTime;
}
}
// App.onHide 时结束会话并上报
onHide() {
const userId = this.getUserId();
const session = this.sessionStore.get(userId);
if (!session) return;
const currentPage = session.pageStack.findLast(p => p.hideTime === null);
if (currentPage) {
currentPage.hideTime = Date.now();
currentPage.stayDuration = currentPage.hideTime - currentPage.showTime;
}
tracker.track('session_end', {
session_id: session.sessionId,
scene: session.scene,
launch_path: session.path,
pv_count: session.pvCount,
duration: Date.now() - session.launchTime,
page_stack: session.pageStack.map(p => ({
path: p.path,
stay_duration: p.stayDuration || 0,
})),
});
this.sessionStore.delete(userId);
}
}
2.2 浏览深度统计SQL
sql复制
-- 1. 人均浏览页数(按日)
SELECT
event_date,
count() AS sessions,
sum(toUInt64(JSONExtractString(properties, 'pv_count'))) / count() AS avg_pages,
avg(toFloat64(JSONExtractString(properties, 'duration'))) / 1000 AS avg_duration_sec
FROM track_events
WHERE app_id = 'your_app_id' AND event_name = 'session_end'
AND event_date >= today() - 30
GROUP BY event_date ORDER BY event_date;
-- 2. 浏览深度分布(用户看了几页就走)
SELECT
toUInt64(JSONExtractString(properties, 'pv_count')) AS pages_viewed,
count() AS sessions,
count() * 100.0 / sum(count()) OVER () AS percent
FROM track_events
WHERE app_id = 'your_app_id' AND event_name = 'session_end'
AND event_date >= today() - 7
GROUP BY pages_viewed ORDER BY pages_viewed;
-- 3. 跳出率
SELECT
countIf(toUInt64(JSONExtractString(properties, 'pv_count')) = 1) * 100.0 / count() AS bounce_rate
FROM track_events
WHERE app_id = 'your_app_id' AND event_name = 'session_end'
AND event_date >= today() - 7;
-- 4. 按场景值的浏览深度对比
SELECT
toUInt32(JSONExtractString(properties, 'scene')) AS scene,
avg(toFloat64(JSONExtractString(properties, 'pv_count'))) AS avg_pages,
avg(toFloat64(JSONExtractString(properties, 'duration'))) / 1000 AS avg_duration_sec,
countIf(toUInt64(JSONExtractString(properties, 'pv_count')) = 1) * 100.0 / count() AS bounce_rate
FROM track_events
WHERE app_id = 'your_app_id' AND event_name = 'session_end'
AND event_date >= today() - 7
GROUP BY scene ORDER BY avg_pages DESC;
2.3 高跳出率页面(停留<3秒的页面)
sql复制
SELECT
JSONExtractString(properties, 'pagePath') AS page_path,
avg(toFloat64(JSONExtractString(properties, 'stayDuration'))) / 1000 AS avg_stay_sec,
count() AS views,
CASE WHEN avg(toFloat64(JSONExtractString(properties, 'stayDuration'))) / 1000 < 3
THEN '⚠️ 异常' ELSE '正常' END AS status
FROM track_events
WHERE app_id = 'your_app_id' AND event_name = 'page_view'
AND event_date >= today() - 7
GROUP BY page_path
ORDER BY avg_stay_sec ASC;
三、浏览路径分析
3.1 微信特有的路径模式
| 场景值 | 典型路径 | 特征 |
|---|---|---|
| 1011/1025(扫码) | 直接进入中间页 → 目标页 | 跳过首页 |
| 1018(分享) | 目标页 → 分享详情页 → 购买页 | 直达内容 |
| 1014/1035(公众号) | 首页 → 列表页 → 详情页 | 从首页开始 |
| 1038(搜一搜) | 搜索结果页 → 详情页 | 从搜索直达 |
| 1027(附近) | 首页 → 门店页 | 带地理位置信息 |
| 1059(支付完成) | 首页 → 订单页 → 评价页 | 后置场景 |
3.2 常见浏览路径统计
sql复制
-- 提取前3步路径,统计Top20
SELECT
arrayJoin(page_paths_3) AS path_3,
count() AS sessions,
count() * 100.0 / sum(count()) OVER () AS percent
FROM (
SELECT arraySlice(page_stack_paths, 1, 3) AS page_paths_3
FROM (
SELECT arrayMap(x -> JSONExtractString(x, 'path'),
JSONExtractArrayRaw(JSONExtractString(properties, 'page_stack'))
) AS page_stack_paths
FROM track_events
WHERE app_id = 'your_app_id' AND event_name = 'session_end'
AND event_date >= today() - 7
)
)
GROUP BY path_3
ORDER BY sessions DESC LIMIT 20;
四、浏览深度优化
4.1 低浏览深度的优化方向
| 问题 | 诊断指标 | 优化方向 |
|---|---|---|
| 跳出率高 | 单页会话比例>60% | 优化首屏内容、增加引导 |
| 人均页数低 | 人均<2页 | 增加内容推荐、相关页面引导 |
| 停留时间短 | 平均<10秒 | 优化页面加载、内容质量 |
| 特定页面跳出 | 某页面停留<3秒 | 检查页面是否有Bug |
4.2 微信小程序特有的优化手段
| 优化手段 | 实现方式 | 效果 |
|---|---|---|
| 分享卡片优化 | 自定义分享标题、图片、路径 | 提高分享打开率 |
| 下拉刷新 | enablePullDownRefresh | 增加页面互动性 |
| TabBar引导 | 在TabBar中间放"发现"tab | 引导浏览更多内容 |
| 收藏引导 | wx.addFavoritePrompt | 引导用户收藏,增加回访 |
| 订阅消息 | 引导用户订阅消息 | 通过消息召回 |
| 客服引导 | button open-type="contact" | 通过客服引导用户操作 |
写在最后
UV告诉你"来了多少人",浏览深度告诉你"来了之后干了什么"。
小程序场景值决定了用户的入口路径,不同场景值的用户行为差异很大。按场景值分析浏览深度,才能做出精准优化。
