On the Operating Mechanism of Small Programs

  html5, javascript, Small program

Writing background

Contact with small programs has been going on for some time. Generally speaking, the development threshold of small programs is relatively low, but the basic operation mechanism and principle still need to be understood. “For example, when I was interviewing, I asked a question about the applet. Do the applets have window objects? He said yes “,but in fact there is no. I feel that he did not understand some things at the bottom of the applet. In the final analysis, he should only be able to use this tool, but he did not understand the reason.

The development of small programs is very different from that of ordinary web pages, which needs to be analyzed from the bottom of its technical framework. For example, developers who are accustomed to Vue and react development will complain about the complexity of creating new pages for small programs. page must be composed of multiple files, the component support is not perfect, every time data in Data is changed, setData is required, there is no convenient watch monitoring like Vue, Dom cannot be operated, and it is not very good for complex scenes. npm and sass and less precompiled processing languages are not supported before.

“Some people say that small programs are like castrated Vue.” Ha ha, of course, they have different starting points from the design. We also have to understand the original intention of small program design. Through its use scenarios, why it adopts this technical architecture and what benefits it has. I believe you will understand after you have understood these. I will analyze the operation mechanism of the applet and its overall technical framework from the following angles.

Understand the origin of applets

Before the applet came out, WeChat webView gradually became an important portal for mobile Web. WeChat released a complete set of Web page development kits, called JS-SDK, which opened a brand-new window for all Web developers to use WeChat’s native capabilities to accomplish some things previously impossible or difficult to do.

However, the JS-SDK model does not solve the problem of poor experience when using mobile web pages, such as the possibility of a white screen due to the limitation of device performance and network speed. Therefore, an enhanced version of JS-SDK, namely “WeChat Web Resources Offline Storage”, is designed. However, the problem of white screen still appears on complex pages due to the stiff page switching and sluggish clicking. At this time, we need a system that JS-SDK can’t handle to make the user experience better. Small programs came into being.

  • Fast loading
  • More powerful capabilities
  • Native experience
  • Easy-to-use and Secure WeChat Data Openness
  • Efficient and simple development

The Difference between Small Programs and Common Web Page Development

The development of small programs is very similar to that of ordinary web pages. The main development language of small programs is JavaScript, but there are still some differences between the two.

  • Common web page development can use DOM API provided by various browsers for DOM operations. The logic layer and rendering layer of small programs are separated, and the logic layer runs on JSCore
    In, there is not a complete browser object, so the related DOM API and BOM are missing.
    API。
  • Ordinary web page development rendering thread and script thread are mutually exclusive, which is why long-term script running may cause the page to lose response, while in small programs, the two are separated and run in different threads.
  • When developing a web page, web developers only need to use a browser and match it with some auxiliary tools or editors. The development of applets is different, and can only be completed through the process of applying for a applet account, installing applet developer tools, configuring items, etc.
  • Execution environment for small programs

clipboard.png

Small program architecture

I. Technical Selection

In general, there are three techniques for rendering interfaces:

  • Rendering with pure client-side native technology
  • Rendering with Pure Web Technology
  • Rendering is based on Hybrid technology, which combines client-side native technology and Web technology.

Through the analysis of the following aspects, which technical scheme does the applet adopt

  • Development threshold: Web threshold is low, and Native also has framework support like RN
  • Experience: the Native experience is much better than the Web, and Hybrid is closer to the native experience to some extent than the Web.
  • Version update: the Web supports online update, while Native needs to package to wechat for review and release.
  • Control and security: the Web can jump or change the content of the page, and there are some uncontrollable factors and security risks.

Since the host environment of the applet is WeChat, if the applet is written using pure client-side native technology, then the applet code needs to be distributed with WeChat code every time, which is definitely not possible.

Therefore, it is necessary to have a resource package that can be updated at any time on the cloud like web technology. after downloading to the local, the interface can be rendered after dynamic execution. If you use pure web technology to render applets, you may face some performance problems in some complex interactions. This is because in web technology, UI rendering and JavaScript script execution are executed in a single thread, which easily leads to some logical tasks seizing the resources of UI rendering.

Therefore, Hybrid technology combining the two is finally adopted to render applets, which can be developed in a way similar to the web and can update codes online. at the same time, the introduction of components also has the following benefits:

  • The ability to expand the Web. For example, input (input, textarea) has the ability to better control the keyboard.
  • The experience is better, and the rendering work of WebView is lightened at the same time.
  • Bypass setData, data communication and re-rendering processes to achieve better rendering performance
  • Using client-side native rendering with built-in complex components can provide better performance.

Second, the two-thread model

The rendering layer and logic layer of the applet are managed by two threads respectively: the interface of the view layer uses WebView to render, and the logic layer uses JsCore thread to run JS scripts.

图片描述

图片描述

So why do you want to design it like this? Control and security are also mentioned earlier. In order to solve these problems, we need to prevent developers from using some open interfaces, such as the window object of the browser, jumping pages, operating DOM, and dynamically executing scripts.

We can use the JavaScript engine of the client system, the JavaScriptCore framework under iOS, and the JsCore environment provided by Tencent x5 kernel under Android.

This sandbox environment only provides a pure JavaScript interpretation execution environment without any browser-related interfaces.

This is the origin of the small program double thread model:

  • Logic layer: create a separate thread to execute JavaScript, where all the codes executed are related to the business logic of small programs, responsible for logic processing, data request, interface call, etc.
  • View layer: all tasks related to interface rendering are executed in WebView thread, and which interfaces are rendered are controlled by logic layer code. A applet has multiple interfaces, so there are multiple WebView threads in the view layer
  • JSBridge serves as a bridge between upper-level development and Native (system layer), so that small programs can use native functions through API, and some components are implemented as native components, thus having good experience.

Three, double thread communication

Put the developer’s JS logic code into a separate thread to run, but in Webview thread, the developer cannot directly operate DOM.

How can we change the interface dynamically?

As shown in the above figure, communication between the logical layer and the attempt layer will be relayed by Native (WeChat client), and network requests sent by the logical layer will also be forwarded by Native.

This means that we can update DOM through simple data communication.

Virtual DOM believes that everyone already knows about this process:Simulate DOM tree with JS object-> compare differences between two virtual DOM trees-> apply differences to real DOM trees.

As shown in the figure:

clipboard.png

1. Convert WXML into corresponding JS object in rendering layer.

2. When data changes occur in the logical layer, the data is transferred from the logical layer to Native and then forwarded to the rendering layer through setData method provided by the host environment.

3. After comparing the differences before and after, apply the differences to the original DOM tree and update the interface.

We transform WXML into data and forward it through Native to realize the interaction and communication between logic layer and rendering layer.

Such a complete framework cannot be separated from the basic library of small programs.

Four, the basic library of small programs

The basic library of applets can be injected into the view layer and logic layer for operation, mainly used in the following aspects:

  • At the view level, various components are provided to form elements of the interface
  • At logic level, various API are provided to handle various logic
  • Handle a series of framework logic such as data binding, component system, event system, communication system, etc.

Since the rendering layer and logic layer of the applet are managed by two threads, the two threads are injected into the base library respectively.

The basic library of small programs will not be packaged in the code package of a small program. It will be built into WeChat client in advance.

This will:

  • Reduce the code package size of business applets
  • Bugs in the base library can be fixed separately without modifying the code package of the business applet.

V. Exparser framework

Exparser is the component organization framework of WeChat applets, which is built into the applet basic library and provides basic support for various components of applets. All components in the applet, including built-in components and custom components, are organized and managed by Exparser.

The main features of Exparser include the following:

  1. Based on Shadow
    DOM Model: The model is highly similar to ShadowDOM of WebComponents, but it does not rely on the native support of browsers and other dependent libraries. During the implementation, other APIs are added specifically to support the programming of small program components.
  2. Can be run in a pure JS environment: this means that the logical layer also has certain component tree organization capabilities.
  3. High efficiency and light weight: good performance, especially when there are many instances of components, and small code size.

In the applet, all operations related to the node tree depend on Exparser, including the construction of WXML to the final node tree of the page, createSelectorQuery call and custom component characteristics, etc.

Built-in components

Based on the Exparser framework, the applet has a set of built-in components, providing dozens of components such as view container class, form class, navigation class, media class, open class, etc. With such a rich set of components and WXSS, an interface with any effect can be built. At the functional level, it also meets most of the requirements.

VI. Operational Mechanism

There are two situations when a applet starts, one is “cold start” and the other is “hot start”.If the user has already opened a small program and then opens the small program again within a certain period of time, there is no need to restart at this time, only the small program in the background state needs to be switched to the foreground, and this process is hot start; Cold start refers to the situation that the user opens the applet for the first time or the applet is opened again after being actively destroyed by WeChat. At this time, the applet needs to be reloaded and started.

  • There is no concept of restarting small programs.
  • When the applet enters the background, the client will maintain its running state for a period of time, and after a certain period of time (currently 5 minutes), it will be destroyed voluntarily by WeChat.
  • When receiving more than two system memory alarms in a short period of time (5s), small programs will be destroyed.

clipboard.png

VII. Renewal Mechanism

If a new version is found during a small program’s cold start, it will download the new version of the code package asynchronously and start with the package local to the client at the same time, that is, the new version of the small program will not be applied until the next cold start. If you need to apply the latest version immediately, you can usewx.getUpdateManagerAPI for processing.

VIII. Performance Optimization

The main optimization strategies can be summarized into three points:

  • Simplify the code and reduce the complexity of WXML structure and JS code;
  • Reasonable use of setData calls to reduce setData times and data volume;
  • Use subcontracting optimization when necessary.

1. setData Working Principle

The view layer of applets currently uses WebView as the rendering carrier, while the logic layer uses independent JavascriptCore as the running environment. In terms of architecture, WebView and JavascriptCore are independent modules and do not have direct data sharing channels. At present, the data transmission between the view layer and the logic layer is actually realized by evaluateJavascript provided on both sides. That is, the data transmitted by the user needs to be converted into a character string for transmission, and the converted data content is spliced into a JS script, which is then transmitted to the independent environments on both sides by executing the JS script.

However, the execution of evaluateJavascript will be affected by many aspects, and the data arriving at the view layer is not real-time.

2. Common setData Operation Errors

  1. Frequent setData Removal In some cases that we have analyzed, some small programs will remove setData very frequently (millisecond level), which leads to two consequences: users will feel Caton when sliding under Android, and the operation feedback delay is serious, because JS thread has been compiling and executing rendering, failing to timely transfer user operation events to logic layer, and logic layer also failing to timely transfer operation processing results to view layer; There is a delay in rendering. As the JS thread of WebView is always busy, the communication time between logical layer and page layer is increasing. Hundreds of milliseconds have passed since the data message received by view layer is sent out, and the rendering result is not real-time.
  2. Every time setData passes a large amount of new data, it can be seen from the bottom implementation of setData that our data transmission is actually an evaluateJavascript.
  3. In the script process, when the amount of data is too large, the compilation and execution time of the script will be increased, occupying WebView JS thread, and the background page will be used.
    SetData When the page enters the background state (the user is not visible), setData should not be continued. Rendering the background state page is not felt by the user. In addition, the background state page going to setData will also preempt the execution of the foreground page.

Summary

This paper analyzes the underlying architecture of small programs from the above several angles. From the origin of small programs to the appearance of double threads, design, communication, to the basic library, Exparser framework, to the operation mechanism, performance optimization, and so on, these are all interrelated and interactive choices. As for the design of the underlying framework for small programs, there are still many things involved, such as custom components, native components, performance optimization and so on, which are not completely finished. We need to look at the source code more and think more. The birth of every framework has its meaning. What we as developers can do is not only use this tool, but also understand its design pattern. Only in this way can we not be controlled by tools and go further!