The original link

Introduction to the

Following on from the principles, we’ll talk about how to capture and scrub data for graphically visualizing Web performance.

Ask questions

  • doubt
  1. What can developers do to improve Web application performance?
  2. So-and-so said: Optimized performance! Q: How is it reflected in statistics?
  3. When you say performance optimization, is it really what users want?

Performance myth: Performance is just a matter of load time.

  1. OnLoad trigger time?
  2. DOMContentLoaded trigger time?
  • What is the real user experience?
experience perception
Does it happen? Is navigation started successfully? Is the server responding?
Is it useful? Has enough content been rendered to interact with the user?
Is it available? Can the user interact with the page, or is the page still busy loading?
Is it enjoyable? Is the interaction smooth and natural, with no lag and lag?
  • Perception is defined as the exact key indicators
experience indicators
Does it happen? First Draw (FP)/ First Content Draw (FCP)
Is it useful? First valid draw (FMP)/ Hero element timing
Is it available? Interactive time (TTI)
Is it enjoyable? Long tasks (there are technically no long tasks)
  • How to collect and calculate indicators?

As pointed out in the Principles section, here again are the criteria to understand

  1. Navigation Timing
  2. PerformanceNavigationTiming
  3. Resource Timing Level 2

The collected data is divided into THE data of HTML parsing and loading process and the information data of HTML resource loading.

In field

HTML analysis

  • api
  1. Preferred use:performance.getEntriesByType('navigation')[0],navigation
  2. Degradation handling when not available:performance.timing,timing
  • The difference between
  1. Timing attributes are identified by timestamps like date.now () and navigation starts from 0 for each page with higher accuracy.
  2. Timing is navigationStart and navigation is startTime.
  3. Timing and navigationStart are both deprecated by the new standard, but they are highly compatible.
  4. Navigation adds resource size and serverTiming to analyze whether resource compression is too high or too small and the processing time of offline applications.
  • Compatible with the processing
if(window.performance && typeof window.performance.getEntriesByType === 'function') {
  this.resources = window.performance.getEntriesByType('resource');
  this.marks = window.performance.getEntriesByType('mark');
  this.measures = window.performance.getEntriesByType('measure');
  this.timing = window.performance.getEntriesByType('navigation') [0];
  this.paint = window.performance.getEntriesByType('paint');
  this.isSupportRTL2 = true;
} else if(window.performance && typeof window.performance.webkitGetEntriesByType === 'function') {
  this.resources = window.performance.webkitGetEntriesByType('resource');
  this.marks = window.performance.webkitGetEntriesByType('mark');
  this.measures = window.performance.webkitGetEntriesByType('measure');
  this.timing = window.performance.webkitGetEntriesByType('navigation') [0];
  this.paint = window.performance.webkitGetEntriesByType('paint');
  this.isSupportRTL2 = true;
}

this.timing = this.timing || (window.performance && window.performance.timing);
Copy the code
  • Key Performance Indicators
let stage = {
  // ...
  
  // Key performance indicators
  fb: this.timing.responseStart - this.timing.domainLookupStart, // first byte
  fpt: this.timing.responseEnd - this.timing.fetchStart,         // First paint time white
  tti: this.timing.domInteractive - this.timing.fetchStart,      // First interaction
  ready: this.timing.domContentLoadedEventEnd - this.timing.fetchStart,
  load: this.timing.loadEventStart - this.timing.fetchStart,
};

// Transfer resource size, used to determine whether the file size is appropriate, whether compression (such as gzip) is enabled
if(this.timing.transferSize ! = =undefined) {
  stage.transferSize = this.timing.transferSize;       // Document + header size
  stage.encodedBodySize = this.timing.encodedBodySize; // Compress the document size
  stage.decodedBodySize = this.timing.decodedBodySize; // Unzip the document size
}

const [firstPaint, firstContentfulPaint] = this.paint;
if(firstPaint) {
  stage.fp  = firstPaint.startTime;            // Accurate white screen time
  stage.fcp  = firstContentfulPaint.startTime; // Accurate grey screen time
}
Copy the code
  • Can see what
  1. How is the fb network?
  2. Paint Time allows you to get more accurate white and grey screen times.
  3. Ready DOM parsing time.
  4. Load Indicates the time when resources on the first screen finish loading.
  5. Page transfer size, compression size, decompression size.
  6. Is HTTP compression such as Gzip enabled for plain text classes?
  7. Is the header too large according to the transmission size and compression size? Is the HTML structure too large or too small?

  • With enough data support, weekly comparison can be formed to reflect the real optimization effect.

  • Phase calculation

let stage = {
  total: this.timing.loadEventEnd - startTime,
  unload: this.timing.unloadEventEnd - this.timing.unloadEventStart,
  redirect: this.timing.redirectEnd - this.timing.redirectStart,
  cache: this.timing.domainLookupStart - this.timing.fetchStart,
  dns: this.timing.domainLookupEnd - this.timing.domainLookupStart,
  tcp: this.timing.connectEnd - this.timing.connectStart,
  ssl: 0.ttfb: this.timing.responseStart - this.timing.requestStart,                // TimeToFirstByte
  response: this.timing.responseEnd - this.timing.responseStart,
  dom1: this.timing.domInteractive - this.timing.responseEnd,                // Interactive DOM parsing takes time
  dom2: this.timing.domContentLoadedEventStart - this.timing.domInteractive, // DOM complete loading time
  dcl: this.timing.domContentLoadedEventEnd - this.timing.domContentLoadedEventStart,
  res: this.timing.loadEventStart - this.timing.domContentLoadedEventEnd,
  onLoad: this.timing.loadEventEnd - this.timing.loadEventStart,
};

// HTTP does not have an SSL phase, HTTPS does
if(this.timing.secureConnectionStart) {
  stage.ssl = this.timing.connectEnd - this.timing.secureConnectionStart;
}
Copy the code

  • Can see what
  1. Unload event time affects the load time of the next page (ps: mobile is not very unload friendly)
  2. Is the Redirect too multidirectional and can optimizations be reduced
  3. Why is DNS always so long, HTTP DNS can work?<link rel="dns-prefetch" href="cdn.xx.com" />Added?
  4. The first package of TTFB takes so long, can it be optimized by adding CDN according to regions such as provinces?
  5. DOM parsing script execution is too long. Do you consider time slicing and trigger frequent rearrangements?
  6. Too many resources are loaded too long. Is text resources compressed? Is the image optimized like WebP? Is the non-first screen lazy loading done? Is the HTTP cache on?
  7. .
  • FMP zha do?

Consider a life cycle like react

// DOM parse the first script to start manually
performance.mark('starting_calculations');

// The main character starts loading...

performance.mark('ending_calculations');
performance.measure('FMP'.'starting_calculations'.'ending_calculations');
Copy the code

Analysis of the Resource

  • api
  1. performance.getEntriesByType(‘resource’)
{
  "name": "https://www.bilibili.com/gentleman/polyfill.js?features=Promise%2CObject.assign%2CString.prototype.includes%2CNumber.is NaN"."entryType": "resource"."startTime": 214.5700000692159."duration": 27.78000000398606."initiatorType": "script"."nextHopProtocol": "HTTP / 1.1"."workerStart": 0."redirectStart": 0."redirectEnd": 0."fetchStart": 214.5700000692159."domainLookupStart": 214.5700000692159."domainLookupEnd": 214.5700000692159."connectStart": 214.5700000692159."connectEnd": 214.5700000692159."secureConnectionStart": 214.5700000692159."requestStart": 220.7000000635162."responseStart": 239.71500003244728."responseEnd": 242.35000007320195."transferSize": 350."encodedBodySize": 72."decodedBodySize": 72."serverTiming": []."workerTiming": []}Copy the code
  • What data is available
  1. Name: domain name and suffix category domain name
  2. InitiatorType: Classifies resources with the suffix of name
  3. Duration and file size
  4. StartTime and responseEnd calculate concurrency and total consumption
  5. Of course, the same page can also collect DNS, TCP, TTFB, etc
  • First screen Resource analysis (First screen: Resources obtained after loading are not classified in the first screen)
// Slight delay of 100ms
this.resources
  .filter(({startTime}) = > startTime < this.timing.loadEventEnd + 100)
Copy the code
  • Domain analysis

  • There are much use
  1. Resource domain names are clearly classified
  2. The loading time of each domain name is clear
  3. CDN location problem? Configuration issues?
  4. Accidental references to third parties can easily bring down your own app. Consider a replacement?
  5. Is there a problem with the use of third-party resources? Can you ask them to optimize?
  • You can define some company-controlled domain names, which can be classified into local domain (host), company-controlled domain (OWN), and third-party domain (external).

  • Partition by initiatorType

  • InitiatorType division is sometimes unclear, based on the file ending andMIMEdivision

  • Cross domain andTime-Allow-OriginThis will affect your collection of resources such as DNS.

  • Cross domainTime-Allow-OriginNo, the browser is in secure mode0
redirectStart
redirectEnd
domainLookupStart
domainLookupEnd
connectStart
connectEnd
secureConnectionStart
requestStart
responseStart
Copy the code
  • Limit the size of information collected and report some full resource information

  • Pay attention to
  1. Name with care, some reports using img. SRC may cause this value to be too long, which may slow down your acquisition performance.
  2. As can be seen from the above, cross-domain is not set in most cases, resulting in resource size of 0.

report

  • Timing: onLoad? Unload? Visibilitychange?
  1. OnLoad will interfere with the user
  2. Unload Mobile Not friendly
  3. Visibilitychange adopted
  • Report the way
  1. Img. SRC may exceed the URL limit and also affect the processing of the name mentioned above.
  2. Ajax is a bit more complicated, either by hand or by introducing third-party libraries.
  • Select VisibilityChange + Navigator. sendBeacon + compatible with Synchronous Ajax

  • Survivor bias, maybe the user environment is so bad that they wait a long time before they can show any useful information or interact, and then they’re turned off, and then they’re not picked up. You can use Visibilitychange to upload performance.now() to collect user jump time.

conclusion

  • Optimization is endless
  1. Calculate application satisfaction based on weighted average of key performance indicators, and continuously optimize towards satisfaction;
  2. Business enough shop wide enough for province optimization, select CDN, etc.;
  3. The ultimate purpose of optimization is to retain and attract customers and bring economic benefits to individuals or companies.