Content is arranged in wechat open class

Why do performance tuning?

All performance optimizations are about experience optimizations

1. When using small programs, do you often encounter the following problems?

  • Open is always a white screen

  • In loading mode, turn several times

  • My page point how jump so slow?

  • Why is my list slipping and slipping?

2. What are our optimization directions?

  • Boot loading performance

  • Rendering performance

3. Start loading performance

1. First loading

Have you ever seen a picture of a small program that looks like this when it first loads?

What are the three states in this picture?

When the small program starts, wechat will show a fixed startup interface for the small program, which contains the icon, name and loading prompt icon of the small program. At this time, wechat will complete several work behind the back: download the small program code package, load the small program code package, initialize the small program home page. The downloaded small program code package is not the source code of the small program, but the compiled, compressed, packaged code package.

2. Loading sequence

What is the order in which small programs are loaded?

Wechat will prepare a general operating environment for small programs before they start. This runtime environment consists of several threads for the small program to use, in which the basic library of the small program is initialized, the common logic is executed in advance, and the small program is as ready to start as possible. This can significantly reduce the startup time of small programs.

Resources to prepare
Business code injection and landing page first rendering
Loading mode of landing page data request

3. Control the packet size

The most straightforward way to improve the experience is to control the size of small packages, which is the most obvious

  • Select the “compress code when uploading” option in developer tools.

  • Clean up useless code and resource files (including useless log code)

  • Reduce the number and size of images and other resources in the resource pack (in theory, except for small icon, other image resources can be downloaded from the network), and the compression rate of image resources is limited

From a developer’s point of view, controlling package size can help reduce startup time for small programs. For a code package less than 1MB, the download time can be controlled within 929ms (iOS) and 1500ms (Android).

4. Adopt subcontract loading mechanism

According to the business scenario, the pages with high user access rate are put into the main package, and the pages with low user access rate are put into the subpackage and loaded on demand.

5. Use subcontract preloading technology

On the basis of 4, when the user clicks to sub package directory, or is there a code package download process, it will feel obviously card, so package also hurt too big, is not recommended, of course, we can use sub package preload technology, does not need to wait until after the user clicks to sub package page in the download package, but late may, according to data, do bag preload, Load the subpackage page that the user may click in the current page first, and jump directly after the user clicks;

6. Use independent subcontracting technology

At present a lot of small programs main bag + child bag (2 m + 6 m), but when doing a lot of operating activities, we will find that activity (red envelope) is in the bag, but operation, products on the landing page of the link is the child bag, yes this user in direct landing, you must first download the main content of the package (more generally), son in the download package content (the main package, relatively less), This makes the user experience not very good and wastes a large part of the traffic in small program scenarios where the user stays short;

7. Optimize the first-screen loading

7.1 Advance Request

Asynchronous requests can be loaded when the page is onLoad, instead of waiting for the page to be ready. Of course, it would be better if you could pre-request the core asynchronous request of the current page when you click the jump on the front page;

7.2 Using the Cache

The storage API is used to cache the asynchronous data that changes less frequently. During the second startup, the cached data is first used to initialize rendering, and then the asynchronous data is updated in the background. This not only optimizes the performance, but also enables users to smoothly use key services in the netless environment.

7.3 Avoid white screens

Some useful fields can be brought to the current page in the front page, for the first rendering (some data in the list page -> details page), the module without data can be skeleton screen placeholder, the user will not wait very anxious, or even go;

7.4 Timely Feedback

Timely feedback on interactive operations that require users to wait, to avoid users thinking that the small program card, no response


Render performance optimization

1. Principle of small program rendering

Under the dual-thread interface rendering, the applet’s logical layer and the rendering layer are separated by two threads. In the rendering layer, the host environment will convert WXML into corresponding JS objects. When data changes occur in the logical layer, we need to pass the data from the logical layer to the rendering layer through the setData method provided by the host environment. After comparing the differences before and after, we apply the differences to the original Dom tree to render the correct UI interface.

If the data amount is less than 64KB, the total duration can be controlled within 30ms

2. Avoid using improper setData

During data transfer, the logical layer performs json. stringify once to remove the non-transferable parts of the setData and then sends the data to the view layer. At the same time, the logical layer will set the data field setData and data, so that developers can use this. Data to read the changed data. Therefore, in order to improve the performance of data updates, developers should follow the following principles when making setData calls:

2.1 Do not call setData too often. Consider combining multiple setData calls into a single setData call;

2.2 The performance of data communication is positively correlated with the amount of data. Therefore, if some data fields are not displayed in the interface and the data structure is complex or contains long strings, they should not be usedsetDataTo set the data;

2.3 Data that is not related to interface rendering should not be set in data. Consider setting it in another field of the Page object

Example code for ways to improve data update performance

Page({
  onShow: function() {

    // Don't call setData too often
    this.setData({ a: 1 })
    this.setData({ b: 2 })
    // Most of the time can be optimized to
    this.setData({ a: 1.b: 2 })

    // Do not set data that is not used in the rendering of the interface, and leave the interface irrelevant data out of the data
    this.setData({
      myData: {
        a: 'This string is used in WXML.'.b: 'This string is not used in WXML, and it is long ………………………… '}})// Can be optimized to
    this.setData({
      'myData.a': 'This string is used in WXML.'
    })
    this._myData = {
      b: 'This string is not used in WXML, and it is long ………………………… '}}})Copy the code
  • Use setData for local list refresh

In a list, there are n pieces of data, and more methods are used to pull up. If you want to like one of the data at this time, you can also see the effect of liking in time

  • The solution

1, you can use setData global refresh, after the completion of the thumbs up, to obtain data again, again global re rendering, the advantages of this is: convenient, fast! Disadvantages: The user experience is extremely bad, when the user brushes more than 100 pieces of data, the re-rendering amount will appear blank period (no rendering over).

2, the main point is to use setData local refresh

> a. Select * from 'like' where 'id' = 'like' and 'id' = 'like' where 'id' = 'like'Copy the code
<view wx:if="{{! item.status}}" class="btn" data-id="{{index}}" bindtap="couponTap"> Get </view>Copy the code
> b. Retrieve the data and find the index (' index 'is unchanged) > c. Local refresh with setDataCopy the code
this.setData({
    list[index] = newList[index]
})
Copy the code

In fact, this small operation to just touch the micro channel small program for people should be not easy to find, do not understand setData and such writing method.

2.4 Do not perform setData on the background page

In some pages will carry out some operations, and to the page jump, the code logic is still executing, at this time multiple WebViews are sharing a JS process; Background setData operations preempt foreground page rendering resources;

3. User events are improperly used

When the view layer feeds events back to the logical layer, a communication process is also required, and the direction of communication is from the view layer to the logical layer. Because this communication process is asynchronous, there will be a certain delay, and the delay time is also positively correlated with the amount of data transmitted. When the amount of data is less than 64KB, it will be within 30ms. There are two main ways to reduce latency.

1. Remove unnecessary event bindings (bind and catch in WXML), thus reducing the amount of data and times of communication; 2. Event binding needs to transfer the dataset of target and currentTarget, so do not place too much data in the data prefix attribute of the node.

4. Rendering principle of view layer

4.1 First Rendering

Initial rendering occurs when the page is just created. During initial rendering, the initial data is applied to the corresponding WXML fragment to generate the node tree. The node tree is the structure of the page tree that you see in the developer tools WXML panel. It contains information such as the names, property values, and event callbacks of all component nodes in the page. Finally, each component is created on the interface according to each node in the node tree.

Throughout this process, the time cost is roughly proportional to the total number of nodes in the node tree. Therefore, reducing the number of nodes in WXML can effectively reduce the time cost of initial rendering and rerendering, and improve rendering performance.

Examples of simplified WXML code

<view data-my-data="{{myData}}"> <! -- This view can be merged with the view on the next row -->
  <view class="my-class" data-my-data="{{myData}}" bindtap="onTap">
    <text> <! -- This text is usually unnecessary -->
      {{myText}}
    </text>
  </view>
</view>

<! -- can be simplified as -->

<view class="my-class" data-my-data="{{myData}}" bindtap="onTap">
  {{myText}}
</view>
Copy the code

4.2 heavy rendering

After the initial rendering, the view layer can apply setData data multiple times. Each time the setData data is applied, a re-render is performed to update the interface. The data obtained from the initial render and the current node tree are retained for rerendering. At each rerender, data and setData data are applied to the WXML fragment, resulting in a new tree of nodes. The new node tree is then compared to the current node tree to get a sense of which nodes need to be updated with which attributes, and which nodes need to be added or removed. Finally, the setData data is merged into the data and the old node tree is replaced with the new node tree for the next rerendering.

When the current node tree is compared to the new node tree, the node attributes affected by the setData data are compared. Therefore, removing unnecessary Settings and reducing the amount of setData can also help improve the performance of this step.

5. Use custom components

The update of a custom component is only carried out within the component, and is not affected by other contents that cannot be divided on the page. For example, the timing module of some operational activities can be extracted separately and made into a timing component. The update of the timing component will not affect the update of other elements on the page. Each component will also have its own logical space. Each component has its own separate data, setData call.

6. Avoid improper use of onPageScroll

Every event listening is a view-to-logic communication, so only listen to pageSrcoll when necessary

conclusion

Applet startup loading performance

  • Control the size of the code package

  • The subcontract to load

  • First screen experience (pre-request, use cache, avoid white screen, timely feedback

Small program rendering performance

  • Avoid improper use of setData

  • Rational use of event communication

  • Avoid improper use of onPageScroll

  • Optimizing view nodes

  • Use custom components