The mobile web page is affected by the network speed and terminal performance of the mobile network. We often need to pay attention to the first screen content display time (hereinafter referred to as the first screen time, it measures whether our pages can be displayed before the user's patience ends, and affects user satisfaction to a great extent.
How can I get the first screen time?
We often need to first ask ourselves: how does a page load data?
A: After loading static resources, use Ajax requests to obtain data from the backend, and render the content after the data is returned.
Add a timestamp at each point. The first screen time is;
B: Use the background direct output. The returned HTML already contains the content.
The first screen time is.
Note: 1. so many points are made, because after we collect the first screen time, we need to analyze which one is the performance bottleneck and which one has room for optimization, so we need to collect ...... These times are used for analysis;
2. Hitting 1. We usually add a timestamp at the beginning of the head tag of an HTML file;
3. There is generally no other loading processing before loading CSS files, so hitting 1 and hitting 2 can generally be merged.
At this point, we have collected various data related to the first screen and made various targeted optimizations. Wait! Before you perform drastic optimization, you need to know some details, which will help you perform more accurate analysis and more detailed optimization.
Details 1: node after js-node before JS = loading time of JS
Jsendtime-jsstarttime = loading time of JS files, right?
No! Obviously, this equation ignores the JS execution time. It takes several hundred milliseconds to execute code in JS, especially for complex calculations or frequent Dom operations.
So, jsendtime-jsstarttime = loading and execution time of JS files?
Still incorrect! BecauseLoading and executing CSS files causes interference.. I think it's strange, right? Don't worry. Let's do a test: Find a demo page, open it in chrome, start the console, simulate low network speed, and load files for a long time:
Collect the jsendtime-jsstarttime in normal cases, and then use Fiddler to block a CSS request for several seconds:
Then, restore the request and obtain the jsendtime-jsstarttime result. The first time is several hundred milliseconds and nearly one second, the second time is less than Ms or even close to 0 (in my example, the time is determined by the reader's specific JS file). The gap between the two is very obvious.
What is the principle? This is what we often call "loading is parallel and execution is serial. When HTML is loaded, the browser loads CSS files and JS files that are exposed to the page in parallel. If a file is not returned, the Code following it will not be executed. In our demo, we blocked the CSS file for several seconds. At this time, the JS file has been loaded back in parallel, but the CSS file is blocked, soThe value assignment statement of the following jsstarttime is not executed!When blocking is enabled, values assigned to jsstarttime, parsing of JS files, and values assigned to jsendtime are run. The difference between jsendtime and jsstarttime is very small because the loading of large data volumes has been completed.
Do you know how to use this?
- Do not make the jsendtime-jsstarttime result into the loading and execution time of JS files (unless you do not have an external CSS file). Otherwise, they will be teased by insiders;
- Blocking of CSS files will affect the execution of js code in the future. Naturally, HTML code execution is also included, that is, your page is blank at this time. Therefore, try to inline CSS files. You can ask the build tool to help you;
- If you really want to know the loading time of JS files, the most correct posture is to use the resource timing API, but this API mobile end can only get data in android4.4 and later versions, it is enough for analysis and use in scenarios with high business PV.
Of course, the two hitting points can still be used for analysis.
Details 2: JS files that are external to HTML. loading the previous file will block the execution of the next file. If. JS is responsible for rendering and dynamically pulls JS files, pulls cgi files, and performs rendering. It will find that the blocking of JS files after it will not affect its processing.
The conclusion of the first half has been proved in detail 1, because browser execution is serial. This indicates that the JS Code responsible for rendering content will not be executed until all the JS files in front of it are loaded and executed, even if the code that is irrelevant to rendering is reported as data:
The conclusion in the last half is very good. We are extending a JS file behind the JS file that is responsible for rendering and blocking it, you will find that rendering-related JavaScript files, whether dynamically pulling new JS files or pulling rendering-related content, are all normal, and the page content is successfully rendered, their execution does not need to wait for the blocked file.
Do you know how to use this?
- The JS that is irrelevant is not placed in front of the JS that is responsible for rendering. The "irrelevant" here means it has nothing to do with the first screen rendering.Such as the data reporting component. We can choose to temporarily store the data to be reported. First, we can continue to execute the rendering JS, and then load the reporting component after the rendering JS is executed. Even zepto and other libraries can be stored in the back, and rendering-related code can be extracted and written in native Js;
- We can see that the execution of Dynamically Loaded JS is not affected by the blocking of JS behind HTML, that is, its execution and the subsequent execution sequence of JS are uncertain. Therefore, we must be careful with the dependency of the file. Of course, you can also use the least error-prone method: loading JS files dynamically is the last file in HTML that is used for external access.
(Note: I personally think this is the most important two conclusions in the full text, because I am doing the first screen optimization ^-^)
Details 3: If the HTML return header contains a chunk, It is parsed by the return side. Otherwise, it is returned once and then parsed. This is configured on the server.
Hitting 1 is generally written at the beginning of the head tag in HTML. Some friends often compare the starting time of-with that, I don't think it is certain how many milliseconds the direct output optimization has taken. You must know that the HTML file contains the rendered content and DOM nodes. The file size is generally larger than that of the non-direct file, sometimes even dozens of kb, I think the loading time of HTML should be taken into account to illustrate how much direct output optimization is. Does the above calculation method consider the loading time of HTML?
Check whether the response header of the HTML file contains Chunk:
If the returned header is included, the HTML file parses the returned edge. The calculation method above is reasonable. If this header is not included, the HTML file is parsed only after the whole response is returned. In this case, the preceding calculation method does not calculate the loading time of HTML, which is not accurate enough. The return header is controlled by the background.
Do you know how to use this?
- If we want to explain the optimization degree of direct output, we 'd better first look at your HTML return header. If the chunk return header is not included, use navigationstart in HTML5 performance as hitting 1 (this API is also supported by android4.4 and later). Otherwise, you need to evaluate the file size change and make some corrections;
- For HTML without chunk enabled, we recommend that you do not include too many JS files irrelevant to the content of the first screen rendering, which will affect the rendering time.
Details 4: loading and parsing of script nodes written in HTML will affect the trigger time of the domcontentloaded event.
We sometimes use the domcontentloaded event instead of the onload event, and do some processing when the page is ready. However, you must know that the DOM in domcontentloaded not only contains common DOM nodes, but also script nodes.
To test this, We will block a JS file in the external area of the page for a while before releasing it. Let's take a look at the chrome console:
Obviously, the loading time of JS files affects the trigger event of this event. Will the parsing time of JS Code affect? We typed a point behind the last external JS file. The time is:
Therefore, loading and executing JS files will affect the execution time of the domcontentloaded event.
Do you know how to use this?
- If we plan to perform some special processing in the domcontentloaded and onload events and these processing operations are important (such as rendering-related ), we 'd better not directly expand some JS files irrelevant to rendering in HTML, so we can consider using dynamic loading instead.
Summary
It is interesting to study the first screen time and resource loading. You can use the chrome Console (especially the network tag) and Fiddler to find many interesting small details and draw small conclusions. Don't think it's okay to find something. It's very good to understand these scenarios, such as performance optimization for the first screen and locating errors caused by disordered execution of JS files. So remember to share something with me ~
On the first screen, how is the white screen time calculated ??