使用Piwik,我想跟踪呈现网页所花费的总时间。总时间将包括初始页面请求之后的ajax调用。
默认情况下,Piwik只跟踪完成原始页面加载请求所花费的时间。例如
GET页面:|----->(0.5秒)=>默认情况下在piwik中转发
我希望重新ported的总时间包括所有后续的ajax调用。例如
GET页面:|----->(0.5秒)=>默认情况下在piwik中转发
Ajax 1:|--获取-->|----->(0.6秒)
Ajax 2:|--获取-->|--->(0.3秒)
Ajax 3:|--GET-->|--------------->(1,0秒)=>我希望看到1,5秒的总页面呈现时间。
早些时候,我看到有人在论坛上发帖,说这已经尝试过了,但我再次找不到这个帖子。如能参考这篇文章或如何做到这一点的技巧,将不胜感激。
这不是一个完美的解决方案,可能会包含错误,但这似乎可以正常工作。您可能需要更多的自定义来处理此脚本可能未涵盖的某些情况。页面加载时间可能有很小的偏差(与从fire bug查看的时间相比,大约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
//更新
对此进行了一点改进(上面的脚本中没有包含更改)。使用html5会话可以更好地使用cookie存储:
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函数替换为类似的函数,如上面的helper函数示例。