What are the ways to optimize page performance
Introduction
The Internet has a famous 8-second rule. Users get impatient when they visit a web page for more than 8 seconds, and if it takes too long to load, they give up . Most users expect web pages to load within 2 seconds. In fact, you lose 7% of your users for every additional second of load time. 8 seconds is not exactly 8 seconds, it just shows the importance of load times to website developers. So how do we optimize page performance and improve page loading speed? This is the main question to be discussed in this article. However, performance optimization is a comprehensive problem, and there is no standard answer. It is not easy to list everything.
This article only focuses on some core points. The following is a summary of common methods of performance optimization combined with the MOOC course "Web Front-End Performance Optimization":
1. Resource compression and consolidation
Mainly include these aspects: html compression, css compression, js compression and confusion and file merging .
Resource compression removes extraneous characters, such as carriage returns and spaces, from files. When you write code in the editor, you use indentation and comments, these methods will undoubtedly make your code concise and readable, but they also add extra bytes to the documentation.
1. html compression
HTML code compression is to compress these characters that are meaningful in text files, but not displayed in HTML, including spaces, tabs, newlines, etc., and some other meaningful characters, such as HTML comments, can also be compressed.
How to do html compression:
- Use an online website for compression (generally not used during development)
- nodejs provides the html-minifier tool
- Backend template engine rendering compression
2. css code compression:
CSS code compression is simply the deletion of invalid code and the merging of CSS semantics
How to do css compression:
- Use an online website for compression (generally not used during development)
- Use the html-minifier tool
- Compress CSS with clean-css
3. Compression and confusion of js
The compression and confusion of js mainly includes the following parts:
- Removal of invalid characters
- Remove comments
- Code Semantics Reduction and Optimization
- Code protection (code logic becomes cluttered, reducing code readability, which is important)
How to compress and mess with js
- Use an online website for compression (generally not used during development)
- Use the html-minifier tool
- Use uglifyjs2 to compress js
In fact, the compression and confusion of css compression and js is much more profitable than html compression. At the same time, css code and js code are much more than html code. The traffic reduction brought by css compression and js compression will be very obvious. So for large companies, html compression is optional, but css compression and js compression and confusion must be there!
4. File Merge
As can be seen from the above figure, not merging requests has the following disadvantages:
- There are inserted upstream requests between files, adding N-1 network delays
- More seriously affected by the packet loss problem
- There may be situations in the keep-alive method, and it may be disconnected when passing through the proxy server, which means that the keep-alive state cannot be maintained all the time.
Compressing and merging css and js can reduce the number of http requests for a website, but merging files may bring problems: above-the-fold rendering and cache invalidation problems . So how to deal with this problem? ----Common library merging and merging of different pages.
How to do file merge
- File merging using an online website
- File merging using nodejs (gulp, fis3)
2. Asynchronous loading of non-core code asynchronous loading
1. Asynchronous loading method
Three ways of asynchronous loading - async and defer, dynamic script creation
① async method
- The async attribute is a new HTML5 attribute, which requires Chrome, FireFox, IE9+ browser support
- The async attribute specifies that once the script is available, it will be executed asynchronously
- async attribute only works with external scripts
- In the case of multiple scripts, this method does not guarantee that the scripts will be executed in order
<script type="text/javascript" src="xxx.js" async="async"></script>
② defer method
- Compatible with all browsers
- The defer attribute specifies whether to delay script execution until the page loads
- If there are multiple scripts, this method can ensure that all scripts with the defer attribute set are executed in order
- If the script does not change the content of the document, the defer attribute can be added to the script tag to speed up the processing of the document
③ Dynamic creation of script tags
Before defer and async have not been defined, the asynchronous loading method is to dynamically create scripts, and use the window.onload method to ensure that the page is loaded and then insert the script tags into the DOM. The specific code is as follows:
function addScriptTag(src){
var script = document.createElement('script');
script.setAttribute("type","text/javascript");
script.src = src;
document.body.appendChild(script);
}
window.onload = function(){
addScriptTag("js/index.js");
}
2. The difference between asynchronous loading
1) defer will be executed after the HTML is parsed. If there are more than one, they will be executed in the order of loading.
2) async is executed immediately after loading, if there are multiple, the execution order has nothing to do with the loading order
The blue line represents network reads, the red line represents execution time, both of which are for scripts; the green line represents HTML parsing.
3. Use browser cache
For web applications, caching is a powerful tool for improving page performance and reducing server pressure.
Browser cache type
1. Strong cache: no request is sent to the server, and resources are read directly from the cache. In the network option of the chrome console, you can see that the request returns a status code of 200, and the size shows from disk cache or from memory cache;
Related headers:
Expires : The expiration time in the response header. When the browser loads the resource again, if it is within this expiration time, it will hit the strong cache. Its value is an absolute time string in GMT format, such as Expires:Thu,21 Jan 2018 23:39:02 GMT
Cache-Control : This is a relative time, in seconds when configuring the cache, expressed as a numerical value. When the value is set to max-age=300, it means that the resource will be loaded again within 5 minutes of the correct return time of the request (the browser will also record it), and the strong cache will be hit. For example, Cache-Control:max-age=300,
A brief summary : In fact, there is little difference between the two. The difference is that Expires is a product of http1.0, and Cache-Control is a product of http1.1. If the two exist at the same time, Cache-Control has a higher priority than Expires ; in some cases Expires can be useful in environments that do not support HTTP 1.1. So Expires is actually an outdated product, and its existence at this stage is just a way of writing compatibility. The strong cache determines whether the cache is based on whether it exceeds a certain time or a certain period of time, and does not care whether the server-side file has been updated, which may cause the loaded file to not be the latest content on the server-side, so how do we know the server-side content? Has the client been updated ? At this point we need to negotiate a caching strategy.
2. Negotiation cache: Send a request to the server, and the server will determine whether to hit the negotiation cache according to some parameters of the request header of the request. If it hits, it will return a 304 status code and bring a new response header to notify the browser to read from the cache. Get resources; in addition, the negotiated cache needs to be used together with cache-control.
Related headers:
① Last-Modified and If-Modified-Since : When the resource is requested for the first time, when the server passes the resource to the client, it will add the last modified time of the resource to the entity header in the form of "Last-Modified: GMT". returned to the client.
Last-Modified: Fri, 22 Jul 2016 01:47:00 GMT
The client will mark the resource with this information, and next time it requests again, it will attach the information to the request message and bring it to the server for inspection. If the passed time value is consistent with the final modification time of the resource on the server , it means that the resource has not been modified, and the 304 status code is returned directly, and the content is empty , which saves the amount of transmitted data. If the two times do not match, the server will send back the resource with a 200 status code, similar to the first request. This ensures that resources are not repeatedly sent to the client, and that when the server changes, the client can get the latest resources. A 304 response is usually much smaller than a static resource, thus saving network bandwidth.
But last-modified has some disadvantages:
Ⅰ. Some servers cannot obtain the exact modification time
Ⅱ. The modification time of the file has changed, but the content of the file has not changed
Since whether the cache is still insufficient is determined based on the file modification time, can the cache strategy be determined directly based on whether the file content is modified? ----ETag and If-None-Match
② ETag and If-None-Match : Etag is the response header returned by the server when the resource was loaded last time. It is a unique identifier for the resource. As long as the resource changes, the Etag will be regenerated. The next time the browser loads the resource and sends a request to the server, it will put the Etag value returned last time into the If-None-Match in the request header. The server only needs to compare the If-None-Match sent by the client with its own server. If the ETag of the resource is consistent, it can be well judged whether the resource has been modified relative to the client. If the server finds that the ETag does not match, it will directly send the new resource (including the new ETag) to the client in the form of a regular GET 200 return packet; if the ETag is consistent, it will directly return 304 to notify the client directly Just use local cache.
Comparison between the two :
First of all, Etag is better than Last-Modified in terms of accuracy . The time unit of Last-Modified is seconds. If a file is changed multiple times within 1 second, then their Last-Modified does not actually reflect the modification, but the Etag will change every time to ensure accuracy; if it is load balanced The Last-Modified generated by each server may also be inconsistent.
Second, in terms of performance, Etag is inferior to Last-Modified . After all, Last-Modified only needs to record the time, and Etag needs the server to calculate a hash value through an algorithm.
Third, in terms of priority, server verification gives priority to Etag
caching mechanism
Mandatory caching takes precedence over negotiated caching. If mandatory caching (Expires and Cache-Control) takes effect, the cache is used directly. If it does not take effect, negotiated caching is performed (Last-Modified / If-Modified-Since and Etag / If-None-Match) , the negotiated cache is determined by the server whether to use the cache. If the negotiated cache is invalid, the cache representing the request is invalid, and the request result is re-fetched and stored in the browser cache; if it is valid, it returns 304 and continues to use the cache . The main process is as follows:
The impact of user behavior on browser caching
1. Address bar access and link jumping are normal user behaviors, which will trigger the browser caching mechanism;
2. F5 refresh, the browser will set max-age=0, skip the strong cache judgment, and will negotiate the cache judgment;
3. ctrl+F5 refresh, skip strong cache and negotiation cache, and pull resources directly from the server.
If you want to know more about the caching mechanism, please click to understand the caching mechanism of the browser
4. Use CDN
The pursuit of speed in large-scale web applications does not stop at the browser cache, because the browser cache is always only to improve the speed of the second visit. For the acceleration of the first visit, we need to optimize from the network level. The most common method is to CDN (Content Delivery Network) acceleration. By caching static resources (such as javascript, css, pictures, etc.) to the CDN node of the same network operator that is close to the user, it can not only improve the access speed of the user, but also save the bandwidth consumption of the server and reduce the load.
How does CDN accelerate?
In fact, this is a CDN service provider deploying computing nodes in various provinces across the country. CDN accelerates caching of website content at the edge of the network, and users in different regions will access the nearest CDN nodes on the same network line. When the request reaches the CDN node After that, the node will judge whether its own content cache is valid. If it is valid, it will immediately respond to the cached content to the user, thereby speeding up the response speed. If the cache of the CDN node is invalid, it will go to our content source server to obtain the latest resource response to the user according to the service configuration, and cache the content to respond to subsequent users. Therefore, as long as one user in a region loads resources first and establishes a cache in the CDN, other subsequent users in the region can benefit from it .
5. Pre-parse DNS
Resource preloading is another performance optimization technique that we can use to inform the browser in advance that certain resources may be used in the future.
Through DNS pre-resolution to tell the browser that we may obtain resources from a specific URL in the future, when the browser actually uses a resource in the domain, DNS resolution can be completed as soon as possible. For example, in the future we can get images or audio assets from example.com, then we can include the following in the tag at the top of the document:
<link rel="dns-prefetch" href="//example.com">
When we request a resource from this URL, we no longer need to wait for the DNS resolution process. This technique is especially useful for using third-party resources. A simple line of code can tell those compatible browsers to do DNS pre-resolving, which means that when the browser actually requests a resource in that domain, the DNS resolution is already done, saving valuable time.
In addition, it should be noted that the browser will automatically enable DNS Prefetching for the href of the a tag, so the domain name contained in the a tag does not need to manually set the link in the head. But it does not work under HTTPS, and requires meta to force the function to be turned on . The reason for this restriction is to prevent eavesdroppers from inferring hostnames displayed in hyperlinks in HTTPS pages based on DNS Prefetching. The function of the following sentence is to force the opening of the a-tag domain name resolution
<meta http-equiv="x-dns-prefetch-control" content="on">