Small program since its release, for developers and users to provide a lightweight App. As an app that doesn’t need to be downloaded and installed, it realizes the dream of apps being “at your fingertips”. Users can open an app by scanning or searching it. Applets also embody the concept of “use and go”, so users don’t have to worry about installing too many apps. Wechat client provides framework support for the running of small programs, such as service running environment, page caching mechanism and control biochemistry support, etc. This paper will introduce the implementation principles of these parts one by one.
1. Content summary
Wechat applet uses the traditional mobile TERMINAL H5 browser as the page running environment, but different from the traditional B/S structure of WEB applications, applet provides users with control experience similar to the original App that cannot be achieved by ordinary H5 pages, and also provides developers with rich apis. This paper will start with the running environment and framework of the small program, and introduce in detail the framework support of iOS wechat client for the small program control layer: how the user’s development code interacts with the user interface, the functional classification and design of API, and also briefly introduce the page caching mechanism of the small program.
In addition, for some H5 can not be realized, or the implementation of poor performance of the control, wechat small program adopts the “control original biochemistry” way, the client implementation of the native control to provide developers with use, this paper will be on the design and experience optimization of the native control to do a detailed introduction.
2. Brief introduction of running environment and framework of small program
In order to discuss the operation mechanism of applets, we will start with a simple applets button, a brief understanding of the event processing flow of applets.
When developing applications on different operating system platforms, development tools usually use XML language to describe the interface layout of applications. For example, Storyboard files are used for iOS and Layout files are used for Android. In the applet, WXML files are customized to describe the interface layout. Here is an example of a simple interface file that shows a normal button with the click event bound:
Figure 1. A small program interface layout with only one button
A small program interface can optionally provide a WXSS file as a style description in addition to the required WXML to describe the interface layout. In addition, we also need to write the corresponding JS file of this page, the developer’s development code logic is completed in this JS file, in this JS process user events, control the corresponding interface changes and so on. Here is an example of a JS file that processes the interface logic in Figure 1. The script responds to the button click event and outputs a log message:
The response processing button event in the figure 2.js script
Wechat client provides a running environment for small programs through WKWebView and JavaScriptCore. WKWebView is responsible for parsing and rendering WXML and WXSS; JavaScriptCore provides a runtime environment for the logic code (JavasScript) written by developers. This runtime environment is called Service. The code in Service is completely isolated from the code in WebView, as shown in Figure 3.
Figure 3. Applets running environment framework
In the figure above, the green part represents the support framework provided by the client and the white part represents the front-end logic. As shown in the figure, a small program corresponds to a Service. The client provides a running environment for the developer’s Service code through JavaScriptCore. A small program may have one or more pages as the interactive interface to display the content to the user, the client provided by WKWebView Page parsing and rendering support; The communication between pages is mediated by the Service environment.
After the user clicks Button control in the page, the flow sequence of message data in the wechat client is shown in Figure 4:
Figure 4. Timing diagram of applet button click events
After monitoring the user’s button clicking behavior, the current Web JS sends the click event to the WKWebView of the current page of the wechat client through the PostMessage mechanism provided by WebKit. WKWebView then delivers the click event to the client Native Service environment of the current applet. Through Native JSCore(JavaScriptCore), the callback is executed to the onClick listening function in the front-end Service Js code.
Using a button as an example, the following is implemented in pseudocode to understand the above process:
A, developers in interface WXML for button binding listener function:
JSSDK sends the onClick event to the service
C. The binding function is listened to and executed in a service
The WeixinJSBridge object used in the above process is responsible for sending and listening for event messages, the Publish function is responsible for sending messages to the client, and subsribe is responsible for receiving the messages published by the client. More on this in the next section
3. Implementation of data transmission framework **** and WeixinJSBridge
In the normal H5 page development mode, each WebView page is a relatively independent operating environment. If there is a demand for data interaction between pages, the communication mode that can be selected is relatively single, such as using cookie, localstorage, or even through query parameters for data transmission. As mentioned above: a small program is composed of multiple WebViews, and the conventional development structure of H5 is far from meeting the data transmission requirements of small program App development, and does not conform to the habits of App development.
In view of the above reasons, the wechat client provides an independent running environment for each small program (the small program is internally called Service), which maintains a consistent life cycle with the small program and provides logical support for all webViews in the running of the small program:
A. Ability to handle user interaction events on WebView controls
B. Provide relatively isolated logical development environment for developers
C. Provide data communication between WebViews
D. Monitor the life cycle of applets and each page (WebView), and inform developers in the form of App events
The last section introduces the realization of A capability through the processing of button click events. For capability B, the iOS client uses the JavaScriptCore library as the running environment of small program user code, which ensures the isolation of the running environment. JavaScriptCore also provides core functions for small programs to run normally C: That is, the data communication capability between front-end JavaScript script and client is supported. This capability is mainly realized by WeixinJSBridge object. The design of WeixinJSBridge is described in detail below.
In order to meet the communication requirements of small programs, WeixinJSBridge should support the following basic communication interfaces:
L Call functions in wechat client (Objective C) via JavaScript;
L wechat client (Objective C) performs functions of JavaScript scripts.
For the convenience of front-end development, WeixinJSBridge provides the same set of code, and supports Webview and Service.
WeixinJSBridge.publish
On the Webview side, the postMessage provided by WebKit is used to transmit web page data to the Objective C listener function, and the client side is directly transmitted to the small program Service. The service-side call executes a block in Objective C to transfer the data to the client, which then passes the data transparently to the current Webview.
WeixinJSBridge.subscribe
Registers listener functions to listen for function calls from client Objective C code. The WebView side listens for publish calls in the Service. The Service listens for publish calls in the Webview.
WeixinJSBridge.invoke
The transfer logic is the same as the Publish function, except that this function is used to provide calls to JSAPI, which will be executed by the wechat client after the function is called to Objective C.
WeixinJSBridge.on
Listen for system events actively thrown out by the client, such as applet start events, page switching events, and applet switch background events.
Client by providing WeixinJSBridge object, developers can publish and subscribe in Service through JS code and small program WebView communication; Invoke the native capabilities of wechat client through Invoke; And monitor the notification events transmitted by wechat through the ON interface.
4. Page preloading and caching mechanism
In the small program, in order to improve the running speed of the page and achieve the quasi-native experience, the page preloading mechanism is provided. After the developer submits the code, the development tool compiles the code package in the background. Page-frame.html is pre-generated (with some JavaScript code describing the structure of the page and CSS code for the common style of all pages) :
A. After creating the homepage WebView, load page-frame. HTML through the loadHTMLString interface provided by WKWebView, and insert the page-specific logic into the current page through evaluateJavaScript;
C. After the home page is loaded successfully, the applet will preload a new WebView in the background and load page-frame.html through loadHTMLString.
D. When a page needs to be redirected, the preloaded page in the cache is taken and the logic specific to the page is executed in evaluateJavaScript. At the same time, the cached preloaded page needs to be replenished to prepare for the next jump.
This preloading mechanism greatly reduces the execution time of page jump of small program and improves the user’s click experience.
5. Design and implementation process of the two types of API
Applets have two types of apis: “component apis” and “development apis.” Component apis are not directly exposed to developers; development apis are functional apis that are directly provided to developers to call. The only API that developers see during development is the development API; For component apis, the front-end SDK encapsulates them as components for developers to use, so when a component is used in a developer’s page and the component uses some native functionality of the client, the component API is called during initialization or execution.
Figure 5 shows the dependency modules that the two types of API calls go through from the front-end call to the Objective C code of wechat client. WeixinJSBridge has been introduced in detail in the previous section. Service SDK and Webview SDK are further functional encapsulation of WeixinJSBridge by the front end respectively.
Figure 5. Module dependencies related to applets components
6. The creation and interaction mechanism of native controls
The applets internally provide some native controls that are not H5 implementations. Native control can provide some functions that H5 control cannot achieve, and the user experience of native control will be more smooth. In addition, the use of native control reduces the communication process between Objective C code and WebView, reducing the communication overhead.
Taking canvas as an example, the front-end provides the WX-Canvas control to the developer. When the developer sets a canvas tag < /canvas> in the page and calls the drawing interface, the front-end SDK will have the following CALL flow of JSAPI:
Figure 6. Canvas control primitive creation logic
As shown in the figure above, when the WX-Canvas control is initialized, it will be called by the Webview SDK wrapper to execute the “component API” provided by the client: InsertCanvas interface and updateCanvas interface (optional). During drawing, the drawCanvas interface of the client is called to pass the drawing command to the client, and the client parses the parameters of drawCanvas interface to obtain the drawing command set. Quarz2D is used to draw graphs.
InsertCanvas tells the client to insert a canvas control on the current WebView. The client determines the position and size of the control to be inserted according to the position and width parameters passed in.
When the developer changes the position size of the WX-Canvas control, the client is notified through the updateCanvas interface, and the client makes corresponding changes to the frame position size property of the native control.
When the page leaves, a call to the removeCanvas interface removes the canvas control from the WebView.
In addition to canvas, the Video component encapsulates AVPlayer, uses the system component function to provide the function of side-down playback, and customizes the original full-screen user interface. The package of Map component to QQ Map component will introduce the rich function of QQ Map into the small program, so that developers have a broader development imagination space; Input control respectively introduced the iOS native UITexField and UITextView, provides the HTML input box can not meet the customization of the keyboard and other functions.
In order to provide more flexible and controllable control functions, the small program has also done the original biochemistry of Toast, Alert, Picker, ActionSheet and other controls in H5. These components are provided to developers in the form of “development apis”.
- Native controls are inserted into the web DOM**** node
Control probiotics bring a smoother probiotics experience and richer control functionality, but they also introduce new challenges. As mentioned earlier, the native control is inserted into the WebView control (in practice, under WKScrollView under WKWebView). As shown in Figure 7, the web elements are always drawn on the WKContentView control — the WKContentView is responsible for drawing all HTML elements in the web page. When inserted, the video control overwrites all HTML elements in the web page:
Figure 7. Native controls inserted into WKWebView overwrite HTML nodes in the control tree
As shown above, inserting native controls must always cover the page (the lower the node in the node tree, the higher the display level), which results in:
A. If developers wish to overwrite some custom HTML elements on native controls, they will not be supported.
B. All H5 pop-up elements are blocked by native controls, such as the Alert dialog. This problem can be solved by primitive H5 pop-up components, such as Toast, Alert, Picker and ActionSheet mentioned in the previous section;
C. If a developer inserts a native control into a div scrollbar as a child of the div, it is expected that the native control should move with the parent div scrollbar, and the content outside the div area should be cut off. However, since the native control is directly inserted into the WebView, there is no association between the control and the div. Therefore, it will not follow the movement and will not be trimmed, and the performance will be inconsistent with the developer’s expectations, affecting the user experience.
In order to solve this problem, the client tries to analyze the principle of WKWebView parsing HTML elements. WKWebView will generate corresponding iOS native controls under THE WKWebView control according to the PAGE DOM element when parsing HTML elements. Through analysis, In normal cases, the generated native controls have no corresponding relationship with HTML nodes, but in some special cases, some special DOM elements will generate native controls in the corresponding position of the WebView, and the size is exactly the same, such as the DIV tag containing the overflow attribute, as shown in the following figure:
Figure 6. WKWebView parses HTML to generate a sample native control on the client side
As shown in the figure above, WKWebView will generate a corresponding UIScrollView control for this tag position as it parses HTML. Using this property, we can pre-generate a DIV node containing overflow tags at the location where the developer expects the native control to be inserted, and then, when inserting the native control, insert it into the UIScrollView corresponding to the tag, so that “native controls do not block HTML elements.” For example, after inserting a video player into a DOM node, the node tree looks like this:
Figure 9. Node tree after inserting the video control into the WEB DOM node
The client adopts the scheme of “inserting native control into webpage DOM node”, the specific implementation principle is as follows:
A. The WEB side inserts a DIV tag with overflow property in the reserved position where native controls need to be inserted in advance, and informs the client side of the position and size of the scrollbar through the “component API” insertContainer;
B. According to the position and size of insertContainer, the client iterates under WKWebView to find the UIScrollView corresponding to the DIV tag (the size and location are consistent), saves its object pointer, and allocates an ID to return to the WEB end;
C, when the WEB side inserts the native control, through the interface to pass the ID to inform the client: the native control belongs to which div scroll bar, the client finds the corresponding native UIScrollView, and inserts the control into the UIScrollView;
D. When the DOM element of the page changes, you need to use updateContainer to tell the client to resize the specified native control. The client adjusts the size of the native control according to the parameter (the position does not need to be resized because it is always at the origin position relative to the parent control).
Native control event handling after DOM node insertion. Since WKWebView takes over all user action events, native controls cannot respond to user events after being inserted as described above. Therefore, special handling of events is required: by overloading the hitTest method of WKWebView, events on the web page are processed first in the processing logic of this method, and if the web page is not processed, it is passed to the native control.
8. To summarize
Wechat client provides a whole set of running environment for small programs, including runtime support of JS scripts, task management of small programs, communication bridge mechanism between JS scripts in Service and WebView, as well as biochemization of complex controls. Thus provides a good small program experience for developers and users.
Welcome to exchange technical development with me