使用Piwik,我想跟踪渲染网页所需的总时间。总时间将包括初始页面请求后的ajax调用。
默认情况下,Piwik仅跟踪完成原始页面加载请求所需的时间。 例如
获取页面:| -----> (0,5秒)=>默认情况下在piwik中出现
我希望报出的总时间包括所有后续的ajax调用。 例如
获取页面:| -----> (0,5秒)=>默认情况下在piwik中出现
Ajax 1:| --GET - > | ------> (0,6秒)
Ajax 2:| --GET - > | ---> (0,3秒)
Ajax 3:| --GET - > | ----------> (1,0秒)=>我希望看到总页面渲染时间为1.5秒。
早些时候,我看到有人在论坛上发帖,说这已经尝试了,但我再也找不到这篇文章了。 参考这篇文章或提示如何实现这一点将不胜感激。
答案 0 :(得分:0)
这不是一个完美的解决方案,可能包含错误,但这似乎与预期的一样。您可能需要更多自定义来处理此脚本可能未涵盖的某些情况。页面加载时间可能有较小的偏差(与火灾中查看的时间相比,约为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
// update
改进了一下(上面脚本中未包含的更改)。使用html5 sessionStorage可以更好地使用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函数。