How does this article monitor web page lag? The next. Today we focus on how to monitor web crashes.
Inch zhi: how to monitor web page congestion?zhuanlan.zhihu.com
What’s the difference between a crash and a caton?
Gridlock refers to the temporary slow response of the web page, JS may not be timely execution, which is also the technical point on which the previous web page gridlock monitoring relies.
But crash is not the same, the page crashed, the page can not see, JS are not running, there is no way to monitor the crash of the page, and the crash report?
But there is always a way.
Load with beforeUnload events
Searching the Internet, I could hardly find a way, and finally came across this article. This article uses the Load and beforeUnload events of window objects to monitor web crashes.
http://jasonjl.me/blog/2015/06/21/taking-action-on-browser-crashes/jasonjl.me
window.addEventListener('load', function () { sessionStorage.setItem('good_exit', 'pending'); setInterval(function () { sessionStorage.setItem('time_before_crash', new Date().toString()); }, 1000); }); window.addEventListener('beforeunload', function () { sessionStorage.setItem('good_exit', 'true'); }); if(sessionStorage.getItem('good_exit') && sessionStorage.getItem('good_exit') ! == 'true') { /* insert crash logging code here */ alert('Hey, welcome back from your crash, looks like you crashed on: ' + sessionStorage.getItem('time_before_crash')); }Copy the code
A picture is worth a thousand words:
This approach takes advantage of the fact that a page crash cannot trigger beforeUnload events.
Good_exit is logged as pending in sessionStorage at page load time (load event). If the user exits normally (beforeUnload event) the state is changed to True. If crash occurs, the state is still pending. When the user accesses the page for the second time (the 2nd load event), check the status of good_exit. If the status is still pending, it can be determined that the last page crashed!
But there are problems with this plan:
- SessionStorage is used to store the state, but usually after the web page crashes/freezes, users will forcibly close the web page or simply reopen the browser, sessionStorage but the state will not exist;
- If the status is stored in localStorage or even cookies, and the user opens multiple web pages but does not close them, good_exit will always be stored as pending, and every time a web page is opened, a crash will be reported.
A live broadcastThis scheme was adopted at the beginning, and I realized the problems of this scheme only when I found that even though the page was optimized, crash did not decrease and kept proportion with PV.
Crash statistics scheme based on Service Worker
With the popularity of the PWA concept, Service workers are becoming more and more familiar to everyone. We can use Service workers to monitor web crashes for the following reasons:
- The Service Worker has its own independent Worker thread, which is separated from the web page. If the web page crashes, the Service Worker will not crash in general.
- Service workers typically have longer life cycles than web pages and can be used to monitor the state of web pages;
- Web pages can be through the navigator. ServiceWorker. Controller. PostMessage API to run their own SW send messages.
Based on the above points, we can realize a monitoring scheme based on heartbeat detection:
- P1: After the web page is loaded, it sends a heartbeat to sw through postMessage API every 5s to indicate that it is online. Sw registers the online web page and updates the registration time.
- P2: Web pages use postMessage API to tell themselves that they have closed properly before loading, and sw clears registered web pages;
- P3: If the webpage crashes during running, the running state in SW will not be cleared, and the update time stays at the last heartbeat before crash.
- Sw: The Service Worker checks the registered web page every 10 seconds and finds that the registered time has exceeded a certain time (such as 15s), then the web page can be judged as crashing.
Some simplified detection code, for everyone as a reference:
/ / page JavaScript code if (the navigator. ServiceWorker. Controller! == null) { let HEARTBEAT_INTERVAL = 5 * 1000; // Let sessionId = uuid(); let heartbeat = function () { navigator.serviceWorker.controller.postMessage({ type: 'heartbeat', id: sessionId, data: {} // Additional information, additional data to report if the page crashes}); } window.addEventListener("beforeunload", function() { navigator.serviceWorker.controller.postMessage({ type: 'unload', id: sessionId }); }); setInterval(heartbeat, HEARTBEAT_INTERVAL); heartbeat(); }Copy the code
- SessionId Unique ID of the current session.
- PostMessage contains information that can be used to report data needed for a crash, such as the address of the current page.
const CHECK_CRASH_INTERVAL = 10 * 1000; // Check every 10s const CRASH_THRESHOLD = 15 * 1000; Const pages = {} let timer function checkCrash() {const now = date.now () for (var id in Pages) {let page = pages[id] if ((now-page.t) > CRASH_THRESHOLD) {// Report crash delete pages[id]}} if (Object.keys(pages).length == 0) { clearInterval(timer) timer = null } } worker.addEventListener('message', (e) => { const data = e.data; if (data.type === 'heartbeat') { pages[data.id] = { t: Date.now() } if (! timer) { timer = setInterval(function () { checkCrash() }, CHECK_CRASH_INTERVAL) } } else if (data.type === 'unload') { delete pages[data.id] } })Copy the code
Pretty simple code, I won’t go into detail.
Feasibility of the scheme
Compatibility:
The popularity of Service workers has been quite high. Considering that all domestic browsers are Chrome kernel and their versions are above Chrome 45, a considerable number of users have been covered. As surveillance, data coverage is mostly good.
Reliability:
This is probably the most accurate way I know of a crash. However, our solution is still in the testing environment, and we will share data with you after a period of time.
Recommendations for browser vendors
As you can see from the Crash list in Chrome :// Crashes /, it would be nice if the vendor provided an API to check the last Crash of the user when the page opened!