piwik总页面加载时间(包括主要的ajax调用)

时间:2014-10-03 12:26:02

标签: matomo

使用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秒。

早些时候,我看到有人在论坛上发帖,说这已经尝试了,但我再也找不到这篇文章了。 参考这篇文章或提示如何实现这一点将不胜感激。

1 个答案:

答案 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函数。