Original Panming Baidu App technology

preface

Performance is a topic that every front-end engineer should pay attention to. General optimization methods have many articles and practices, which will not be described again. This article takes baidu App personal homepage as an example to talk about some performance optimization practices for business characteristics.

Suitable for: the traditional sense of optimization means can be used: packaging and unpacking, reduce the volume and HTTP request number, CDN and load on demand, but the performance is still not ideal.

Define indicators and build reports

The formulation of good programs first needs accurate data to do the support.

Generally speaking, front-end performance indicators include DOM Ready, First Contentful Paint, white screen, First screen, user operation time, and onload time. In practice, front-end performance indicators need to be defined based on the characteristics of the service itself. Common indicators cannot reflect the real user experience in the current service.

Personal home page is a web page in Baidu App client. There are two different opening modes: Hybrid version (using file protocol to directly load local HTML, JS, and CSS) and Web version (opening a Web URL).

First, let’s take a look at the structure of your home page:

The process of opening your home page can be simplified as follows:

The user data displayed on the home page is an asynchronous rendering of THE DATA requested by JS on the page. Therefore, the first screen is defined as: the header area and TAB list the first screen data is rendered (the user can actually see, i.e. the user can manipulate time).

The main page is a SPA page built by SAN. No real content of THE DOM synchronized on THE HTML appears. The page is in loading state before the user data is returned to the first screen. So a white screen is defined as: when the page DOM mounts content (the first time the user sees the page is no longer blank)

In the end, iOS and Android onload events are triggered at different times. Resource loading on iOS will block page rendering. Therefore, the main page is adjusted for iOS by using rAF to trigger onLoad when JS starts to execute. However, Android triggers after the load of all the resources required by the first screen, such as pictures and JSONP, is completed. Therefore, this indicator is mainly used as an auxiliary function.

  • Group the three versions of the home page: Hybrid, Hybrid Web, and Web. The data interference can be avoided, and the experimental comparison can be carried out by controlling the on-line time
  • System, inside and outside end and starting point are added as screening conditions to exclude data differences caused by different use conditions, which helps to narrow the scope and locate the analysis
  • According to the home page of the implementation process, to subdivide time-consuming process, further location problem, the whole phase subdivided into: end time (from click to parse the top head page), synchronous within the HTML that JS reference phase time-consuming, data request time-consuming, the ability and the interconnected life cycle within the page to the first screen to take (take part in the practical optimization stepwise refinement analysis)

Finally, the detailed division of each stage is obtained:

  • End-to-end operation records data from the user’s operation time, covering the complete process of client time, network time, server time, and front-end time from the user’s click to the page display. Among them, the start time stamp is recorded by the previous page when the user operates, and transparently transmitted to the personal home page; The front-end records the current timestamp each time it initiates a network request, and the return value of the interface returns the time spent by the back-end processing interface. The difference between the two values is the time spent on the HTTP connection. This time, the scheme of front-end calculation reporting and platform display is adopted. The front-end control is flexible and the iteration is fast.

  • The end time section can only calculate the total time from the previous page click to the top of the parsing page.

Data analysis, put forward optimization direction

After stage 1, get stable data and time consuming of each stage of the page, analyze and propose solutions.

End time, start time of introducing main profile.js into JS, time of first-screen interface, time of page data processing and rendering

  • For the end time, the front-end cooperated with the end to find the optimization point
  • In view of the time consuming of the interface on the first screen, the front-end combined with the server optimized the interface
  • In view of the internal time consuming of JS, the front-end carries out its own code optimization

Start optimizing and gradually improve

There are many main page entrances, which need to be compatible with different entrance situations and historical legacy. The basic situation of personal home page services is as follows:

  • The page is in SPA mode, but the business is complex and the total volume of code is large
  • Resources required by the first screen of hybrid version are returned by two interfaces, and the two interfaces are dependent on each other, so they are executed in front of each other
  • The top user data of the Web edition uses synchronous data and relies on the same TAB interface as hybrid
  • Hybrid version features:
    • Hybrid uses the same set of code compiled differently from the Web version, but on the Web version the first interface is synchronous and the data is returned along with the HTML template, whereas in Hybrid all interfaces are asynchronous
    • More scenarios are used
    • File protocol is used to load HTML template, and jSONP method is used to request back-end data interface

According to the four directions of front-end code, engineering, server and client native framework, optimization plans are made respectively. The following two aspects are mainly introduced: front-end controllable code and engineering.

The front-end code

IOS onLoad is triggered in advance

  • Method: Use rAF nested setTimeout to trigger onload event in advance to solve the situation of iOS resource loading blocking page display
  • Revenue: The first screen time visible to the user is not blocked by load

Reduce first screen dependency

The first screen time reflects the user’s perception of page speed. The more behaviors the first screen relies on, the longer the user has to wait. Therefore, in performance optimization, operations performed in front of the first screen should be reduced as much as possible, and some unnecessary operations should be put after, which can improve user experience to some extent.

After a period of data collection and analysis and code review, we found some areas that can be improved:

  • In the logic before the first screen, JS invokes multiple methods (end capability) provided by Native at one time when initializing some data, resulting in the execution time of end capability being 80 qubits, far exceeding the theoretical value.
  • The App, the outermost component of the SPA page, is mounted only after the data from the first interface is returned. For web pages, the first interface is synchronous, so App mounting after the interface has little impact. However, for hybrid versions with more application scenarios, the first screen of a page requires at least two interfaces, and all interface requests are asynchronous. Before the first interface is returned, it is enough to process the necessary logic of many pages, so the mounting time of App is very inappropriate.
  • There are a lot of dots buried on the page. Except for PV, most of them are the dots of some small components on the page. Sending dot requests frequently before the first screen takes up the loading time of pictures in the first screen.

Combined with the above findings, the code was adjusted as follows:

  • Adjust the execution sequence of the call with native terminal ability, leave the necessary first screen, and put the other ones after, so as to reduce the execution time of terminal ability
  • Optimize the initialization logic for the necessary code information (for example, the runtime from beginning to end of the personal home page)
  • The outermost App component mount does not depend on interface data. The page is initialized in advance, and interface data is requested in parallel and rendered asynchronously
  • Adjust code execution logic, move key logic to Store, execute ahead of schedule
  • Logical postpositions, such as some dots in the page, reduce the page mounting time

A wave of operations down, the gain of 80 qubits 100ms+.

Merge interfaces on the first screen

As mentioned above, the hybrid first screen requires the serial execution of two asynchronous network interfaces at the front end. In terms of statistics and performance data, it takes the longest time to establish a network connection in the process of calling the interface and getting the interface data. Merging two interfaces into one interface can save at least one time to establish a network connection in the first screen time (the personal home page has achieved 110ms+). Of course, interface merge also needs to consider the server side of the flat noise, considering the loss of white screen time.

Front screen port front

As a standard SPA page, almost all of the logic on the personal home page is executed after the public JS load is complete, but js loading takes time, especially when it is first loaded and there is no local cache. The Hybrid version has no synchronization interface and can only send the first request of the first screen after js loading is complete, so there is still room for optimization in the hybrid version.

It is known that the requests that can be processed in parallel by mainstream browsers are usually 4~6 by default. When loading JS, the data required by the first screen is taken (JSONP), and the serial changes into parallel, saving the time of overlap between the two. This is what the front-screen interface does: When hybrid packs, it inlines a minimal code package as small as possible to fetch the data from the first interface on the front-screen, stores it in global variables and sends it out as an event. In some iOS scenarios, it takes a long time to establish a network connection for the first time, and the native terminal capability is used to replace JSONP. In the front-screen interface, the revenue of iOS is 260ms+ and android is about 60ms.

engineering

The engineering optimization is mainly focused on packaging, which affects the HTTP loading time of JS, CSS and other resources. Under the same conditions, the smaller the package size and the fewer requests, the faster the resource loading speed.

Pack and unpack

JS and CSS resources should be packaged and merged. However, you need to consider that the package file is too large and a single request takes too long. You need to split the code package based on service scenarios. Mainstream browsers can process 4~6 requests in parallel by default, which can reasonably split resource bundles and reduce the overall response time by using parallel requests. Make the most of the browser cache by partitioning packages properly. Lock the version, keep the hash value stable for each small bundle unchanged, and write large JS, CSS, and images directly to the hard disk cache. For example, personal homepages split JS packages into three of roughly the same size, vendors are various NPM dependencies, vendors are stable, and generally don’t change, based on the frequency of code changes. Each time the user browser goes live, it only needs to request two more code packages from the CDN, and the vendors use the local cache that didn’t expire last time.

Modern Mode

In general, we use ES6(ES2015+) to write our code while developing. The new features of ES6 make development work faster and faster, but when packaged, we need to use Babel to transform our code to run on non-ES6-enabled browsers. Polyfill is added to the converted code, and the most intuitive feeling is that the size of the code package increases. Modern mode In browsers that support native ES6, js is loaded using the ES module <script type=”module”>, while in unsupported browsers, the compiled version of Babel is loaded using <script nomodule>. And browsers that support the ES module ignore this notation. Why not use the ES6 version on a browser that supports ES6 and have smaller code bundles that parse and execute faster? Data collected from the personal homepage shows that 75% of the scenarios currently support Modern Mode, and the performance benefits are significant:

White (ms) The first screen (ms)
The experimental group 1055 1913
The control group 1136 2081
earnings 81 168

Summary of optimization effect

After optimization, JS initialization time is reduced. Jsonp requests for the first screen data are issued before the page is ready using an inline minimalist code package. Other CSS and JS resources required by the page are loaded in parallel before jSONP gets the return value. The time of App mounting and page runtime initialization is advanced, and the data can be processed and rendered immediately after the first screen data comes back, instead of being occupied by some other operations. Before the end of the first screen, LET JS focus on data and rendering, while freeing up bandwidth to load images and other resources visible to the user. The optimized process can be shown in the following figure:

On Android, thanks to the optimization of hybrid framework, the loading speed of hybrid pages and local JS resources is faster and the effect is more significant.

conclusion

To do a good job, he must sharpen his tools. Before starting optimization, a lot of time was spent on selecting data reference points, collecting data, and ensuring that each key indicator reflected authentic and credible data through repeated code review, experiments, and business logic elaboration. This paper only provides an optimization point analysis method based on data. The optimization method listed is inseparable from the actual business and does not have strong universality. I hope it can bring a different way of thinking to solve the bottleneck.