piwik общее время загрузки страницы (включая первичные вызовы ajax)
С помощью Piwik я бы хотел отследить общее время, необходимое для отображения веб-страницы. Общее время будет включать вызовы ajax после запроса начальной страницы.
По умолчанию Piwik отслеживает только время, необходимое для выполнения исходного запроса загрузки страницы. например.
GET page: | -----> (0,5 сек) => по умолчанию записывается в piwik
Общее время, которое я хотел бы записать, включает в себя все последующие вызовы ajax. например.
GET page: | -----> (0,5 сек) => по умолчанию записывается в piwik
Ajax 1: |--GET->|------> (0,6 сек)
Ajax 2: | --GET ->|---> (0,3 с)
Ajax 3: | --GET ->|----------> (1,0 сек) => Я бы хотел видеть общее время рендеринга страницы в 1,5 сек.
Ранее я видел сообщение на форуме, что это уже было сделано, но я не могу найти это сообщение снова. Ссылка на этот пост или советы, как этого добиться, будет принята с благодарностью.
1 ответ
Это не идеальное решение и может содержать ошибки, но, похоже, это работает почти так, как задумано. Вам может потребоваться дополнительная настройка для обработки определенных ситуаций, которые могут не охватываться этим сценарием. Время загрузки страницы может иметь небольшое отклонение (~0,2 с по сравнению со временем просмотра из-за ошибки), но они кажутся достаточно корректными.
<script type="text/javascript">
// Not used at the moment, but can be used with all cookies methods, e.g. $.cookies.get('cookie', cookieOptions)
var cookieOptions = {
domain: '*.mydomain.com',
path: '/piwik',
expiresAt: new Date(2100, 1, 1),
secure: true
}
var slowOnPages = ["firstPage", "secondPage"]; // A list of pages where it should be waited longer before sending a raport (e.g. there may be delayed ajax event that may trigger a moment after the page load completes, but should be included in the total page loading time)
// Note: The title used is loaded from a custom field with id 'piwikTitle' in this script. You need to add this field in page markup (e.g. <span id="piwikTitle" style="display: none;">firstPage</span>).
var requestStartCookie = "requestStart"; // The name of a cookie that will store the start time ms of the 1st independent request noticed (page (re)load/transition or 1st ajax request triggered from an event on a completely loaded page)
var taskPollCookie = "taskPoll"; // You may set elsewhere a cookie right before ajax call to indicate that this call should not be raported ($.cookies.set("taskPoll", true);)
var timeOutId = -1; // If there is an time out id set, it indicates that there is a pending raport
var delay = 25; // Note: browser speed may affect on how fast a new chained request would be initiated. This will introduce a bit of uncertainty for time tracking but is needed sometimes to prevent greater uncertainty
var _paq = _paq || []; // Must be here to make it global and detectable by piwik.js
$(document).ajaxStop(function() {
var startMs = $.cookies.get(requestStartCookie);
if (startMs == null) {
console.log("No requestStartCookie was set => no raport sent");
} else {
if (timeOutId > -1) {
// There was a new ajaxStop while the raport was purposedly waiting if such an event happens
// Track the time it takes to complete the last request that completes (this request + including the time it took to complete all the previous)
// clearTimeOut => Discard the pending raporting event of the previous request completed
clearTimeout(timeOutId);
console.log("Discarded pending raport with id: " + timeOutId);
}
var endTimeMs = new Date().getTime();
// There are some pages that may initiate delayed ajax requests
// In such cases the piwik raport sending has to be delayed also, else we will get unnecessary and incorrect raports
// Note: This will start a long waiting period only for the 1st raporting event on the specified pages.
// You may need to tune this for your specific case
if (slowOnPages.indexOf($("#piwikTitle").text()) > -1 && timeOutId == -1) {
timeOutId = setTimeout(function() {doPiwikRaport(startMs, endTimeMs);}, 5000);
} else {
timeOutId = setTimeout(function() {doPiwikRaport(startMs, endTimeMs);}, 1000);
}
}
});
// This will handle the actual raport sending when the time comes
// @param long requestChainStartMs The time in millis when the request chain started
// @param long requestChainEndMs The time in millis when the request chain ended
// @param boolean waitForPageLoadToComplete When this is false the raport is sent even if the page is not completed rendering yet (true by default)
var doPiwikRaport = function(requestChainStartMs, requestChainEndMs, waitForPageLoadToComplete) {
waitForPageLoadToComplete = (typeof waitForPageLoadToComplete !== 'undefined' ? waitForPageLoadToComplete : true);
if(waitForPageLoadToComplete && (document.readyState != 'complete' || $.active != 0)) {
var endTimeMs = new Date().getTime();
timeOutId = setTimeout(function() {doPiwikRaport(requestChainStartMs, endTimeMs);}, delay); // Recursive call, try again after short delay
} else {
var generationTime = requestChainEndMs - requestChainStartMs;
console.log("Page load time was: " + generationTime);
// Construct the Piwik raport
_paq.push(["setCustomUrl", location.pathname]);
_paq.push(['setDocumentTitle', $("#piwikTitle").text()]);
_paq.push(['setCustomVariable', 1, "visitPurpose", $("#visitPurpose").text(), "visit"]);
_paq.push(['setCustomVariable', 2, "pageLoadCompleted", waitForPageLoadToComplete, "page"]);
_paq.push(['setGenerationTimeMs', generationTime]);
_paq.push(['trackPageView']);
_paq.push(['enableLinkTracking']);
(function() {
_paq.push(['setTrackerUrl', 'http://www2.mydomain.com/piwik/piwik.php']);
_paq.push(['setSiteId', 1]); // Correct the site id
var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0]; g.type='text/javascript';
g.defer=true; g.async=true; g.src= '/' + location.pathname.split("/")[1] + '/js/piwik.js'; s.parentNode.insertBefore(g,s);
})();
// Remove attributes indicating a pending raport
$.cookies.del(requestStartCookie);
timeOutId = -1;
if (!waitForPageLoadToComplete) {
// If the page did not finish loading, a page transition was made
// Set a new requestStartCookie with the end time previous raport had
$.cookies.set(requestStartCookie, requestChainEndMs);
console.log("Piwik page content load raporting was done prematurely");
} else {
console.log("Piwik page content load raporting was done normally");
}
}
}
$(document).ajaxStart(function() {
var taskPoll = ($.cookies.get(taskPollCookie) != null ? true : false);
// Do not set new start time if a taskPoll iniated the request (taskPolls are not supposed to be raported)
if (!taskPoll) {
// If there is a time out set, then there already is a pending raport => do not change start time
// There also may be a requestStartCookie if there is ongoing page transition
if (timeOutId == -1 && $.cookies.get(requestStartCookie) == null) {
var start = new Date().getTime();
console.log("New request start detected: " + start);
$.cookies.set(requestStartCookie, start);
}
} else if (timeOutId == -1) {
console.log("taskPoll detected, no requestStartCookie set");
}
});
// Detects if the user is leaving page before a raport was sent
window.onbeforeunload = function() {
if (timeOutId > -1) {
clearTimeout(timeOutId);
var startMs = $.cookies.get(requestStartCookie);
doPiwikRaport(startMs, new Date().getTime(), false);
}
};
</script>
Примечание: JQuery используется. Никакая часть трекера изображения не включена.
Удалите детали каротажа, когда закончите!
Также использовал этот плагин для обработки файлов cookie: https://code.google.com/p/cookies/wiki/Documentation
// Обновить
Это немного улучшено (изменения не включены в скрипт выше). Использование файлов cookie может быть улучшено с помощью html5 sessionStorage:
var checkSessionStorageAvailability = function() {
try {
return 'sessionStorage' in window && window['sessionStorage'] !== null;
} catch(e) {
return false;
}
}
var sessionStorageAvailable = checkSessionStorageAvailability();
var setRequestStart = function(millis) {
if (typeof millis == 'undefined' || millis == null) {
millis = new Date().getTime();
}
if (sessionStorageAvailable) {
sessionStorage.setItem(requestStart, millis);
} else {
$.cookies.set(requestStart, millis);
console.log("New request start detected");
}
}
Замените функции get/set/remove/is-cookie в скрипте отслеживания аналогичными функциями, как в приведенном выше примере вспомогательной функции.