This article is mainly a summary of notes documenting front-end performance optimization, and also refers to the following articles;

Summary of performance optimization: reduce the number of requests, reduce the size of resources, improve the response and loading speed, optimize the loading time of resources, optimize the loading mode

Performance classification

I think the optimization of front-end engineering performance can be divided into two categories:

  • Subjective and perceived performance from the user’s perspective.
  • Objectively measurable performance from a developer’s perspective.

In short, your page can be fast, but you can make your users feel fast.

Objective performance is a measure of time from the time the user enters the URL to the time all resources are downloaded, parsed, and executed, and eventually drawn.

Reduce the number of requests

  • Webpack url-loader set limit, images exceeding limit size, parsing into base64 bits, reduce image requests;

Reduce resource size

  • With gzip compression or compression-webpack-plugin enabled, gzip compression is very efficient, usually up to 70% compression

  • Terser-webpack-plugin js compression, and remove console.log() and comments;

  • Remove SourceMap

  • Put the public resources on the CDN and work with webpack externals and the CDN

Improve packing speed

  • Webpack dllPlugin, autoDllPlugin, hardSourcePlugin out of public resources
  • HappyPack, threadloader multi-process packaging

Improved response and loading speed

  • Network resource optimization Service Worker

    • ServiceWorker is a SECTION of JS running in the browser background process. It can do many things, such as intercepting client requests, sending messages to clients, and making requests to servers. One of the most important functions is offline resource caching.

    • The ServiceWorker has rich and flexible control over the cache process. When a page request is made to the ServiceWorker, the ServiceWorker requests the cache and the network at the same time, directly delivers the cached content to the user, and then overwrites the cache

    Note: You need HTTPS to use ServiceWorker

  • HTTP cache

    • Cache strategy analysis:

    1. Enter the label, enter the URL, and press Enter to enter:

    1) If no-cache and no-store are not set, strong cache is used by default. Determines whether the cache expires based on cache-control, or returns 200(from cache) if not.

    2) If the local cache has expired, the negotiation cache will be compared with the server based on the previous last-Modified value. If the local cache has not been modified after this time, the local cache will be read and 304(not Modified) will be returned.

    3) Otherwise return the new resource, status code 200(OK), and update the last-Modified value of the returned response.

    2, press the refresh button, F5 refresh, webpage right click “reload” :

    In this case, the browser actually sets the max-age of cache-control to 0, allowing the cache to expire immediately and go directly to the negotiated cache route

    3, CTRL + F5 force refresh:

    In the case of a forced refresh, the browser forces the request header cache-control: no-cache to fetch the latest resource, and even the if-modified-since and other cache protocol fields in the request header are eaten.

    • What is caching

    Brower Caching enables the browser to cache previously requested files so that they can be reused for next access, saving bandwidth, improving access speed, and reducing server pressure.

    HTTP caches generally fall into two categories: strong cache (200, also known as local cache) and negotiated cache (also known as 304 cache).

    A normal refresh enables negotiated caching and ignores strong caching. Strong caching is enabled only when you enter a url in the address bar or favorites, reference a resource through a link, and so on.

    • How does the browser decide whether to use caching or not

      First request:

      Second request for same page:

    • Strong cache (200) : The browser does not send any requests to the server, reads the file directly from the local cache and returns Status Code: 200 OK

    Local caching is the fastest way of caching. As long as the resource is still in the cache, the browser will read it directly locally without asking the server.

    200 Form memory cache: does not access the server. Usually, the resource has been loaded and cached in the server’s memory. When the browser closes, the data will not exist (the resource has been freed), and when the same page is opened again, the from Memory cache will not appear.

    200 From Disk cache: does not access the server. The resource has been loaded at a previous time. The cache is directly read from the hard disk.

    • Negotiation cache (304) : Sends requests to the server

    Negotiation cache, as the name implies, is negotiated between the browser and the server, after deciding whether to read the local cache. If the server notifies the browser that it can read the local cache, the 304 status code will be returned, and the negotiation process is very simple, only the header message will be sent, not the response body.

    Send a request to the server, and the server will judge whether the negotiation cache is hit according to some parameters of the request header. If yes, it will return the 304 status code with a new Response header to inform the browser to read resources from the cache.

    • The cache location

    The Cache location is usually divided into Memory Cache and Disk Cache.

    Memory cache: fast read, short duration, small capacity

    Hard disk cache: Reads data slowly, lasts for a long time, and has a large capacity

    • Cache priority

    Service Worker -> Memory Cache -> Disk Cache -> Network request

    • Header parameters for strong and negotiated caching

      Strong cache:

      1.Expires: Expires time. If a time is set, the browser will directly read the cache within the set time and will not request any more. Expires is set to Time, and the Time is Greenwich Mean Time (GMT), not local Time, so it has a high Time requirement.

      Cache-control: when max-age=300, the strong Cache will be hit if the resource is reloaded within 5 minutes of the correct return time of the request (which is also recorded by the browser).

      3. Cache-control: In addition to this field, there are several common Settings:

      All representations of resources can be cached in seconds.

      2) s-maxage: the same as max-age, but only for proxy caches;

      3) public: indicates that the response can be cached by any cache;

      4) private: can only be used for individual users and cannot be cached by proxy servers;

      5) no-cache: Forces the client to send requests directly to the server, that is, every request must be sent to the server. The server receives the request and determines if the resource has changed, returns new content if it has, or 304 unchanged if it has not. This can be very misleading and can be mistaken for a response that is not cached. Cache-control: no-cache is actually cached, but the Cache evaluates the validity of the cached response to the server each time it provides response data to the client (browser).

      6) no-store: disables all caching (this is what responses are not cached).

      Cache-control is an HTTP1.1 header field, and Expires is an HTTP1.0 header field. If both expires and cache-Control exist, cache-Control overwrites expires.

      Negotiation cache:

      Last-modifed/if-modified-since and Etag/ if-none-match are paired separately in a one-to-one relationship.

      • Etag/If None – Match:

        Etag:

        Etag is an HTTP 1.1 attribute that is generated by the server (Apache or another tool) and returned to the front end to help the server control caching validation on the Web side. In Apache, the value of ETag is hashed by INode, Size, and last modified time.

        If-None-Match:

        When the resource expires and the browser finds an Etag in the response header, it will apply the request header if-none-match(the value of the Etag) to the server’s request. The server receives the request for comparison and decides to return either 200 or 304

      • The Last – the Modifed/If – Modified – Since:

        Last-modified:

        The browser sends the last modification of the resource to the server

        The if-modified-since:

        When a resource expires (the browser determines the max-age expiration of the cache-control identifier) and finds a last-Modified statement in the response header, the browser sends a request to the server again with if-Modified-since, indicating the request time. If the request is received, the server finds if-modified-since and compares it with the Last modified time of the requested resource (last-modified). If the Last modified time is new (large), it indicates that the resource has been modified again, and returns the latest resource, HTTP 200 OK; If the last modification time is earlier (smaller), the resource is not updated, and the response is HTTP 304.

        • Last-modifed/if-Modified-since time accuracy is in seconds, whereas Etag can be more accurate.

        • The Etag priority is higher than last-modiFed, so the server validates the Etag first

        • Last-modifed/if-Modified-since is the header field for HTTP1.0

  • HTTP2

    Four new features of HTTP2:

    • Multiplexing eliminates the need for multiple TCP connections because it allows multiple requests to be made on a single HTTP2 connection and therefore does not rely on establishing multiple TCP connections.

    • Binary framing, which encodes all messages to be transmitted (response and request bodies) in binary and divides the information into smaller message blocks.

    • Header compression: Uses the HPACK technology to compress the header and reduce the packet size

    • Server push. The server can send data before the client initiates a request. In other words, the server can send multiple responses to a request from the client, and the resources can be properly cached.

    Note: To use HTTP2, you must use HTTPS.

Resource preloading

Use of link tags:

Summary: Use preload to preload resources required by the current page and prefetch to preload resources required by other pages.

  • Preload: Loaded during the current page load before the browser begins the body rendering.

    <! <link rel="preload" href="style.css" as="style"> <link rel="preload" href="index.js" as="script">Copy the code
  • Dns-prefetch: The transformation work is carried out ahead of time, shortening the time of resource request.

    <link rel="dns-prefetch" href="//example.com">
    Copy the code

    When will it be used? When we use other domain name resources in the page, for example, our static resources are placed on the CDN, then we can pre-resolve the domain name of the CDN.

  • Preconnect: link

    <link rel="preconnect" href="//example.com">
    <link rel="preconnect" href="//cdn.example.com" crossorigin>
    Copy the code

    When we visit a site, we simply go through the following steps:

    1. The DNS
    2. TCP handshake
    3. If the site is Https, the TLS handshake is performed

    With PreConnect, the browser pre-initializes the link for a specific domain name (all three steps above), saving us time to access third-party resources. It is important to make sure that preConnect’s site is required for web pages, otherwise it will waste browser and network resources.

  • Prefetch: prefetch. After a page is loaded, resources on other pages are loaded in advance in idle time.

    <! <link rel="prefetch" href=" next-.css "> <link rel="prefetch" href=" next-.js "> <link rel="prefetch" href="//example.com/next-page.html" as="document" crossorigin="use-credentials"> <link rel="prefetch" href="/library.js"  as="script">Copy the code

    With Prefetch, the resource is just downloaded in advance, and no action, such as parsing the resource, takes place after the download.

  • Prerender: Prerender

    <link rel="prerender" href="//example.com/next-page.html">
    Copy the code

    Prerender goes one step further than Prefetch. Not only will the corresponding resource be downloaded, but it will also be parsed.

    If additional resources are needed during parsing, they may be downloaded directly. This allows the browser to respond more quickly when the user jumps from the current page to the target page.

Resource Hints are just “Hints”. Browsers can use our Hints, but it’s up to the browser to implement them. For example, if you use Prefetch when the CPU is currently under pressure and the network is congested, the browser may only pre-parse DNS and not download resources.

How to load javascript resources

  • A normal script would block the execution of the following code, DOM rendering, which is generally recommended under the body.

    <script src="a.js" ></script> 1. Stop parsing document.2. Request A. js 3. Execute script 4 in A. js. Continue parsing the documentCopy the code
  • defer

    Load js files asynchronously without blocking page rendering.

    <script src="d.js" defer></script> <script src="e.js" defer></script> 1. Do not prevent document parsing, parallel downloading of D. js, e.js; 2. Even after downloading D. js, E.js continues to parse document; 3. Execute d.js and e.js after the execution of other synchronization scripts and before the DOMContentLoaded event according to the order in the page;Copy the code
  • async

    <script src="b.js" async></script> <script src="c.js" async></script> 1. Do not prevent document parsing, parallel downloading of B. js, C. js 2. Execute the script immediately after it is downloaded. (The execution sequence and execution stage are uncertain, which may be before or after the DOMContentLoaded event)Copy the code

User perception performance optimization

  • Image lazy load imgLazyLoad
  • Skeleton screen

Reference: several uses of the Link tag to help improve page performance summary of front-end performance optimization