Подсчитайте, как долго пользователи остаются на сайте

JavaScript

Недавно я получил запрос на подсчет времени с момента входа пользователя на веб-страницу до закрытия всех веб-страниц в браузере.

Сначала определите свои потребности:

  1. Как только пользователь заходит, записывайте время начала входа пользователя на страницу;
  2. Пользователь открывает страницу в новой вкладке.Если другие вкладки уже открыли страницу, время начала в это время по-прежнему совпадает со временем входа на первую страницу;
  3. Когда пользователь закрывает все вкладки веб-страницы, необходимо записать время окончания закрытия, и вызывается интерфейс для передачи данных в фоновый режим;

Во-первых, при входе на страницу браузер вызоветonloadСобытие, при закрытии браузера браузер вызоветbeforeunloadСобытия, вы можете начать с этих двух событий.

Но тут есть несколько проблем, то есть при обновлении браузера он тоже будет вызыватьbeforeunload, а как узнать, что пользователь открывал веб-страницу и в других вкладках?

Есть ли способ записать, обновился ли браузер или нет? Вот тогда я подумалsessionStorage.

sessionStorage, используется для временного сохранения данных того же окна (или вкладки), которые будут удалены после закрытия окна или вкладки. То есть данные хранятся вsessionStorage, всегда будет существовать на текущей вкладке.

Во-первых, при первом входе на страницу,onloadв случаеsessionStorageсохранить идентификатор

window.addEventListener("load",function(){
    if(sessionStorage.getItem("flag")){
        return;
    }
    sessionStorage.setItem("flag", true);
})

Есть еще одна проблема, упомянутая выше, а именно, как считать пользователей, открывших несколько вкладок?

В локальном кешеlocalStorageДанные в нем могут быть общими для всего сайта, то есть сайтов с одинаковым доменным именем и ip,localStorageДанные также одинаковы в разных вкладках.

В это время вы можете пойти вlocalStorageВ нем хранится счетчик, когда пользователь заходит на страницу, счетчик увеличивается на 1, а когда пользователь покидает страницу, счетчик уменьшается на 1. Когда счетчик равен 0, все страницы с флагами закрываются, и в это время может быть записано время окончания закрытия страницы. При этом время начала посещения сайта также сохраняется вlocalStorageсередина

window.addEventListener("load",function(){
    let nowTime = getNowTime()
    let openPageCount = localStorage.getItem("openPageCount")
    openPageCount += 1
    localStorage.setItem("openPageCount",openPageCount)
    //其实说明是页面是刷新后加载的,不应该统计开始时间
    if(sessionStorage.getItem("flag")){
        return;
    }
    localStorage.setItem("startTime",nowTime)
    sessionStorage.setItem("flag", true);
})

window.addEventListener("beforeunload",function(){
    let nowTime = getNowTime()
    let openPageCount = localStorage.getItem("openPageCount")
    openPageCount -= 1
    localStorage.setItem("endTime",nowTime)
    localStorage.setItem("openPageCount",openPageCount)
    if(openPageCount == 0){
        //说明页面全部关闭,这时候可以传数据给后台
    }
})

function getNowTime(){
    let nowTime = new Date().getTime()
    return nowTime
}

Здесь также есть проблема, то есть пользователь случайно выключил компьютер или внезапно отключилось питание, в это время он не будет выполнен.beforeunloadОн не будет выполнен. В настоящее время данные неверны и должны быть отброшены.

Чтобы решить эту проблему, перейдите кlocalStorageВремя обновления хранится в магазине, и время обновления обновляется каждые 30 секунд. Когда пользователь загружает веб-сайт, время обновления считывается. Если разница между текущим временем и временем обновления превышает 1 минуту, указывает на наличие пробела в данных, и данные этой записи должны быть отброшены.

window.addEventListener("load",function(){
    let nowTime = getNowTime()
    let openPageCount = localStorage.getItem("openPageCount")
    openPageCount = openPageCount ? parseInt(openPageCount) : 0
    openPageCount += 1
    localStorage.setItem("openPageCount",openPageCount)
    refreshTime()
    let isRightTime =  compareRefreshTime()
    //其实说明是页面是刷新后加载的,不需要统计开始时间
    if(sessionStorage.getItem("flag") && isRightTime){
        return;
    }
    localStorage.setItem("startTime",nowTime)
    localStorage.setItem("refreshTime",nowTime)
    sessionStorage.setItem("flag", true);
})

window.addEventListener("beforeunload",function(){
    let nowTime = getNowTime()
    let openPageCount = localStorage.getItem("openPageCount")
    openPageCount -= 1
    localStorage.setItem("endTime",nowTime)
    localStorage.setItem("openPageCount",openPageCount)
    if(openPageCount == 0){
        //说明页面全部关闭,这时候可以传数据给后台
    }
})

function getNowTime(){
    let nowTime = new Date().getTime()
    return nowTime
}

function compareRefreshTime(){
   let nowTime = getNowTime()
   let refreshTime = localStorage.getItem("refreshTime")
   return nowTime - refreshTime < 60 * 1000
}

function refreshTime(){
    setTimeout(refreshTime ,30 * 1000)
    let nowTime = getNowTime()
    localStorage.setItem("refreshTime",nowTime)
}

Выше приведен весь код для подсчета продолжительности пребывания пользователей на сайте.

Сценарии приложений могут представлять собой статистику времени использования мобильных приложений и статистику того, как долго веб-сайт будет закрыт после того, как пользователи откроют его, и все они относятся к категории больших данных.

Это может быть расширено на время просмотра пользователями каждой страницы, и подсчет времени просмотра каждой страницы может лучше подсчитать, какие страницы часто просматриваются пользователями, чтобы лучше оптимизировать эти страницы, в то время как те, у которых меньше или нет просмотров страниц. страницы должны быть переработаны или требуют меньше времени для обслуживания. Идеи реализации для хранения этих данных во внешнем интерфейсе в целом схожи.

Конечно, вышеописанный способ имеет и определенные недостатки, например, данные могут быть потеряны, для каждой открытой страницы необходимо запускать таймер и так далее.

Если данные должны быть более точными, мы можем использовать веб-сокет или запустить таймер для регулярной передачи данных в фоновый режим и т. д. Это также будет иметь некоторые недостатки, такие как увеличение нагрузки на сервер и влияние на производительность.