mirror of
https://github.com/plausible/analytics.git
synced 2024-12-22 09:01:40 +03:00
Reduce script size (#68)
* Remove cookie code * Compile tracker separetly from website assets * Install uglify * Help minifier reduce varaibles
This commit is contained in:
parent
01bc5911d1
commit
4bd12f03fc
1
.gitignore
vendored
1
.gitignore
vendored
@ -27,6 +27,7 @@ npm-debug.log
|
||||
|
||||
# The directory NPM downloads your dependencies sources to.
|
||||
/assets/node_modules/
|
||||
/tracker/node_modules/
|
||||
|
||||
# Since we are building assets from assets/,
|
||||
# we ignore priv/static. You may want to comment
|
||||
|
@ -39,6 +39,7 @@ RUN set -x \
|
||||
|
||||
COPY config ./config
|
||||
COPY assets ./assets
|
||||
COPY tracker ./tracker
|
||||
COPY priv ./priv
|
||||
COPY lib ./lib
|
||||
COPY mix.exs ./
|
||||
@ -51,6 +52,8 @@ RUN mix local.hex --force && \
|
||||
RUN npm audit fix --prefix ./assets && \
|
||||
npm install --prefix ./assets && \
|
||||
npm run deploy --prefix ./assets && \
|
||||
npm install --prefix ./tracker && \
|
||||
npm run deploy --prefix ./tracker && \
|
||||
mix phx.digest priv/static
|
||||
|
||||
WORKDIR /app
|
||||
|
127
assets/js/p.js
127
assets/js/p.js
@ -1,127 +0,0 @@
|
||||
(function(window, plausibleHost){
|
||||
'use strict';
|
||||
|
||||
try {
|
||||
const CONFIG = {
|
||||
domain: window.location.hostname
|
||||
}
|
||||
|
||||
function setCookie(name,value) {
|
||||
var date = new Date();
|
||||
date.setTime(date.getTime() + (3*365*24*60*60*1000)); // 3 YEARS
|
||||
var expires = "; expires=" + date.toUTCString();
|
||||
document.cookie = name + "=" + (value || "") + expires + "; samesite=strict; path=/";
|
||||
}
|
||||
|
||||
function getCookie(name) {
|
||||
let matches = document.cookie.match(new RegExp(
|
||||
"(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
|
||||
));
|
||||
return matches ? decodeURIComponent(matches[1]) : null;
|
||||
}
|
||||
|
||||
function ignore(reason) {
|
||||
console.warn('[Plausible] Ignoring event because ' + reason);
|
||||
}
|
||||
|
||||
function getUrl() {
|
||||
return window.location.protocol + '//' + window.location.hostname + window.location.pathname + window.location.search;
|
||||
}
|
||||
|
||||
function getSourceFromQueryParam() {
|
||||
const result = window.location.search.match(/[?&](ref|source|utm_source)=([^?&]+)/);
|
||||
return result ? result[2] : null
|
||||
}
|
||||
|
||||
function getUserData() {
|
||||
var userData = JSON.parse(getCookie('plausible_user'))
|
||||
|
||||
if (userData) {
|
||||
return {
|
||||
initial_referrer: userData.initial_referrer && decodeURIComponent(userData.initial_referrer),
|
||||
initial_source: userData.initial_source && decodeURIComponent(userData.initial_source)
|
||||
}
|
||||
} else {
|
||||
userData = {
|
||||
initial_referrer: window.document.referrer || null,
|
||||
initial_source: getSourceFromQueryParam(),
|
||||
}
|
||||
|
||||
setCookie('plausible_user', JSON.stringify({
|
||||
initial_referrer: userData.initial_referrer && encodeURIComponent(userData.initial_referrer),
|
||||
initial_source: userData.initial_source && encodeURIComponent(userData.initial_source),
|
||||
}))
|
||||
|
||||
return userData
|
||||
}
|
||||
}
|
||||
|
||||
function trigger(eventName, options) {
|
||||
if (/^localhost$|^127(?:\.[0-9]+){0,2}\.[0-9]+$|^(?:0*\:)*?:?0*1$/.test(window.location.hostname)) return ignore('website is running locally');
|
||||
if (window.location.protocol === 'file:') return ignore('website is running locally');
|
||||
if (window.document.visibilityState === 'prerender') return ignore('document is prerendering');
|
||||
|
||||
var payload = CONFIG['trackAcquisition'] ? getUserData() : {}
|
||||
payload.name = eventName
|
||||
payload.url = getUrl()
|
||||
payload.domain = CONFIG['domain']
|
||||
payload.referrer = window.document.referrer || null
|
||||
payload.source = getSourceFromQueryParam()
|
||||
payload.user_agent = window.navigator.userAgent
|
||||
payload.screen_width = window.innerWidth
|
||||
|
||||
var request = new XMLHttpRequest();
|
||||
request.open('POST', plausibleHost + '/api/event', true);
|
||||
request.setRequestHeader('Content-Type', 'text/plain');
|
||||
|
||||
request.send(JSON.stringify(payload));
|
||||
|
||||
request.onreadystatechange = function() {
|
||||
if (request.readyState == XMLHttpRequest.DONE) {
|
||||
options && options.callback && options.callback()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function page(options) {
|
||||
trigger('pageview', options)
|
||||
}
|
||||
|
||||
function trackPushState() {
|
||||
var his = window.history
|
||||
if (his.pushState) {
|
||||
var originalFn = his['pushState']
|
||||
his.pushState = function() {
|
||||
originalFn.apply(this, arguments)
|
||||
page();
|
||||
}
|
||||
}
|
||||
window.addEventListener('popstate', page)
|
||||
}
|
||||
|
||||
function configure(key, val) {
|
||||
CONFIG[key] = val
|
||||
}
|
||||
|
||||
const functions = {
|
||||
page: page,
|
||||
trigger: trigger,
|
||||
trackPushState: trackPushState,
|
||||
configure: configure
|
||||
}
|
||||
|
||||
const queue = window.plausible.q || []
|
||||
|
||||
window.plausible = function() {
|
||||
var args = [].slice.call(arguments);
|
||||
var funcName = args.shift();
|
||||
functions[funcName].apply(this, args);
|
||||
};
|
||||
|
||||
for (var i = 0; i < queue.length; i++) {
|
||||
window.plausible.apply(this, queue[i])
|
||||
}
|
||||
} catch (e) {
|
||||
new Image().src = plausibleHost + '/api/error?message=' + encodeURIComponent(e.message);
|
||||
}
|
||||
})(window, BASE_URL);
|
@ -1,115 +0,0 @@
|
||||
(function(window, plausibleHost){
|
||||
'use strict';
|
||||
|
||||
try {
|
||||
const scriptEl = window.document.querySelector('[src*="' + plausibleHost +'"]')
|
||||
const domainAttr = scriptEl && scriptEl.getAttribute('data-domain')
|
||||
const trackAcquisitionAttr = scriptEl && scriptEl.getAttribute('data-track-acquisition')
|
||||
|
||||
const CONFIG = {
|
||||
domain: domainAttr || window.location.hostname,
|
||||
trackAcquisition: typeof(trackAcquisitionAttr) === 'string'
|
||||
}
|
||||
|
||||
function setCookie(name,value) {
|
||||
var date = new Date();
|
||||
date.setTime(date.getTime() + (3*365*24*60*60*1000)); // 3 YEARS
|
||||
var expires = "; expires=" + date.toUTCString();
|
||||
document.cookie = name + "=" + (value || "") + expires + "; samesite=strict; path=/";
|
||||
}
|
||||
|
||||
function getCookie(name) {
|
||||
let matches = document.cookie.match(new RegExp(
|
||||
"(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
|
||||
));
|
||||
return matches ? decodeURIComponent(matches[1]) : null;
|
||||
}
|
||||
|
||||
function ignore(reason) {
|
||||
console.warn('[Plausible] Ignoring event because ' + reason);
|
||||
}
|
||||
|
||||
function getUrl() {
|
||||
return window.location.protocol + '//' + window.location.hostname + window.location.pathname + window.location.search;
|
||||
}
|
||||
|
||||
function getSourceFromQueryParam() {
|
||||
const result = window.location.search.match(/[?&](ref|source|utm_source)=([^?&]+)/);
|
||||
return result ? result[2] : null
|
||||
}
|
||||
|
||||
function getUserData() {
|
||||
var userData = JSON.parse(getCookie('plausible_user'))
|
||||
|
||||
if (userData) {
|
||||
return {
|
||||
initial_referrer: userData.initial_referrer && decodeURIComponent(userData.initial_referrer),
|
||||
initial_source: userData.initial_source && decodeURIComponent(userData.initial_source)
|
||||
}
|
||||
} else {
|
||||
userData = {
|
||||
initial_referrer: window.document.referrer || null,
|
||||
initial_source: getSourceFromQueryParam(),
|
||||
}
|
||||
|
||||
setCookie('plausible_user', JSON.stringify({
|
||||
initial_referrer: userData.initial_referrer && encodeURIComponent(userData.initial_referrer),
|
||||
initial_source: userData.initial_source && encodeURIComponent(userData.initial_source),
|
||||
}))
|
||||
|
||||
return userData
|
||||
}
|
||||
}
|
||||
|
||||
function trigger(eventName, options) {
|
||||
if (/^localhost$|^127(?:\.[0-9]+){0,2}\.[0-9]+$|^(?:0*\:)*?:?0*1$/.test(window.location.hostname)) return ignore('website is running locally');
|
||||
if (window.location.protocol === 'file:') return ignore('website is running locally');
|
||||
if (window.document.visibilityState === 'prerender') return ignore('document is prerendering');
|
||||
|
||||
var payload = CONFIG['trackAcquisition'] ? getUserData() : {}
|
||||
payload.name = eventName
|
||||
payload.url = getUrl()
|
||||
payload.domain = CONFIG['domain']
|
||||
payload.referrer = window.document.referrer || null
|
||||
payload.source = getSourceFromQueryParam()
|
||||
payload.user_agent = window.navigator.userAgent
|
||||
payload.screen_width = window.innerWidth
|
||||
|
||||
var request = new XMLHttpRequest();
|
||||
request.open('POST', plausibleHost + '/api/event', true);
|
||||
request.setRequestHeader('Content-Type', 'text/plain');
|
||||
|
||||
request.send(JSON.stringify(payload));
|
||||
|
||||
request.onreadystatechange = function() {
|
||||
if (request.readyState == XMLHttpRequest.DONE) {
|
||||
options && options.callback && options.callback()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function page() {
|
||||
trigger('pageview')
|
||||
}
|
||||
|
||||
var his = window.history
|
||||
if (his.pushState) {
|
||||
var originalPushState = his['pushState']
|
||||
his.pushState = function() {
|
||||
originalPushState.apply(this, arguments)
|
||||
page();
|
||||
}
|
||||
window.addEventListener('popstate', page)
|
||||
}
|
||||
|
||||
const queue = (window.plausible && window.plausible.q) || []
|
||||
window.plausible = trigger
|
||||
for (var i = 0; i < queue.length; i++) {
|
||||
trigger.apply(this, queue[i])
|
||||
}
|
||||
|
||||
page()
|
||||
} catch (e) {
|
||||
new Image().src = plausibleHost + '/api/error?message=' + encodeURIComponent(e.message);
|
||||
}
|
||||
})(window, BASE_URL);
|
@ -15,10 +15,7 @@ module.exports = (env, options) => ({
|
||||
},
|
||||
entry: {
|
||||
'app': ['./js/app.js'],
|
||||
'dashboard': ['./js/dashboard/mount.js'],
|
||||
'p': ['./js/p.js'],
|
||||
'analytics': ['./js/plausible.js'],
|
||||
'plausible': ['./js/plausible.js']
|
||||
'dashboard': ['./js/dashboard/mount.js']
|
||||
},
|
||||
output: {
|
||||
filename: '[name].js',
|
||||
|
1
compile
1
compile
@ -1,4 +1,5 @@
|
||||
cd $phoenix_dir
|
||||
NODE_ENV=production npm --prefix ./assets run deploy
|
||||
npm --prefix ./tracker install && npm --prefix ./tracker run deploy
|
||||
mix "${phoenix_ex}.digest"
|
||||
mix "${phoenix_ex}.digest.clean"
|
||||
|
23
tracker/compile.js
Normal file
23
tracker/compile.js
Normal file
@ -0,0 +1,23 @@
|
||||
const uglify = require("uglify-js");
|
||||
const fs = require('fs')
|
||||
const path = require('path')
|
||||
|
||||
const scheme = process.env.SCHEME || "http"
|
||||
const host = process.env.HOST || "localhost"
|
||||
const baseUrl = scheme + "://" + host
|
||||
|
||||
function relPath(segment) {
|
||||
return path.join(__dirname, segment)
|
||||
}
|
||||
|
||||
function compilefile(input, output) {
|
||||
const code = fs.readFileSync(input)
|
||||
.toString()
|
||||
.replace('BASE_URL', "'" + baseUrl + "'")
|
||||
const result = uglify.minify(code)
|
||||
fs.writeFileSync(output, result.code)
|
||||
}
|
||||
|
||||
compilefile(relPath('src/plausible.js'), relPath('../priv/static/js/plausible.js'))
|
||||
compilefile(relPath('src/p.js'), relPath('../priv/static/js/p.js'))
|
||||
fs.copyFileSync(relPath('../priv/static/js/plausible.js'), relPath('../priv/static/js/analytics.js'))
|
19
tracker/package-lock.json
generated
Normal file
19
tracker/package-lock.json
generated
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"requires": true,
|
||||
"lockfileVersion": 1,
|
||||
"dependencies": {
|
||||
"commander": {
|
||||
"version": "2.20.3",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
|
||||
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ=="
|
||||
},
|
||||
"uglify-js": {
|
||||
"version": "3.9.4",
|
||||
"resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.9.4.tgz",
|
||||
"integrity": "sha512-8RZBJq5smLOa7KslsNsVcSH+KOXf1uDU8yqLeNuVKwmT0T3FA0ZoXlinQfRad7SDcbZZRZE4ov+2v71EnxNyCA==",
|
||||
"requires": {
|
||||
"commander": "~2.20.3"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
9
tracker/package.json
Normal file
9
tracker/package.json
Normal file
@ -0,0 +1,9 @@
|
||||
{
|
||||
"scripts": {
|
||||
"deploy": "node compile.js"
|
||||
},
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"uglify-js": "^3.9.4"
|
||||
}
|
||||
}
|
127
tracker/src/p.js
Normal file
127
tracker/src/p.js
Normal file
@ -0,0 +1,127 @@
|
||||
(function(window, plausibleHost){
|
||||
'use strict';
|
||||
|
||||
function setCookie(name,value) {
|
||||
var date = new Date();
|
||||
date.setTime(date.getTime() + (3*365*24*60*60*1000)); // 3 YEARS
|
||||
var expires = "; expires=" + date.toUTCString();
|
||||
document.cookie = name + "=" + (value || "") + expires + "; samesite=strict; path=/";
|
||||
}
|
||||
|
||||
function getCookie(name) {
|
||||
var matches = document.cookie.match(new RegExp(
|
||||
"(?:^|; )" + name.replace(/([\.$?*|{}\(\)\[\]\\\/\+^])/g, '\\$1') + "=([^;]*)"
|
||||
));
|
||||
return matches ? decodeURIComponent(matches[1]) : null;
|
||||
}
|
||||
|
||||
function ignore(reason) {
|
||||
console.warn('[Plausible] Ignoring event because ' + reason);
|
||||
}
|
||||
|
||||
function getUrl() {
|
||||
return window.location.protocol + '//' + window.location.hostname + window.location.pathname + window.location.search;
|
||||
}
|
||||
|
||||
function getSourceFromQueryParam() {
|
||||
var result = window.location.search.match(/[?&](ref|source|utm_source)=([^?&]+)/);
|
||||
return result ? result[2] : null
|
||||
}
|
||||
|
||||
function getUserData() {
|
||||
var userData = JSON.parse(getCookie('plausible_user'))
|
||||
|
||||
if (userData) {
|
||||
return {
|
||||
initial_referrer: userData.initial_referrer && decodeURIComponent(userData.initial_referrer),
|
||||
initial_source: userData.initial_source && decodeURIComponent(userData.initial_source)
|
||||
}
|
||||
} else {
|
||||
userData = {
|
||||
initial_referrer: window.document.referrer || null,
|
||||
initial_source: getSourceFromQueryParam(),
|
||||
}
|
||||
|
||||
setCookie('plausible_user', JSON.stringify({
|
||||
initial_referrer: userData.initial_referrer && encodeURIComponent(userData.initial_referrer),
|
||||
initial_source: userData.initial_source && encodeURIComponent(userData.initial_source),
|
||||
}))
|
||||
|
||||
return userData
|
||||
}
|
||||
}
|
||||
|
||||
function trigger(eventName, options) {
|
||||
if (/^localhost$|^127(?:\.[0-9]+){0,2}\.[0-9]+$|^(?:0*\:)*?:?0*1$/.test(window.location.hostname)) return ignore('website is running locally');
|
||||
if (window.location.protocol === 'file:') return ignore('website is running locally');
|
||||
if (window.document.visibilityState === 'prerender') return ignore('document is prerendering');
|
||||
|
||||
var payload = CONFIG['trackAcquisition'] ? getUserData() : {}
|
||||
payload.name = eventName
|
||||
payload.url = getUrl()
|
||||
payload.domain = CONFIG['domain']
|
||||
payload.referrer = window.document.referrer || null
|
||||
payload.source = getSourceFromQueryParam()
|
||||
payload.user_agent = window.navigator.userAgent
|
||||
payload.screen_width = window.innerWidth
|
||||
|
||||
var request = new XMLHttpRequest();
|
||||
request.open('POST', plausibleHost + '/api/event', true);
|
||||
request.setRequestHeader('Content-Type', 'text/plain');
|
||||
|
||||
request.send(JSON.stringify(payload));
|
||||
|
||||
request.onreadystatechange = function() {
|
||||
if (request.readyState == XMLHttpRequest.DONE) {
|
||||
options && options.callback && options.callback()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function page(options) {
|
||||
trigger('pageview', options)
|
||||
}
|
||||
|
||||
function trackPushState() {
|
||||
var his = window.history
|
||||
if (his.pushState) {
|
||||
var originalFn = his['pushState']
|
||||
his.pushState = function() {
|
||||
originalFn.apply(this, arguments)
|
||||
page();
|
||||
}
|
||||
}
|
||||
window.addEventListener('popstate', page)
|
||||
}
|
||||
|
||||
function configure(key, val) {
|
||||
CONFIG[key] = val
|
||||
}
|
||||
|
||||
try {
|
||||
var CONFIG = {
|
||||
domain: window.location.hostname
|
||||
}
|
||||
|
||||
var functions = {
|
||||
page: page,
|
||||
trigger: trigger,
|
||||
trackPushState: trackPushState,
|
||||
configure: configure
|
||||
}
|
||||
|
||||
var queue = window.plausible.q || []
|
||||
|
||||
window.plausible = function() {
|
||||
var args = [].slice.call(arguments);
|
||||
var funcName = args.shift();
|
||||
functions[funcName].apply(this, args);
|
||||
};
|
||||
|
||||
for (var i = 0; i < queue.length; i++) {
|
||||
window.plausible.apply(this, queue[i])
|
||||
}
|
||||
} catch (e) {
|
||||
new Image().src = plausibleHost + '/api/error?message=' + encodeURIComponent(e.message);
|
||||
}
|
||||
})(window, "https://plausible.io");
|
75
tracker/src/plausible.js
Normal file
75
tracker/src/plausible.js
Normal file
@ -0,0 +1,75 @@
|
||||
(function(window, plausibleHost){
|
||||
'use strict';
|
||||
|
||||
var location = window.location
|
||||
var document = window.document
|
||||
|
||||
var scriptEl = document.querySelector('[src*="' + plausibleHost +'"]')
|
||||
var domainAttr = scriptEl && scriptEl.getAttribute('data-domain')
|
||||
var CONFIG = {domain: domainAttr || location.hostname}
|
||||
|
||||
function ignore(reason) {
|
||||
console.warn('[Plausible] Ignore event: ' + reason);
|
||||
}
|
||||
|
||||
function getUrl() {
|
||||
return location.protocol + '//' + location.hostname + location.pathname + location.search;
|
||||
}
|
||||
|
||||
function getSourceFromQueryParam() {
|
||||
var result = location.search.match(/[?&](ref|source|utm_source)=([^?&]+)/);
|
||||
return result ? result[2] : null
|
||||
}
|
||||
|
||||
function trigger(eventName, options) {
|
||||
if (/^localhost$|^127(?:\.[0-9]+){0,2}\.[0-9]+$|^(?:0*\:)*?:?0*1$/.test(location.hostname) || location.protocol === 'file:') return ignore('running locally');
|
||||
if (document.visibilityState === 'prerender') return ignore('prerendering');
|
||||
|
||||
var payload = {}
|
||||
payload.name = eventName
|
||||
payload.url = getUrl()
|
||||
payload.domain = CONFIG['domain']
|
||||
payload.referrer = document.referrer || null
|
||||
payload.source = getSourceFromQueryParam()
|
||||
payload.user_agent = window.navigator.userAgent
|
||||
payload.screen_width = window.innerWidth
|
||||
|
||||
var request = new XMLHttpRequest();
|
||||
request.open('POST', plausibleHost + '/api/event', true);
|
||||
request.setRequestHeader('Content-Type', 'text/plain');
|
||||
|
||||
request.send(JSON.stringify(payload));
|
||||
|
||||
request.onreadystatechange = function() {
|
||||
if (request.readyState == 4) {
|
||||
options && options.callback && options.callback()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function page() {
|
||||
trigger('pageview')
|
||||
}
|
||||
|
||||
try {
|
||||
var his = window.history
|
||||
if (his.pushState) {
|
||||
var originalPushState = his['pushState']
|
||||
his.pushState = function() {
|
||||
originalPushState.apply(this, arguments)
|
||||
page();
|
||||
}
|
||||
window.addEventListener('popstate', page)
|
||||
}
|
||||
|
||||
var queue = (window.plausible && window.plausible.q) || []
|
||||
window.plausible = trigger
|
||||
for (var i = 0; i < queue.length; i++) {
|
||||
trigger.apply(this, queue[i])
|
||||
}
|
||||
|
||||
page()
|
||||
} catch (e) {
|
||||
new Image().src = plausibleHost + '/api/error?message=' + encodeURIComponent(e.message);
|
||||
}
|
||||
})(window, BASE_URL);
|
Loading…
Reference in New Issue
Block a user