Home >headlines >Summary of five years of small program development experience for e-commerce front-end teams [full of useful information]

Summary of five years of small program development experience for e-commerce front-end teams [full of useful information]

青灯夜游
青灯夜游forward
2022-08-18 11:27:454879browse

Any application that can be written in JavaScript will eventually be written in JavaScript. Likewise, any product that can be implemented using mini programs will eventually be implemented using mini programs. So how to develop a small program? The following article summarizes and shares five years of small program development experience for e-commerce front-end teams (Wanzi principle and optimization tips). I hope it will be helpful to everyone!

Summary of five years of small program development experience for e-commerce front-end teams [full of useful information]

1. Discuss the dual-thread architecture

Questions about the underlying design of WeChat mini programs

  • What exactly is the dual-thread model?
  • How to separate the view and logic?
  • Why use strange syntax like WXML and WXSS?
  • How to block dangerous operation API?
  • How to communicate and how to implement data-driven view updates?
  • What are the disadvantages of the dual-threaded model?

1. Model composition

1) Problems with traditional browser processes and threading models

Summary of five years of small program development experience for e-commerce front-end teams [full of useful information]

Performance issues

The rendering thread and the JS engine thread are mutually exclusive, and there is a blocking problem. Long-term JS script execution will directly affect Rendering to the UI view causes page lag

Security issues

Dangerous HTML tags (a, script) and JS API (Function, eval, DOM API) , it is easy for attackers to tamper with page content, illegally obtain user information, etc.

Solution

The applet uses a dual-thread model to combine view display and logic The processing is executed separately in two threads. The HTML tags are encapsulated in the model. Developers cannot directly call native tags. The original dangerous logic operation API capabilities in JS are also blocked, and the communication actions involved are only Can trigger virtual DOM updates (data-driven view) through the API provided by the middle layer

2), mini program dual-thread model

Summary of five years of small program development experience for e-commerce front-end teams [full of useful information]The capabilities of the view layer and the logic layer are provided through the JS file of the mini program basic library built into the WeChat client

WAWebview.js

Provides the basic API capabilities of the view layer. Including a complete set of component systems and related implementations of Virtual Dom (virtual DOM)

WAService.js

Provides API capabilities based on the logic layer and exposes APIs for various operations to developers

3), client engine underlying implementation

Under different running environments, the script execution environment and the environment for component rendering are different, and the performance is also different:

    On iOS, iPadOS and Mac OS, the JavaScript code of the applet logic layer runs in
  • JavaScriptCore

    , the view layer is rendered by WKWebView, and the environment is iOS 14 , iPad OS 14, Mac OS 11.4, etc.

  • On Android, the JavaScript code of the applet logic layer runs in
  • V8

    , and the view layer is based on Mobile Chromium The core is rendered by the WeChat self-developed XWeb engine (from the past X5 to the self-developed XWeb engine), the view layer is rendered based on the Mobile Chrome kernel, and according to official disclosures, in the future the logic layer will also be separated from V8 and use customized Customized XWeb Worker thread, that is, customizing a Web Worker thread as the logical layer of the applet. Reference link)

  • On Windows, the applet logic layer JavaScript and view layer use the Chromium kernel
  • On the development tool, the JavaScript code of the applet logic layer runs in
  • NW.js

    , and the view layer is rendered by Chromium WebView

2. View layer

1), mini program component system

There are three types of components involved in the mini program: built-in components, custom components Components, native components

Summary of five years of small program development experience for e-commerce front-end teams [full of useful information]

2), mini program component organization framework

1, Web Component

Web Component

is the ability to create encapsulated functions and customized elements in the browser. It consists of three main technologies

#The template and slot elements allow you to write markup templates that are not displayed in the rendered page. They can then be reused multiple times as the basis for custom element structures

2. Exparser framework

Exparser is the component organization framework for WeChat mini programs, built into the mini program base library, and provides Provides basic support for various components of the program All components in the mini program, including built-in components and custom components, are organized and managed by Exparser

In the mini program, all node tree-related operations depend on Exparser, including the construction of WXML to the final node tree of the page , createSelectorQuery calls and custom component features, etc.

Exparser will maintain information related to the node tree of the entire page, including node attributes, event binding, etc., which is equivalent to a simplified version of Shadow DOM implementation

Summary of five years of small program development experience for e-commerce front-end teams [full of useful information]

3. Exparser features
  • Based on the Shadow DOM model: The model is highly similar to the Shadow DOM of Web Component, but does not rely on the native support of the browser , and there are no other dependent libraries; during implementation, other APIs are also added to support small program component programming

  • can run in a pure JS environment: this means that the logic layer also Have certain component tree organization capabilities (will be used in component rendering)

  • Efficient and lightweight: good performance, especially excellent in environments with a large number of component instances. At the same time, the code size is also smaller

4. Exparser core method

registerBehavior Registers some basic behaviors of the component for the component to inherit

registerElement Register components, the interfaces that interact with us are mainly properties and events

Component creation

The basic library of the mini program provides Page and There are two constructors of Component. When the applet is started, the defined fields such as properties, data, methods, etc. are written into Exparser's component registry. When initializing the page, Exparser will create an instance of the page root component, and other components used will also Create component instances accordingly (this is a recursive process)

5. The creation process of Page and Component

Summary of five years of small program development experience for e-commerce front-end teams [full of useful information]

We can clearly see from the above figure It can be seen that there are differences in the communication methods between page rendering and component rendering of mini programs. Among them, the generation and diff of VDOM in Page rendering are completed in the view layer, and the logic layer is only responsible for sending data data to trigger the update logic of the rendering layer. In the rendering of Component, the logic layer and the view layer need to jointly maintain a set of VDOM. The method is to build the component's VDOM in the logic layer when the component is initialized, and then synchronize it to the view layer. Subsequent update operations will first perform a diff of the old and new VDOMs in the logic layer, and then only communicate the results after the diff, and pass them to the view layer for direct VDOM updating and rendering. The biggest advantage of doing this is to control the granularity of view update communication to the DOM level. Only the DOM that eventually changes will be updated (because sometimes changes in data do not necessarily bring about updates to the view). Compared with the previous data Level updates will be more accurate, avoiding unnecessary communication costs and providing better performance.

3), Mini Program native components

1. Advantages of native components
  • Expand the ability of the Web . For example, input box components (input, textarea) have the ability to better control the keyboard.

  • Better experience, while also reducing the rendering work of WebView. For example, the rendering work of more complex components such as map components does not occupy the WebView thread, but is handed over to the more efficient client for native processing.

  • Better rendering performance, bypassing setData, data communication and re-rendering processes, for example, canvas components (canvas) can directly use a rich set of drawing interfaces To draw.

2. Native component creation process
  • After the component is created, it is inserted into the DOM tree, renders a placeholder element, and the browser kernel will Calculate the layout immediately. At this time, we can read the position (x, y coordinates), width and height of the component relative to the page

  • The component notifies the client that the client inserts a native area at the same position according to the width and height, and then the client renders the interface in this area

  • When the position or width and height change, the component will notify the client to make corresponding adjustments

3. Native component rendering restrictions
  • Some CSS styles cannot be applied to native components

  • Hierarchy issues (native components are the highest level and will cover components in the WebView layer)

Solution

  • Use cover-view and cover-image components to cover the native components (limited capabilities, inflexible)

  • Same layer Rendering (rendering native components directly to the same level of WebView through certain technical means)

4), rendering native components on the same layer

1. iOS system implementation principle

The same-layer rendering on the iOS side of the applet is implemented based on WKChildScrollView. After the native component is attached, it will be directly mounted to the pre-created WKChildScrollView container

Principle Analysis

WKWebView uses a layered approach for rendering internally. WKWebView will render the Compositing Layer (composition layer) generated by the WebKit kernel into a WKCompositingView component on iOS, but the composition layer There is no one-to-one mapping relationship with DOM nodes (the kernel generally merges multiple DOM nodes into one composition layer).

WKChildScrollView: When the CSS property of a DOM node is set to overflow: scroll (lower versions need to set -webkit-overflow-scrolling: touch at the same time), WKWebView will generate a WKChildScrollView (In order to make WebView scrolling on iOS have a smoother experience, the scrolling in WebView is actually carried by a real native scrolling component, and the WebKit kernel has already processed the hierarchical relationship between it and other DOM nodes), And there is a one-to-one mapping relationship between WKChildScrollView and DOM nodes.

Summary of five years of small program development experience for e-commerce front-end teams [full of useful information]

Creation process

  • Create a DOM node and set its CSS property to overflow: scroll and- webkit-overflow-scrolling: touch

  • Notify the client to find the native WKChildScrollView component corresponding to the DOM node

  • Mount the native component to The WKChildScrollView node serves as its child View

  • Through the above process, the native component of the applet is inserted into the WKChildScrollView

2. Android System implementation principle

WebPlugin is a plug-in mechanism in the browser kernel. The same-layer rendering on the Android side of the mini program is based on the

principle implemented by the

embed tag and WebPlugin. Analysis

embed tag is a new tag in HTML5, which is used to define embedded content (such as plug-ins, media, etc.). The format can be PDF, Midi, Wav, MP3, etc., such as Chrome browsing The PDF preview on the browser is implemented based on the embed tag.

Based on the embed tag combined with the Chromium kernel extension. Chromium supports the WebPlugin mechanism. WebPlugin is a plug-in mechanism of the browser kernel. It is mainly used to parse and describe the embed tag and render native components to the Texture texture provided by the kernel. Create an embed DOM node on the WebView side and specify the component type

Summary of five years of small program development experience for e-commerce front-end teams [full of useful information]

The Chromium kernel will create a WebPlugin instance and generate a RenderLayer

The Android client initializes a corresponding native component
  • The Android client draws the picture of the native component to the SurfaceTexture bound to the RenderLayer created in step 2
  • Notifies the Chromium kernel to render the RenderLayer
  • Chromium renders the embed node and displays it on the screen
  • 5), view layer code compilation
  • WeChat developer tools are built-in Binary WXML and WXSS code file compiler. The compiler accepts WXML and WXSS code file lists. After processing, it outputs JavaScript code
  • 1 and WXSS code file

  • wcsc command tool execution. Process

wcsc Compile WXSS to generate a JS file Product

The JS file contains a conversion method to add size unit rpx, which can be used according to the device screen The width is adaptively calculated into px units

Provide the setCssToHead method to add the converted css content to the head of the html template
  • eval method execution This JS file string completes style injection

Summary of five years of small program development experience for e-commerce front-end teams [full of useful information]

2. WXML code file

WCC command tool execution process

  • wcc compiles WXML to generate a JS file product

  • The JS file contains the $gwx method, receives the WXML file path, generates the generateFunc method after execution, and triggers the generateFuncReady event

  • generateFunc method accepts dynamic data data, similar to a render function, used to generate virtual dom

Summary of five years of small program development experience for e-commerce front-end teams [full of useful information]

3. Logical layer

1), the logical layer contains content

  • Provides JS code execution environment

  • is the window object Add module interface require define

  • Provide Page, App, getApp and other interfaces

  • Provide api methods under the wx global object, network, media, Files, data caches, locations, devices, interfaces, interface node information and some special open interfaces

2), JS code execution environment

JSCore Composition (iOS, Android)

1. JSVirtualMachine

It instantiates a VM environment To execute JS code, if you have multiple JS that need to be executed, you need to instantiate multiple VMs. And it should be noted that these VMs cannot interact with each other, because GC problems are prone to occur

2. JSContext

JSContext is the context object for JS code execution. Equivalent to a window object in Webview. In the same VM, you can pass different Context

3, JSValue

Similar to WASM, JsValue is mainly used to solve JS data types and Swift or Java data Mapping between types. That is to say, any content mounted in JSContext is of type JSValue. Swift and Java automatically implement type conversion between JS and JS internally

4, JSExport

is a protocol in JSCore used to expose the Native interface. To put it simply, it will directly convert the relevant properties and methods of Native into the methods and properties on the prototype object

3. Implementation of module specifications

  • Passed define defines a module and limits the other modules that the module can use, such as window, document, etc. The define method is implemented by storing all JS code logic in global variables in the form of "path-module" key-value pairs. The

Summary of five years of small program development experience for e-commerce front-end teams [full of useful information]

1Summary of five years of small program development experience for e-commerce front-end teams [full of useful information]

  • ##Use require to apply a module. When using the module, only the After entering require, module, and exports, all other variables read in the code will be undefined. This is also the reason why some browser environment objects cannot be obtained in the mini program

1Summary of five years of small program development experience for e-commerce front-end teams [full of useful information]

This is actually a typical module loading idea, which is very similar to the way Webpack packages modules.

4. Communication principle

In WAWebview.js and WAService.js files In addition to providing the basic API capabilities of the view layer and logic layer, it also provides the ability to communicate between the two threads

The communication between the applet logic layer and the rendering layer will be done by Native (WeChat client) For transfer, the logical layer sends network requests and also forwards them through Native

1), and the underlying implementation

The different implementations of several ends will eventually be encapsulated into a compatibility layer like WeiXinJSBridge for developers to call

1. iOS side

The view layer is implemented through window.webkit.messageHandlers.NAME.postMessage and eval of WKWebView. The logic layer injects a global native method into the JavaScriptCore framework

2. Android side

The implementation principles of the view layer and the logic layer are the same, and they are both directed to the window of WebView The object is injected into a native method WeixinJSCore implementation. This WeixinJSCore is the interface provided by WeChat for JS calls (native implementation)

3. WeChat developer tools

Use websocket for communication

2) WeixinJSBridge module object

WeixinJSBridge provides a message communication mechanism between the view layer JS and Native, the view layer and the logic layer, and provides the following methods:

  • invoke:JS calls Native API

  • on:JS listens to Native messages

  • publish:View layer publishes messages

  • subscribe: Subscribe to messages from the logic layer

##5. Defects and optimizations of dual-thread architecture

1) Defects of dual-threaded architecture

  • Inability to flexibly operate DOM and achieve more complex effects

  • Parts and native components Related views have usage restrictions. For example, WeChat’s scrollView cannot have textarea

  • The page size and the number of open pages are limited

  • Need to be separated Development adaptation, existing code resources cannot be reused

  • When the JS volume in JSCore is relatively large, its initialization time will be affected

  • When transmitting data, the time consumption of serialization and deserialization needs to be considered

2), optimization of dual-thread architecture

The performance bottleneck caused by dual-threads, This is also a key issue that WeChat itself has been committed to solving. As mentioned earlier, the applet will replace the implementation of the logic layer with a custom XWeb Worker thread by modifying the Chromium kernel in the new XWeb kernel. This will eliminate the need for additional V8 and significantly increase memory usage. reduce. In addition, since it is based on the Worker thread of the Chromium kernel, regarding data communication, it is natural to have the ability of PostMessage to replace the original setData underlying communication method to obtain higher performance communication capabilities

1Summary of five years of small program development experience for e-commerce front-end teams [full of useful information]

3), the dual-thread architecture of the Alipay applet

In addition, I also learned about and studied the underlying implementation of the Alipay applet. The Alipay applet also uses a similar dual-thread architecture model. By using the browser kernel provided by UC, the rendering layer runs in the Webview thread, and the logic layer starts a separate thread to run the Service Worker. However, the Service Worker needs to communicate with the rendering thread through the MessageChannel API. When the amount of data is large and the objects are complex, there are also performance bottlenecks.

Therefore, the Alipay applet redesigned the existing JS virtual machine V8 and proposed an optimized isolation model (Optimized isolation model, OIM). The main idea of ​​OIM is to share data and infrastructure in JS virtual machine instances that have nothing to do with the thread execution environment, as well as immutable or immutable JS objects, so that while maintaining the logical isolation of the JS layer, memory can be saved in multi-instance scenarios. and power consumption overhead. Although some data shared between instances will bring synchronization overhead, under the isolation model, the data, objects, code and virtual machine infrastructure shared by this solution are immutable or non-volatile, so competition rarely occurs.

Under the new isolation model, the V8 instance in the Webview is a Local Runtime, and the V8 instance in the Worker thread is also a Local Runtime. When the logic layer and the rendering layer interact, the setData object will be created directly in In the Shared Heap, the Local Runtime of the rendering layer can directly read the object and use it for rendering of the rendering layer, which reduces the serialization and network transmission of the object and greatly improves startup performance and rendering performance.

In addition, the Alipay applet implements homepage offline caching optimization. It first renders the homepage UI page saved last time, displays the homepage to the user, and then continues to load the front-end framework and business code in the background. After the loading is completed, it is merged with the offline cached homepage UI to display a dynamic homepage to the user. This is very similar to the initial rendering caching scheme of the WeChat applet and is more radical. WebAssembly technology was also used to reimplement the core code of the virtual DOM and improve the page rendering of the mini program. [Recommended related video tutorials:

web front-end]

6. Thoughts on the design of dual-thread model architecture

Technical architecture is born to solve problems , a good technical solution not only requires designers to make balance and trade-offs between development efficiency, technical cost, performance experience, and system security, but also needs to be closely integrated with business trends, product forms, and user demands

2. A closer look at the runtime mechanism

1. Code package download

When the mini program starts (cold start), WeChat will The program displays a fixed startup interface, which contains the icon, name and loading prompt icon of the mini program

1Summary of five years of small program development experience for e-commerce front-end teams [full of useful information]

At this time, WeChat will complete several tasks behind the scenes:

Download the mini program code package, load the mini program code package, and initialize the mini program homepage

1Summary of five years of small program development experience for e-commerce front-end teams [full of useful information]

From a developer's perspective, controlling the size of the code package helps reduce the startup time of the mini program. For code packages less than 1MB, the download time can be controlled within 929ms (iOS) , 1500ms (Android)

Optimization plan

  • Reduce the size of main package and sub-package

  • Reasonable allocation, sub-package preloading rules

  • Fine splitting, asynchronous subcontracting

2. Page level preparation

Before starting the mini program , WeChat will prepare a page level in advance to display the homepage of the mini program. Whenever a page level is used to render a page, WeChat will start preparing a new page level in advance, so that each time wx.navigateTo is called, a new page can be displayed as soon as possible. The content of the view layer page is generated through the pageframe.html template

Summary of five years of small program development experience for e-commerce front-end teams [full of useful information]

Preparation steps for the page level

1Summary of five years of small program development experience for e-commerce front-end teams [full of useful information]

  • The first stage is to start a WebView. On iOS and Android systems, it takes a short time for the operating system to start the WebView.

  • The second stage is Initialize the basic library in WebView. At this time, some internal optimizations of the basic library will be performed to improve page rendering performance

  • The third stage is to inject the WXML structure and WXSS style of the mini program to make the mini program The program can start rendering the page immediately after receiving the initial data of the page (this stage cannot be executed before the mini program is started)

3. Page code injection and execution

1), initialize global variables

View layer global variables

  • __wxConfig: It is based on the global configuration and Configuration object generated by page configuration, including page, subcontracted page, tabbar and other information
  • __wxAppCode__: non-JS type developer code
  • JSON: JSON configuration file content
  • WXML: The execution result of the $gwx function is an executable function. After execution, the VDOM object will be returned.
  • WXSS: The result of the eval execution style function is an executable function. After execution, the style tag is inserted

Logical layer global variables

  • __wxConfig: similar to the view layer, does not include subcontracting page, tabbar and other information
  • __wxAppCode__: Similar to the view layer, it does not contain WXSS type data
  • __wxRoute: used to point to the path of the page currently being loaded
  • __wxRouteBegin: used to mark the correct registration of the Page
  • __wxAppCurrentFile__: Used to point to the JS file currently being loaded
  • __wxAppData: The data domain object of each page of the applet
  • Component: Custom component constructor
  • Behavior: Custom component behavior constructor
  • definePlugin: Custom plug-in constructor
  • global: Global object
  • WeixinWorker: Multi-threaded constructor

2), basic library and business code JS file injection

View layer code injection

  1. Inject and execute the wxml.js file (define $ gwx method)
  2. Inject and execute the wxss.js file (eval method, add app.wxss style file)
  3. Add __wxAppCode__ variable
  4. Execute eval method, insert into the current page And reference component style files
  5. Execute $gwx (current page path) and return the corresponding method to generate virtual DOM

Logic layer code injection

  1. Inject and execute JS files (order: other, babel, Component, Page, App)
  2. Inject and execute wxml.js file (define $gwx method)

On-demand injection and time-consuming injection

Normally, when the mini program is started, all JS codes in the sub-package and main package (except independent sub-packages) where the startup page is located will be Merge injection. Since the basic library version 2.11.1, on-demand injection and time-based injection are configured. The applet only injects custom components and page codes required by the current page, and customizations that will not be used in the page. Components will not be loaded and initialized

3), logic layer business code execution

1Summary of five years of small program development experience for e-commerce front-end teams [full of useful information]

4, data communication and View rendering

1), page initial rendering

Data communication

When the applet is started or a new When the page is opened, the page's initial data (data) and path and other related information will be sent from the logic layer to the view layer for the initial rendering of the view layer.

The Native layer will pass these data directly to the view layer, and at the same time present a new page level to the user, and the view layer will draw the interface on this page level.

After the view layer receives the relevant data, it selects the appropriate WXML structure according to the page path. The WXML structure is combined with the initial data to obtain the first rendering result of the page

1Summary of five years of small program development experience for e-commerce front-end teams [full of useful information]

After completing the view layer code injection and receiving the initial data sent by the logic layer, combined with the page structure and style information obtained from the initial data and the view layer, the mini program framework will render and display the mini program homepage. The first screen of the mini program and triggers the onReady event on the home page.

If Initial rendering cache is turned on, the first rendering can be completed directly using the cached data of the rendering layer, without relying on the initial data of the logic layer, reducing startup time (onReady event is executed in advance).

Summary of five years of small program development experience for e-commerce front-end teams [full of useful information]

#The page initialization time is roughly composed of two parts: the page's initial data communication time and the initial rendering time. Among them, the data communication time refers to the time from the beginning of data organization at the logical layer to the completion of complete reception by the view layer. When the data volume is less than 64KB, the total time can be controlled within 30ms.

The transmission time is generally positively correlated with the amount of data. Transmitting excessively large data will significantly increase this time. Therefore Reducing the amount of transmitted data is an effective way to reduce data transmission time.

Initial 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 a node tree. The node tree is the page tree structure seen in the WXML panel of the developer tools. It contains information such as the names, attribute values, event callback functions and other information of all component nodes in the page. Finally, according to each node contained in the node tree, each component is created sequentially on the interface. The data and current node tree obtained in the initial rendering will be retained for re-rendering.

2Summary of five years of small program development experience for e-commerce front-end teams [full of useful information]

In this entire process, the time overhead is generally proportional to the total number of nodes in the node tree. Therefore Reducing the number of nodes in WXML can effectively reduce the time overhead of initial rendering and re-rendering and improve rendering performance.

2) Update data rendering

After the initial rendering is completed, the view layer can perform interface updates after the developer calls setData.

setData Principle

1. Change the value of the corresponding this.data (synchronous operation)

Parse the attribute name (including . and [], etc. Data path symbol), return the corresponding hierarchical structure, modify the value of the corresponding local data

{abc: 1} 中 abc 属性名 => [abc]
{a.b.c: 1} 中 'a.b.c' 属性 => [a,b,c]
{"array[0].text": 1} => [array, 0, text]

2. Send data from the logic layer to the view layer (asynchronous operation)

evaluateJavascript : The data transmitted by the user needs to be converted into a string for transmission. At the same time, the converted data content is spliced ​​into a JS script, and then passed to the independent environments on both sides by executing the JS script.

2Summary of five years of small program development experience for e-commerce front-end teams [full of useful information]

When re-rendering, the logic layer merges the setData data into data, and the rendering layer applies the data and setData data to the WXML fragment to obtain a new node tree. Then compare the new node tree with the current node tree, so you can get which nodes need to be updated and which nodes need to be added or removed. Finally, the old node tree is replaced with the new node tree for the next re-rendering.

When comparing the current node tree and the new node tree, the node attributes affected by the setData data will be compared. Therefore, removing unnecessary set data and reducing the amount of data in setData will also help improve the performance of this step.

3), user event communication

The view layer will accept user events, such as click events, touch events, etc.

The communication of user events is relatively simple. When a user event is triggered and a related event listener needs to be triggered, the view layer will feed the information back to the logic layer.

Because this communication process is asynchronous, a certain delay will occur. The delay time is also positively related to the amount of data transmitted. When the data amount is less than 64KB, it will be within 30ms.

2Summary of five years of small program development experience for e-commerce front-end teams [full of useful information]

There are two main ways to reduce the delay time

  • Remove unnecessary event binding (bind and catch in WXML ), thereby reducing the amount and frequency of communication data

  • When binding events, you need to transmit the dataset of target and currentTarget, so do not place too large data in the data prefix attribute of the node

三、小程序基建和优化方案实践

1、小程序性能优化

1)、代码分包

1、合理的分包和分包预加载策略

主包内容

Tab页(系统要求)、业务必要页面(错误兜底页、登陆授权页等),其余文件都以业务模块或者页面的维度,拆分成各自的分包

分包预加载

据用户的实际使用场景,预测下一跳的页面,将可能性最高的场景设置为预加载分包(可以参照业务埋点数据),例如:进入电商首页后,需要对会场和商详页的分包进行预加载

2、组件分包分发

实现思路

小程序不支持主包引用分包代码,只能在分包中引用主包代码,所以把公共使用的组件代码放在主包目录中,但这些公共组件未必在主包所属的页面中会被引用,可能只是在分包页面中被多次引用,这样使得主包中代码体积越来越大,用户首次加载速度变慢。

将主包页面不依赖的公共组件分别分发到依赖它们的分包目录中,虽然分包各自的体积会有所增大,但主包体积会有显著下降

实现原理

将所有需要分发的组件放置主包指定目录中,并添加配置文件,说明组建文件分发信息。在开发时用 gulp 任务监听单个文件变化、在构建时递归遍历所有组件,将其复制到配置文件中指定的子包路径目录中。

目标文件在复制之前,都先要将文件内的依赖路径进行更新,使其在子包中运行时也能引用成功。针对不同类型的文件,采取不同的依赖分析手段。

  • JS 文件:使用 babel.transformFile 修改依赖引用地址

  • WXSS 文件:使用 postcss.plugin('transform-wxss') 处理依赖的 @import 导入样式文件地址

  • WXML 文件:使用 require('htmlparser2').Parser 来转换内部 wxs、template(import 和 include 导入)依赖的引用地址

异步分包

小程序基础库版本 2.17.3 及以上开始支持分包异步化,即可以在分包之间互相引用,这个能力可以快速取代我们自己的组件分发方案,而且优化效果更佳,可以将分包中公共依赖的代码部分打成新的分包,在使用时异步按需引入,能力与 Web 端的异步组件类似,但这个方案在生产环境的稳定性有待验证。

2)、setData 优化

实现思路

合并 setData 调用,将其放在下个时间片(事件循环)统一传输,降低通信频率

实现原理

需要先将逻辑层 this.data 进行更新,避免前后数据不一致造成逻辑出错。将需要传送至视图层的 data 进行整合,在 nextTick 中调用原生的 setData 统一进行传送,可以有效降低通信频率,并且在传送前手动做一次与 this.data 的 diff 操作,降低通信体积

1. 降低频率

const nextTick = wx.nextTick ? wx.nextTick : setTimeout; // 小程序里的时间片 API

2. 减少体积

参考京东 Taro 中 diff 的实现,对基本、数组、对象等不同类型进行处理,最终转换为 arr[1]、x.y 这样的属性路径语法,减少传输信息量

3)、Storage API 重封装

实现思路

onLaunch、onLoad 等生命周期函数中存在大量对微信 Storage 的同步调用(使用 Sync 结尾的API),这些操作涉及JS与原生通信,同步等待耗时过久,推迟页面 onReady 触发即用户可交互时间,影响用户体验。直接改为异步操作又存在业务代码改动量较大的问题,存在一定风险,大量的异步回调代码语义不优雅、可读性较差。因此需要对原生 Storage 操作进行重封装,改为对内存中对象的实时存取,提高响应速度,并定期调用原生 API 向真实 Storage 中同步。

实现原理

Encapsulate APIs with consistent calling methods, with getStorage and getStorageSync as the basic APIs. When called for the first time, the native API is triggered to obtain the original data. After obtaining it, it is stored in a memory object. All subsequent operations (deletion, modification, and query) are based on this object. Do the operation. The set and remove operations need to mark the corresponding data as dirty and store it in a dirty table so that the changes can be synchronized to the native end later. The caller needs to call the change synchronization method regularly to persist the data (traverse the data in the synchronized dirty table) to prevent accidental data loss when the memory is running. Generally, it needs to be executed regularly (the app's onShow executes setInterval) and executed in the app's onHide life cycle. .

We have not only re-encapsulated the Storage API, but also used other synchronization APIs that take a long time (such as the getSystemInfo/getSystemInfoSync API used to obtain device and system information, the underlying implementation is synchronous). In a similar way, the system API is called only during the first acquisition and the result is cached in memory, and subsequent calls directly return the cached information.

4), Data Prefetch

1, Publish and subscribe method

Implementation ideas

From A Before the page jumps to page B, the emit message of page A triggers the data interface request of page B and caches the result data. When page B is opened, the cache is first fetched. If it cannot be fetched, the interface is called again

2Summary of five years of small program development experience for e-commerce front-end teams [full of useful information]

Implementation Principle

Although page B has not been instantiated, the page has been registered and the outer code of Page has been executed, so the message can be completed with page A in advance Publish and subscribe

2. Global registration variable method

Implementation ideas

When the page that needs to be preloaded is not registered in the main package or asynchronously , it is impossible to perform pre-requests through the publish and subscribe mode. We can achieve this by globally registering the preloading method.

Implementation principle

Route jump on the previous page Initiate a pre-request, save this request to a global Promise variable, and when the page that needs to be pre-loaded is rendered for the first time, the data result in the global Promise variable then callback will be taken first

5) , Memory optimization

1. Image optimization

Optimize the overall image resources (Alibaba Cloud function)

  • Size : 1-2 times the actual width and height
  • Webp format : Fully used on the Android side
  • Png format : Transparent bottom only in scenes with strong demands Use, the rest use Jpg/Jpeg by default
  • Image lazy loading: Enable the lazy-load attribute of the Image component
2. Low-end machine downgrade

Implementation ideas

According to the user model hardware performance level, the front-end display sets different presentation strategies

Implementation principle

Downgrade the following functions in low-end machine scenarios

  • Downgrade gif animations to static images
  • Downgrade JS and CSS animations to static styles
  • No Display swiper component
  • Quality uses 60% quality
3. Long list optimization
  • RecycleView
  • IntersectionObserver

2. Mini program engineering

1) Plug-in framework

Framework tools

BeautyWe is a three-party small program business development framework that encapsulates the underlying public business logic of life

Application scenarios

Public business logic, such as verification of user login status on each page, obtaining and processing url parameters, automatic PV burying, performance monitoring, etc.

Implementation Principle

The life cycle function is plug-in, and the native onLoad, onShow, onReady and other functions are rewritten using Object.defineProperty to form a Promise task chain internally. By introducing plug-ins, methods can be freely inserted into the front and back positions of the task chain. The system life cycle functions are triggered when they are executed and called in sequence.

2Summary of five years of small program development experience for e-commerce front-end teams [full of useful information]

After implementing the plug-in of the life cycle hook, we can encapsulate all types of underlying public logic that need to be processed and insert it into the host (native life cycle) Promise task chain

2), automated deployment

Based on the mini program CI Gitlab CI Puppeteer, a set of semi-automatic mini program construction and deployment tools is implemented. For details, see my other article "WeChat Mini Program Automated Deployment Solution" , the WeChat Mini Program later provides miniprogram-ci that can be run independently in the Linux environment, making it simpler and easier to use.

3), hidden point monitoring

Monitoring capability

  • Business hidden point (Business focus such as page PV, module exposure, etc.)

  • Performance reporting (mini program startup, page rendering, FMP, memory alarm)

  • Exception monitoring (JS error, interface error, business error)

Performance monitoring reporting type

  • memory_warning: Memory alarm data reporting. Collection method: Collect alarm levels in wx.onMemoryWarning callback

  • app_launch: App runtime data reporting. Collection method: Record the app life cycle execution time (onLaunch, onShow), and report it when the page is onLoad

  • page_render: Page runtime data reporting. Collection method: Record the page life cycle execution time (onLoad, onShow, onReady), FMP, etc., and report it when the page is onHide or onUnload

Implementation principle

Based on the plug-in framework, rewrite the life cycle hook function to automatically record and report performance data during the execution of the page program

3. Performance optimization implementation and daily Iteration specification

We use FMP as a key indicator to measure the second opening rate. For details, please refer to my other articleUser experience-centered front-end performance optimization. In addition, in daily development, we have also precipitated some specifications that can improve the basic guarantee of performance and stability in daily business iterations. For details, see WeChat Mini Program Development Military Regulations.

4. Summary thinking and development prospects

Continuous improvement of infrastructure capabilities

The official documents have continued to improve the underlying technology of the framework The disclosure shows that the technology construction of mini programs is becoming increasingly mature and perfect. With the continuous enrichment of the infrastructure ecosystem, officials have successively provided support for these capabilities, including same-layer rendering, network environment monitoring, initial rendering caching, and startup performance optimization, gradually bringing mini programs closer to the Web ecosystem.

In our own business iteration, in order to solve various problems, we have created many wheels ourselves, such as: subcontracting and asynchronousization, CI packaging, and performance API. WeChat will later implement these capabilities natively. It may seem like a useless effort, but in fact it just shows that what we have done in the past is correct, and the direction is consistent with the development of the entire ecosystem.

More scenarios to empower business

In addition to the improvement of technical capabilities, the WeChat mini program ecosystem is also constantly enriching capability support in more business scenarios, such as Support mini programs for sharing Moments, generating short links, and WeChat chat materials to open mini programs, providing more possibilities and imagination for our business.

WeChat has also launched a mini program hardware framework, which allows hardware devices (non-general computing devices) to run WeChat mini programs even if they lack the conditions to run the WeChat client. It can be used on Android tablets, tablets, etc. in all walks of life. Hardware such as large-screen devices provides low-cost screen interaction solutions and provides IoT device users with a more standardized and feature-rich experience.

This reminds me of the saying Atwood's Law that has been circulating in the field of computer technology for decades. Any application that can be written in JavaScript will eventually be written in JavaScript. Likewise, any product that can be implemented using mini programs will eventually be implemented using mini programs.

Prospects for the development of mini programs

Since the birth of WeChat mini programs in 2017, the super App mini program/light application model has been tried and tested in various businesses, such as WeChat and WeChat mini programs, Alipay and Alipay mini programs, Douyin and Douyin mini programs, etc. Mini programs, a product model with low cost, fast iteration and easy promotion, have been used in various fields with the support of huge traffic brought by super apps. All have achieved great success and have gradually become a trend, with more and more companies adding this model to their products. The mini program itself has been unknowingly integrated into every aspect of life. During the epidemic, health code applications in various regions, mini program codes for e-commerce group purchases in the community, and restaurant ordering, if you want to drink milk tea and coffee, you can download them in advance on the mini program. In fact, people's lives are inseparable from small programs. The product technology solution of small programs has indeed created great social value.

When I was chatting with a friend, I jokingly said that mini programs are PWA applications with Chinese characteristics. Facing the future, mini programs still have great potential. In addition to the existing online shopping and life service applications that account for a relatively high proportion, they are also used in more The usefulness of mini program technology can also be seen in various scenarios. For example, in the fields of health care, offline retail, entertainment games, AI intelligence and other industries, it is far from reaching saturation. The market gap has made the development potential of mini program become more and more important. To get bigger, Mini Programs are moving towards the original goal of making Mini Programs within reach and everywhere.

Original address: https://juejin.cn/post/7100752247381819399

(Learning video sharing: Getting started with web front-end)

Statement:
This article is reproduced at:juejin.cn. If there is any infringement, please contact admin@php.cn delete