Skip to content

A web tool for tracking dom events & visibility, javascript runtime errors, resource loading, page performance, network, route changes, memory leaks and custom behavior etc.

License

Notifications You must be signed in to change notification settings

Inchill/web-sniffer

Repository files navigation

web-sniffer

Overview

The web-sniffer library is a tool which can track dom events & visibility, javascript runtime errors, resource loading, page performance, network, route changes, memory leaks and custom behavior etc.

Install and load the library

From npm

npm i web-sniffer

From a CDN

<script src="https://unpkg.com/[email protected]/dist/web-sniffer.min.js"></script>

Or

<script type="module">
  import { createDomWatcher } from 'https://unpkg.com/[email protected]/dist/web-sniffer.esm.js'
  createDomWatcher({
    visibility: true
  }, console.log)
</script>

Usage

createDomWatcher

const reportCallback = (data) => {
  const body = JSON.stringify(data);
  const url = 'http://127.0.0.1:8080/analytics';

  // Use `navigator.sendBeacon()` if available, falling back to `fetch()`
  if (navigator.sendBeacon) {
    navigator.sendBeacon(url, body);
  } else {
    fetch(url, { body, method: 'POST', keepalive: true });
  }
}

const domConfig = {
  visibility: true,
  event: true
}

createDomWatcher(domConfig, reportCallback)

The domConfig has the following configuration items:

name type default description
visibility boolean false Dom visibility detection
root HTMLElement document.documentElement The Element or Document whose bounds are used as the bounding box when testing for intersection.
threshold number 0.2 A list of thresholds, sorted in increasing numeric order, where each threshold is a ratio of intersection area to bounding box area of an observed target. Notifications for a target are generated when any of the thresholds are crossed for that target. If no value was passed to the constructor, 0 is used.
event boolean false Dom event detection
eventListeners array ['click'] Dom events like click, dbclick, mouseenter etc.

In Vue

// App.vue
import HelloWorld from './components/HelloWorld.vue'
import { createDomWatcher, createResourceWatcher } from 'web-sniffer/dist/web-sniffer.esm'

export default {
  name: 'App',
  components: {
    HelloWorld
  },
  mounted () {
    createDomWatcher({
      visibility: true,
      event: true
    }, this.reportCallback)

    createResourceWatcher(this.reportCallback)

    let img = document.createElement('img')
    img.src = '//localhost:8081/101.png'
    document.body.appendChild(img)
  },
  methods: {
    reportCallback: (data) => {
      const body = JSON.stringify(data);
      const url = 'http://127.0.0.1:8080/analytics';

      // Use `navigator.sendBeacon()` if available, falling back to `fetch()`
      if (navigator.sendBeacon) {
        navigator.sendBeacon(url, body);
      } else {
        fetch(url, { body, method: 'POST', keepalive: true });
      }
    }
  }
}
<!-- HelloWorld.vue -->
<h3 :data-event="msg" :data-expose="msg">Ecosystem</h3>

Before using custom data attributes, you have to register event type in eventListeners. Using data attributes can avoid the third-party javascript frameworks filtering custom directives.

In React

// App.js
import { createDomWatcher } from 'web-sniffer/dist/web-sniffer.esm';
import Hello from './components/hello'

function App() {
  const reportCallback = (data) => {
    const body = JSON.stringify(data);
    const url = 'http://127.0.0.1:8080/analytics';

    // Use `navigator.sendBeacon()` if available, falling back to `fetch()`
    if (navigator.sendBeacon) {
      navigator.sendBeacon(url, body);
    } else {
      fetch(url, { body, method: 'POST', keepalive: true });
    }
  }

  useEffect(() => {
    createDomWatcher({
      visibility: true,
      event: true
    }, reportCallback)
  }, [])

  return (
    <div className="App" data-expose="App show">
      <Hello/>
    </div>
  );
}

export default App;
// Hello.js
export default function Hello () {
  return (
    <h1 data-expose="hello world" data-event="clicked me">hello world</h1>
  )
}

createJsErrorWatcher

import { createJsErrorWatcher } from 'web-sniffer/dist/web-sniffer.esm'

createJsErrorWatcher(console.log)

The web-sniffer will catch js errors, including synchronous errors and asynchronous errors such as promise unhandledrejection. You can pass on a callback function to handle captured errors.

createResourceWatcher

import { createResourceWatcher } from 'web-sniffer/dist/web-sniffer.esm'

createResourceWatcher(console.log)

The web-sniffer will track the img, script, link, audio and video resources loading, if loaded failed it will report the target info which has tag name and resource url.

Notice: When the page is first to load resources, the web-sniffer maybe loaded behind the css stylesheets link, in such case it could not track the failed link loadings.

If performance API is not supported in the browser, a work around way is combining onerror and onreadystatechange handlers. When the page is first to load, onerror handler may be called before onreadystatechange handler and onreadystatechange handler works only once, so there is a flag to check if the loading errors are first loading.

Notice: Using background-image to load would not be detected.

createRouteWatcher

import { createRouteWatcher } from 'web-sniffer/dist/web-sniffer.esm'

createRouteWatcher(console.log)

It will detect hash and history changes, you can pass on a callback function to handle the detail info which contains oldURL and newURL.

Performance

Network

Memory

Behavior

About

A web tool for tracking dom events & visibility, javascript runtime errors, resource loading, page performance, network, route changes, memory leaks and custom behavior etc.

Resources

License

Stars

Watchers

Forks

Packages

No packages published