Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GA源代码里的小技巧之preview和prerender #21

Open
zmmbreeze opened this issue Sep 17, 2016 · 0 comments
Open

GA源代码里的小技巧之preview和prerender #21

zmmbreeze opened this issue Sep 17, 2016 · 0 comments

Comments

@zmmbreeze
Copy link
Owner

作者前段时间在做类似Google Analytics(以下简称GA)的第三方监控脚本。所以对GA的前端代码做过调研,对GA的压缩后代码做了一定程度上的人肉美化。这里美化的是analytics.js的j41版本,本文提到的小技巧也是基于这个版本的js。

preview

Safari浏览器有个Top site功能,它会展示最长访问的几个页面的截图。示例如下:

Safari会去真正的加载解析这几个站点页面,然后截图并保存。当用户点开这些站点时会再次加载解析这些页面。

GA的功能是统计正常用户的访问情况,很明显这种情况已经不是正常的访问了,所以对这种情况做了过滤。凡是是预览(preview)请求都不会执行自己的主要逻辑。示例代码如下:

function isPreviewLoad(win) {
    win = win || window;
    var api = 'navigator';
    return win[api] && win[api].loadPurpose === 'preview';
};

if (isPreviewLoad()) {
    // TODO
}

prerender

W3C标准(WD)中有个prerender特性。如果在指定页面index.html的HTML代码头部中加入如下的meta标签:

<!DOCTYPE html>
<head>
<meta charset="utf-8">
<title>index.html</title>
<!-- 预渲染 -->
<link rel="prerender" href="./article.html">
</head>
<body>
<a href="./article.html">文章地址</a>
<body>
</html>

那么浏览器在加载index.html的时候,会预先加载渲染article.html页面,但是不展现。当浏览器真正点开页面中article.html页面的地址时,浏览器才会再真正的展现这个页面。不过用户也有可能不再点击article.html的地址,而是直接离开了或是跳去别的页面。目前IE>=11Chrome>=13、Opera>=15都支持了这个特性。

GA为了避免发送无用的统计,也过滤掉了预渲染的情况,在页面真正展示的时候再执行自己的主逻辑。它通过浏览器提供的Page Visibility API来判断当页面处于的状态。如果页面是预渲染,那么页面渲染时document.visibilityState的值为prerender。然后监听visiableChange事件,当页面可见之后开始执行业务主逻辑。

综合previewprerender两种情况,我们可以用如下代码来判断是否需要执行自己的业务主逻辑:

function start(win, main) {
    if (isPreviewLoad(win)) {
        return;
    }

    var doc = win.document;
    var executed = false;
    var isPrerender = function () {
        return doc.visibilityState === 'prerender';
    };
    var cb = function () {
        if (!executed && !isPrerender(win)) {
            executed = true;
            main();
            // 解除事件监听
            off(doc, 'visibilitychange', cb);
        }
    };

    if (isPrerender(win)) {
        // 添加事件监听
        on(doc, 'visibilitychange', cb);
        return;
    }
    main();
}
start(window, function () {
    // TODO 业务主逻辑
});

参考资料:

  1. Safari Top Sites Preview
  2. CanIUse
  3. IE Prerender and prefetch support
  4. W3C Resource Hints Spec
  5. Prefetching, preloading, prebrowsing
@zmmbreeze zmmbreeze changed the title GA代码小技巧之preview和prerender GA源代码里的小技巧之preview和prerender Sep 24, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant