This article was published on the blog of weidian front-end team
Author: Liu Yuan-yang
Company: Micro Store – front end team
Date: 2018-03-05
background
In terms of the acquisition method of front-end performance data, manual embedding is mostly used in the industry at present, that is, manually judge the position of the firstscreen in the code and add the code of the firstscreen record there, similar to firstscreen.report().
This is simple and easy, but the downside is obvious:
-
Mix with business code
Common monitoring requirements are woven into the business code
-
Incomplete coverage
Page developers need to consciously manually add buried code, buried coverage in the business may not reach 100%
-
Accuracy is not necessarily high
Since it’s up to the developer to decide where to place the statistics script, there can be some inaccuracies because everyone’s interpretation of the first screen is different
Based on the above analysis, we recently tried some solutions to automate the first screen time calculation, saving manpower and improving accuracy.
define
The definition of first screen time may vary from company to company. In this article, first screen time refers to:
-
If there is a picture on the front screen
First screen time = first screen picture all loaded moment - window. The performance. The timing. NavigationStartCopy the code
-
If there is no image on the first screen
First screen time = page in a stable state before the last moment of dom changes - window. Performance. The timing. NavigationStartCopy the code
Realize the principle of
The general idea is as follows:
-
From the page loading, according to a certain interval dot, continuously record the next page at each time the first screen picture list and other information
Question: At what intervals?
-
Find the time T1 when the first screen of the page is stable (it may have been stable for some time)
Question: How do I find this T1?
-
Based on the number of images on the first screen at time T1, work backwards to find the last time T2 that is consistent with the first screen at time T1
-
The loading completion time T3 of all images at T2 was counted
-
T3 is the time when the top screen is completed
Now, solve the problems mentioned above one by one:
-
Question: How to find the time T1 when the first screen is in a stable state?
We split the page from loading to rendering into two major stages: 1. 2. After obtaining data, render the page.
This logic is consistent with most page logic: get the data first, then render the page.
Solution:
-
The send object of XHR is monitored by AOP in a faceted way, and the first XHR Request in the page is captured. Starting from the time when the first XHR Request is sent, all the requests sent within 1000ms are counted into the array Request.
We consider that the requests that may affect the first screen have been sent within the time period [first XHR request, first XHR request + 1000ms].
-
For serial requests (that is, the next Request depends on the data returned from the previous Request), the new requests within 500ms after each Request is returned are counted into the array Request.
Some pages request data serially, and the data on the front screen may be loaded after two sequential requests.
Requests that affect the first screen might also be made in this way.
-
The array Request contains all data requests that affect the first screen, and some data requests that do not affect the first screen.
-
For the above statistical requests, find the time T1 when all data return, and then, T1 = T1 + 300ms to ensure that the page is rendered after receiving data (300ms is enough for one rendering).
-
At time T1, the first screen of the page is considered to be in a stable state.
-
-
Question: At what intervals?
-
MutationObserver
We all know that the MutationObserver object is used to capture page DOM changes, so in our script, we use the MutationObserver to listen for DOM changes and trigger a dot every time the DOM changes.
-
setInterval
SetInterval can also implement timing
-
Combination of MutationObserver and setInterval
However, the timing of the MutationObserver callback is out of the developer’s control, in several cases:
- Callbacks can be hundreds of milliseconds or even more than a second apart, leading to large statistical errors
- In some cases, the DOM doesn’t change, but in the page element,
img
的src
Having undergone changes or elementsbackground-image
Changes do not trigger a callback in MutationObserver, resulting in a statistical error
Therefore, our current solution is to combine MutationObserver and setInterval, and start setInterval during the interval of the MutationObserver callback to ensure that the dot interval during the page loading process is not too long and improve the statistical accuracy.
-
Statistical error
Even with all the complexity and judgment mentioned above, errors still exist. So, where are the errors?
As shown below:
Unstable state images (1) a stable state 2 images (2) steady state 1 (2 ') | | | | ________________________ | _______________________ | t1 t2, t3Copy the code
According to the above theory, we will take t2 moment as the moment when the first screen can be counted. The moment when the two pictures are loaded is the moment when the first screen is completed.
There is a difference of 1 image between t2 and T1.
According to our theory, the completion time of the first screen must be t2.n sometime after T2.
However, we do not know when the loading of the actual different picture was completed. It may have been completed before T2, or the request may have been sent, but it has not been completed yet.
The error is there. It’s always there.
But what we need to count is the first screen data within the acceptable error range. According to the feedback of the company’s business practice, the data reliability is very high.
Talk is cheap, show me the code
We’ve also open-source this widget:
github: auto-compute-first-screen-time
npm: auto-compute-first-screen-time
Welcome friends to use, ridicule, improvement.