preface

For an app, good performance means fast first screen rendering, short white screen time, smooth interaction, and improved retention and conversion rates, so performance optimization is important for the product. Performance optimization of the knowledge is scattered, also very test a programmer’s basic skills, a lot of interview will be asked this question, I also like to chat with candidates from this topic, unfortunately there are very few candidates can reach the level of pass), therefore prepared a series of articles talk about the former point of view, how to do performance tuning.

Performance optimization tests comprehensive ability, depth and breadth of knowledge and comprehensive use of tools. It is necessary to know the complete process of an application from request initiation to interaction, which links can be optimized in the process, how to do the optimization scheme, and how to operate and implement the project. This series of articles will be elaborated from the perspectives of network, operation, construction and tools.

Network overview

Let’s take a look at the full flow of a request from the W3C.

As can be seen from the figure, the request process can be divided into three parts: before the request, sending the request, and receiving the response. Next, we will focus on the following parts for optimization:

  1. Reduce the number of requests
  2. Reduce the preparation time, the data carried by the request, and the size of the response body
  3. Prepare data in advance and reuse data
  4. Request as parallel as possible, reduce serial

The Http request

1. Avoid redirection

Each redirection goes through a full HTTP/HTTPS process, which takes a large part of the time on the network.

As you can see in the graph above, I spent an extra 134ms on a single page visit.

Of course, some requests are inevitably redirected. For example, when the domain name changes, users using the old domain name need to be redirected to the new domain name. For example, in some advertising services, redirection is often carried more than once to ensure that business data is carried.

2. DNS preresolution

Dns-prefetch is used to synchronize DNS pre-resolution in the background when the page is loaded. Refer to the MDN

Configure DNS pre-resolution for domain names used in applications to reduce the DNS resolution time for initial requests.

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

3. Resource preprocessing

  1. Resources prefetch

During page loading, resources are downloaded synchronously in the background. Refer to the MDN

<link rel="prefetch" href="assets/index.png">
<link rel="prefetch" href="second.video">
Copy the code
  1. Resources preload

Resources are downloaded during page loading (before the browser’s main rendering mechanism kicks in). Refer to the MDN

For resources that are needed immediately after the page loads, you can configure preload. Commonly used font files, the first screen used CSS, JS and so on.

<link rel="preload" href="main.css">
<link rel="preload" href="main.js">
<link rel="preload" href="fonts/index.eot">
Copy the code

3. HTTP cache: strong cache and negotiated cache

HTTP caches generally fall into two categories: strong cache and negotiated cache.

Let’s start with a graph to see how these two types of caches behave.

Strong cache:

Strong caching is one of the fastest caching methods because it does not require network consumption by the requesting server and reads directly from the local resource as long as the resource is still in the cache life.

As shown in the figure above, disk cache and memory chache are both local caches. You can see that the status of strong cache is 200 (Chrome). In addition, we can see that the Time of the memory cache is 0ms, because the reading Time from the application memory is almost negligible. Disk cache Time is very small, only a few milliseconds, this is the disk I/O overhead.

The header fields that Control strong caching are Expires and cache-Control, which indicate how long the Cache is valid. If both fields exist, cache-control has a higher priority.

Negotiation cache:

Negotiation cache, as its name implies, is a negotiation between the browser and the server, which negotiates whether the content of the server has changed. If there is no change, the local cache is used. If there is change, the new content is returned.

In the figure above, a status of 304 indicates a negotiated cache, and the 304 status code indicates that the file is changed (Chrome).

The header fields that control the negotiated cache are Etag and Last-Modified. Etag indicates the uniqueness of resources. The Etag value varies with resources. Last-modified Indicates the time when the resource was last modified.

These two fields can be used together, and the service will judge the Etag first and last-Modified if the Etag is the same. This raises the question of why last-Modified Etag is needed:

  1. Some files may change periodically, but their contents do not change (only the modification time), and we do not want the browser to think that the file has been modified;
  2. Some files are Modified very frequently (e.g., N times in 1s), and last-modified values are accurate to s-level;
  3. Some servers do not know exactly when a file was last modified.

Finally, a diagram shows the flow of the cache.

How to invalidate the cache:

  1. Chrome devTools Select Disable cache

  1. Page refresh: Command + F5, address bar press Enter
  2. What the code does not want the resource hit cache to do is usually change the url of the resource in a meaningless parameter (because the HTTP cache is indexed by the full URL).
- <img src="https://hao5.qhimg.com/t01d1024d05f4567a06.gif" />
+ <img src="https://hao5.qhimg.com/t01d1024d05f4567a06.gif?t=1323423" />
Copy the code

4. Reduce the number of HTTP requests

Because the time on the network is very high, we need to consolidate some small HTTP requests to reduce the number of HTTP requests.

Common practices include:

  1. Merge static resources such as JS and CSS. For example, merge several CSS files into one CSS file.
  2. Some small ICONS used in THE CSS are merged into Sprite images.
  3. Base64 use: some small images with low reusability can be converted to Base64 to reduce the number of HTTP requests.
  4. Don’t use images when you can use CSS.

Note: Reducing the number of requests and reducing the size of the response body may seem like a paradox, so we need to balance the number of requests and the size of the response body while taking full advantage of the browser’s concurrency capabilities. Request concurrency and response body size will also be addressed later.

5. Reduce header size: Manage the use of cookies and domain names

  1. To manage the writing of cookies, prohibit too much content and unnecessary content to write cookies.
  2. Cookie writing Manages domain names. Cookie writing of root domain names must be strictly restricted.
  3. To separate functional domain names from non-functional domain names, the domain name of static resources must be separated from the domain name of websites and interfaces to reduce the size of static resource request headers.

6. Reduce the response body size of the request

  1. Compress the js, CSS and other resources.
  2. Compress images and other resources without affecting vision;
  3. Load in different formats for different browsers (e.g. Webp in Chrome)
  4. Reduce the size of the request body by gzip compression

7. Use the CDN

Static resources (CSS, JS, images, etc.) and invariant content class interfaces use CDN.

  1. It can reduce the overload pressure of the main application service and improve the response speed of the main application.
  2. Users can obtain the required content in the nearest location to improve the response speed and hit ratio.
  3. After the CDN is used, the domain name of the CDN is different from the domain name of the main application, and the cookie is naturally isolated.

8. Use local cache content

Make proper use of caching technologies such as localStorage, sessionStorage, indexedDb, and Web SQL to reuse reusable data or non-real-time information content in the cache browser for secondary access and reuse to improve the display speed of page content.

9. Use of placeholder maps

The use of a placeholder map, the user visual content, is to avoid a long white screen is an effective means. But there are two things to note when using a placeholder map:

  1. The entire application uses a set of placeholder maps, and the mandatory cache can be set to a longer validity period.
  2. The size of the placeholder map or the container in which the placeholder map resides should be the same as the size of the final display, otherwise a splash screen effect will appear. At the same time, performance is impaired due to triggering backflow.

10. Service Worker

Service Workers are used to cache resources offline. When users access resources again, they can use the offline cache to quickly open applications.

Offline cache is one of the most important capabilities of service workers, which can be used to make PWA applications.

Note: The application must be HTTPS.

11. Take advantage of the browser’s concurrency limit

The current mainstream browsers control the number of concurrent TCP connection requests at about 6 (Chrome and Firefox 6), which is undoubtedly a bottleneck under the premise of more than 100 full-page requests. Hence the use of domain hash technology to use multiple domain names to increase concurrency (since browsers are based on domain concurrency control, not page), but too much spread can increase the burden of DNS resolution, so limit it to around four.

For example, if we have four domain names (s1 ~ s4).qhimg.com, we need to ensure in our code that for static resources that are used, we dynamically allocate the requested domain name to resources that fall between S1 and S4.

For example, the static resources of 360 navigation are hashed under hao1 ~ hao5.

Http2.0 advanced

Http2.0 brings four main features: binary, header compression, multiplexing, and server push.

Header compression and multiplexing provide performance improvements.

  1. The header compression

HTTP1.1 Each communication carries a set of headers that describe the resources, browser properties, cookies, and so on for the communication. Under HTTP2:

  • HTTP/2 uses “header tables” on both the client and server sides to track and store previously sent key-value pairs, instead of sending the same data through each request and response;
  • The header table exists throughout the lifetime of the HTTP/2 connection and is gradually updated by both the client and the server.
  • Each new head key-value pair is either appended to the end of the current table or replaces the previous value in the table.
  1. multiplexing

In http1.1, you must use multiple TCP connections to make multiple requests, and the browser has a limit of six connections for a single domain name to control resources. Any connection beyond this limit requires pending.

Under HTTP2.0, this feature of multiplexing leads to significant performance improvements:

  • A domain name requires only one TCP connection, eliminating the delay and memory consumption caused by multiple TCP connections.
  • Requests and responses can be interleaved in parallel on a single connection, with no interference between them.

Chrome DevTools Is a web-based tool

  1. Network
  • On the network, you can view the status, type, size, and time of HTTP requests. You can filter requests of different types.

  • You can disable caching, which is very important during development, so you don’t lose sight of the changes because of caching.

  • You can click on a network request to see how long it takes at each stage.

  • Request headers and Respond headers

  1. Application