From the PC era, the mobile era to the Internet of Things IoT era, with the increasing diversification of terminal devices, the seeds of cross-terminal reuse have been born and started to germinate. From a business perspective, across more is in different stages, different periods of technical evolution in the choice of business efficiency, Meituan home stay facility operation in large front wave, in the tide of integration of choice, continuously explore and iteration to solve business pain points and hatched across the framework technology, in the process, we made a lot of exploration and practice of thinking, I hope I can give you some inspiration. This paper mainly shares the experience of Meituan Homestay in the process of cross-end reuse technology exploration and business practice.

From the PC era, the mobile era to the Internet of Things IoT era, with the increasing diversification of terminal devices, the seeds of cross-terminal reuse have been born and started to germinate. From Hybrid solutions that rely on container capabilities and all kinds of offline preloaded packages, to connecting JavaScript ecology with native controls through JSC, Combine view framework (React, Vue, etc.) to find more balanced efficiency, dynamic and performance of Native container solutions (React Native, Weex, etc.), then led by wechat with multi-process WebView, container standardization of the small program was born, small programs on various platforms have sprung up. Subsequently, it brought the domestic Taro, UNI-APP, Rax, Remax and other multi-terminal frameworks.

From a business perspective, the evolution of cross-terminal technology is more a choice of business efficiency in different stages and time periods. Meituan home stay business is moving forward in the wave of big front-end integration, constantly exploring and iterating choices, and incubating cross-terminal framework technology to solve business pain points. This article mainly shares meituan homestand’s experience accumulated in the exploration of cross-end reuse technology and business practice, hoping to bring some help or inspiration to everyone.

1. The background

1.1 Introduction to Meituan home stay Business

Meituan homestay focuses on providing consumers with “different living” experience, providing services including homestay, hotel, apartment, inn, short-term rental, guesthouse, travel accommodation, etc., while including treehouse, rv, INS wind and other novel network celebrity homestay. Since its launch, The business of Meituan B&B has developed rapidly. On the supply side, the types of housing supply have been constantly enriched, and various kinds of distribution, direct sales, direct connection and overseas launch have been successively. The dimension of housing information has been expanding, and screening, recommendation and information presentation have also become increasingly complicated. At the same time, with the rich marketing methods, landlord management, operation, service expansion, home stay business is more and more complex. The front-end of Meituan b&B is constantly iterating with the development of business, and the overall structure of mobile terminal is also constantly adjusting and upgrading, in order to meet the development demands of diversified and complicated business.

1.2 Mobile terminal status of Meituan Homestay

With the development of business and the continuous evolution of cross-terminal reuse technology, Meituan home stay client has changed from a single-terminal Native App that just started its business to a combination of cross-app (Home stay stay App, Meituan App and Review App) Native reuse and Hybrid solution that uses SSR to bridge the performance gap. In this game of performance and efficiency, the client finally settles on the reuse framework with React Native (RN for short) as the core. At the same time, with the birth, ecological growth and multi-platform trend of wechat small program, the homestay small program end is also growing, and gradually forms a multi-platform reuse small program architecture.

On the left is the technical architecture of the client. Above the iOS and Android system layer is the independent Native infrastructure layer, and then up through RN to open the door of dual-end reuse. Then RN container standardization shields the differences between host applications to ensure the consistency of containerization. Then the reuse of business layer and cross-app is realized. On the right side is the current simplified architecture diagram of homestand applets. We have made multi-terminal adaptation in the infrastructure layer and realized the reuse of applets on various platforms through multi-platform reuse construction tools. At present, the client and the small program are related and independent, and the development and maintenance are also independent of each other.

Although Meituan Home stay App has realized cross-terminal reuse of iOS and Android through RN, the App and small program still need to invest double the labor cost for business iteration, so we have a question to consider: Is it possible to go further and use a set of code to solve multi-terminal problems, so as to unify iOS App, Android App and small programs?

2. Design of cross-end reuse framework for Meituan Homestand

2.1 Industry Status

In recent years, under the leadership of wechat small program products, the industry has also been born a variety of small program applications, the technical differences at each end make the development and maintenance costs have doubled. In order to bridge the technical differences of plain development, applets development, Web development and so on, some excellent multi-terminal frameworks have been born. For example, Taro, UNI-App, Rax, Remax, etc. These frameworks all convert their own defined DSL (generally React DSL, Vue DSL) into various terminal applications (wechat applet, RN, H5, etc.), so as to realize a set of code and multi-terminal operation.

In Meituan b&B business, App transactions account for a large proportion. From the business perspective, the performance experience and demand development efficiency of App should be guaranteed first. However, the current B&B App has been migrated to RN technology stack. Based on these two points, we hope that the cross-terminal reuse scheme is RN to small program platform scheme, so the multi-terminal framework mentioned above cannot meet our demands of RN-small program cross-terminal reuse. Therefore, Meituan Homestay has realized the scheme based on RN to small program reuse by referring to the multi-terminal design scheme of the industry.

RN uses the React syntax, so how to convert RN into applets requires first thinking about how to convert React code into code that applets can run (applets for short), and then adapting RN’s basic component libraries. React code conversion to applets has become a common practice in the industry over the years. There are two types of solutions in the industry: compile and runtime. Here is a simple comparison of these two solutions:

Classification framework recompile Heavy run
Typical representative Taro2.0 / Rax compile time Taro Next / Remax
The principle of Convert React code directly to applet code at compile time The React custom renderer is used to render the page
advantage Low performance loss No syntax restriction
disadvantage Syntax restriction High performance loss

By contrast, the recompile scheme has one serious problem: syntax limitations. Because most front-end developers have come to rely on flexible syntax, such as using higher-order components, writing a lot of returns when judging conditions, and so on, it is hard to accurately hit during compilation. Therefore, compile-time schemes impose syntax rules that restrict what developers can write. Re-run scenarios have no syntax constraints and can use various React features at will. It is implemented by implementing the React Renderer (mp-Renderer) corresponding to the React Reconciler applets platform through the React-Reconciler to render virtual DOM trees. However, the applet does not have a DOM API to update the interface, so the generated virtual DOM tree data is triggered by the applet’s setData to update the rendering layer, where there is a common template that can be used to render the data.

Due to the limitation of the recompile syntax, we decided to adopt the rerun scheme to implement RN subroutine. However, the rerun scheme has performance problems and is difficult to meet business requirements. After continuous exploration, we designed a corresponding scheme to greatly improve the performance. How to solve this problem will be described in detail below.

2.2 Overall scheme design

2.2.1 Technical scheme of RN and applet reuse

The overall architecture is divided into two parts: compilation process, running process. It renders the React code in a similar manner to the re-run scheme described above, using the MP-renderer. Let’s briefly analyze these two processes:

(1) Compilation process: In this stage, RN source code is converted to run the process. After compilation, the following products are mainly generated:

  • Compiled RN: When compiled, RN code is generated, which is essentially React code.
  • Adaptation library: An adaptation library of RN’s base components, implemented using applets for custom components.
  • Common template: Since applets don’t have the DOM API to manipulate node operations like the Web, a common template renders the React Rendered TreeData (UI data serialized by the page’s virtual DOM tree).
  • Merge template: this template is used for performance optimization. this template will be examined in more detail below.
  • WXSS: Convert the Style of RN code to WXSS to optimize performance by reducing the amount of TreeData on a page.

(2) Running process: The running process is divided into logical layer and view layer.

  • Logical layer: Compiled RN source code contains RN business components and adaptive component libraries, which are adapted by applets custom components. This approach provides flexibility in using the applet native code to align RN component functionality and improves the performance of the converted applet, since the applet native code does not generate TreeData, thereby improving performance. The logical layer has an mp-renderer, which is implemented in the same way as described above. After the RN code is rendered, the corresponding virtual DOM tree is generated. The virtual DOM TreeData is serialized to generate the corresponding TreeData (UI data describing the page).
  • Render layer: When the page needs to be updated, the logical layer transmits the TreeData to the render layer through setData. The TreeData is combined with common templates, merged templates, and corresponding styles to render the corresponding UI.

To sum up, the overall design above is somewhat similar to the industry multi-end framework, but there are also differences, mainly reflected in the adaptation component library and merged template. Adaptive component library is explained above is better understood, and merge template here may be more confusing. The merged template content is actually generated by a “statically compiled” transformation of the compilation process, which is intended to improve the performance of the converted applet. We will focus on this performance solution in the following sections.

2.2.2 Performance Solution

What is the cause of the performance loss of the rerun scenario? As mentioned above, the re-run scheme will transfer the TreeData corresponding to all React code to the rendering layer through the setData small program. When the page is initialized or big data is updated, setData will need to transfer a large amount of data, thus causing corresponding performance problems. So the core of the solution to the performance problem is to reduce the amount of TreeData.

In the RN to applet scheme above, it is mentioned that adaptation component library and style transformation can play a corresponding performance optimization role. Its optimization principle is by reducing TreeData data. Although these methods can optimize performance, when the page is complex, the amount of TreeData is still large, so the optimization effect is not obvious. To this end, we thought of a new way to further compress TreeData’s data volume, namely combining the statically merged tree node scheme mentioned above. Before discussing this scheme, let’s take a look at an example of RN code converting to TreeData:

As shown in the figure above, the TreeData after RN code conversion is a JSON data describing the UI tree, which is equivalent to the UI tree on the right. The nodes of the tree can be classified into static data and dynamic data. For example, View and Text nodes are static data. “Hello” and “World” are dynamic data. By static data, the compilation process is predictable, so could this data be transformed to describe the UI in a way that reduces the amount of data in TreeData? The answer is yes, static compilation of merge tree nodes is achieved by this principle, as shown in the following flow:

This scheme has two actions, namely, static compilation and merge tree node. Static compilation converts RN code into merge template, as shown in code Number 2 in the figure above. The merge template is named “B1”, and the content is a WXML structure fragment corresponding to RN JSX code. The merging node is to merge the statically compiled nodes, as shown in the process no. 2 to No. 3 in the figure above, the original five nodes are merged into the top-level View node, which is called the merging node. The merging node needs to record the name of the merging template and relevant dynamic data. The purpose is to enable the merge node to find the corresponding merge template for rendering. After merging the nodes in this way, the final generated TreeData, as shown in figure 4. You can see that TreeData has been reduced by about 60% compared to its previous volume!

Static compilation has syntax restrictions. Static compilation has syntax restrictions. Static compilation has syntax restrictions. It is true that there are syntactic limitations if you compile completely statically, but the combined static compilation here is selective compilation, that is, during the compilation process, the AST is used to analyze whether the node is static, and if so, it is converted into the corresponding merge template. If an unpredictable dynamic node is encountered, follow the runtime scenario. Therefore, the resulting UI tree node will contain both the merged node and the original component node, as shown below:

In this way, you can keep the syntax unrestricted while maximizing performance through compilation. There are drawbacks to this approach, of course, because it is a space for performance trade-off, and the generated merge templates can affect package size, but for pages that are performance-driven, this increase in package size is worth the cost.

In order to better measure the performance improvement of the solution, we collected and compared the performance indicators before and after optimization as well as after the implementation of native and Taro 3.0 by referring to the experiments on the Taro website. After experiments, the operation time of initializing, loading data and loading a large amount of data of each framework was calculated, as shown in the following table:

Operation time \ frame Before optimization The optimized native Taro 3.0.17
Initialization (first screen render time) 897ms 423ms 210ms 675ms
Load common data (20 pieces) 1124ms 198ms 110ms 640ms
Load a lot of data (400 items) 5330ms 1041ms 470ms 3919ms

As can be seen from the above table, after the performance optimization, the operation time of loading data is reduced by 80% and the initialization time is reduced by 52% compared with that before the optimization, thanks to less rendering data and more streamlined node tree. Taro 3.0 also provides better performance than Taro 3.0, a similar framework.

Compared with the native, the performance gap after optimization is significantly reduced. However, as the runtime scheme requires more setData overhead and more complex rendering process than the native scheme, the performance gap between the runtime scheme and the native scheme objectively exists in principle. However, in business practice, the gap between the two is not so obvious, because in the evaluation experiment, the test data is relatively pure and the setData data utilization rate is high. However, in business practice, the setData data of the original development is inevitably redundant and difficult to optimize, while the runtime scheme will optimize the redundant data by default, making the performance gap between the two closer. From our historical business practice data, the performance gap with native is around 10%.

3. Practice of cross-terminal reuse of Meituan homestay

In the exploration of cross-end multiplexing, we use innovative solutions to solve the problems of performance and characteristic limitations, and design RN- small program cross-end multiplexing framework. Although cross-end reuse belongs to the “sharp weapon in hand”, but it is a “double-edged sword”, if used properly, it will get twice the result with half the effort, and if handled improperly, there are many hidden dangers. So, how to control this sword in business practice? We will introduce the problems encountered in our business practices and then introduce solutions to these problems.

3.1 Problems in cross-end Reuse Scenarios

  1. Problems in reuse scenarios: Small program product form with the light, fast, and purpose, the user can use fast, out of which, the client products relatively complete, refined, stability, can meet the demand of more users, with users of retained, cognitive users, the user experience is given priority to, there are many differences between both on product features, how to properly deal with product differentiation is reuse across the end under the scenario of an important challenge.
  2. Cross-end reuse quality hidden trouble: the realization of reuse will have to consider both ends of the compatibility problems, which will produce a variety of quality hidden trouble. How to ensure compatibility of interface, input and output of components in continuous iteration of reusable components? How to ensure the unity of the underlying dependencies and interfaces of the adaptation layer of each reusable component? How to better test and monitor the dual-end multiplexing scenario? Dual-end students have their own technical cognitive boundaries, how to quickly troubleshoot problems and timely stop loss?
  3. Cross-end reuse process specification problem: the new technological revolution is bound to break the old order. In the current cross-end reuse scenario, various problems including project management, code specification, branch management and demand synchronization will also emerge and need to be solved.

3.2 Cross-end reuse application architecture

Reuse in order to solve the cross end all sorts of problems encountered in business practice, we redesigned the reuse across the end application architecture, architectural layering management, reuse way aspects of design, process specifications, quality assurance, the key to solve across the terminal differentiation, quality hidden trouble, the process specification all sorts of problems, and seek to maximize the reuse of the balance and performance.

3.2.1 Cross-terminal Reuse Application Architecture Evolution

Here, I first post the dynamic architecture evolution process, so that we have a macro understanding. We will briefly describe the evolution and then go into more detail based on the final architecture diagram. The general evolution process is as follows:

  • At first, the client was developed separately for Android App and iOS App, and RN technology was introduced to realize cross-terminal reuse of Android and iOS. However, the small program still needs separate maintenance iterations.
  • In order to further realize rN-applets cross-terminal multiplexing, we access the self-developed RN-applets cross-terminal multiplexing framework, and based on the framework’s adaptation specification and RN infrastructure as the benchmark, to create a unified interface with RN infrastructure applets adaptation layer.
  • After mp-Render and Reconciler layers are completed, the React-Reconciler layer can be opened up to the side of the small program, enabling the ability to reuse React code into small programs.
  • After realizing the reuse between RN and small programs, RN code can be abstracted, adapted and sorted out, and then extract a component reuse layer, which can be directly used by the upper business layer.
  • Finally, in order to solve various process, collaboration and quality risks in cross-end reuse scenarios, corresponding process specifications and quality assurance measures are provided.

3.2.2 Application architecture for Cross-terminal Reuse

The rN-applets cross-terminal multiplexing architecture diagram of the whole b&B is shown above, and we interpret it from the perspective of bottom to top and left to right:

  • System layer: The lowest layer is system services. Except for iOS and Android, we treat applets as a separate system module.
  • Basic service layer: on top of system services, there is the basic service layer, which is mainly the infrastructure built by the Group based on Native and small programs, which is common to the whole company and covers all aspects of basic services in R&D projects. Building on this foundation, we have introduced in our applet infrastructure an MP-Render applet runtime renderer based on the React-Reconciler implementation, which dynamically updates vNodes at run time to match the applet UI templates for compilation and transformation, calls the applet native apis, The React applet renderer makes cross-end reuse possible.
  • Infrastructure layer: above the basic service layer is the infrastructure layer, which mainly includes MRN infrastructure and small program adaptation layer. We take MRN infrastructure as the standard, and adapt a unified standard and unified interface small program adaptation library. Through this layer adaptation, the upper layer can realize the reuse of components in the same standard without perception or difference. The adaptation layer is divided into two parts. The lower part is mainly suitable for RN basic services, and the upper part is the basic library and third-party library independently encapsulated by home stay service. We introduce an adaptation library named Mapping to this part. A separate adaptation library allows RN and applets to be independent of each other during business iteration and technology change, thus ensuring that technology advancement does not affect business iteration at all. On the top of the infrastructure layer is the React-Reconciler. The React framework itself separates the reconciliation process from the rendering process. The React-Reconciler framework is at the heart of cross-reuse, so we put it on a separate display, which really breaks down the gap between clients and small programs. As long as you have a separate applet renderer, you can reuse React code into your applet completely and without limit.
  • Reuse layer: The infrastructure layer is followed by the multiplexing layer, which mainly uses component dimensions for multiplexing. The multiplexing component is abstracted and adapted based on the stock RN component, and then extracted independently. The components of the multiplexing layer are used by the upper-layer business with unified standards and interfaces. The reuse layer is a very important part, and a good reuse mechanism can help us solve the problem of product differentiation and reuse maximization mentioned above. Let’s put this in its own place3.3 Design of cross-terminal reuse modeLet’s go into detail.
  • Business layer: above the reuse layer is the business layer. Each module of the business layer mainly adopts the page container to undertake the reuse components. Based on the differences of different ends and products, the page components can be flexibly and dynamically configured to meet the differentiated needs of the business.

3.3 Design of cross-terminal reuse mode

Differentiation problem has always been a pain point in cross-end reuse scenarios. How to properly deal with and adapt the differences in dual-end products, platforms and codes is also a problem we have been thinking about. A good differentiation solution can improve the maintainability of the code, reduce the hidden quality and improve the development efficiency. We set off from the reuse design level, explore the page multiplexing mode, component reuse mode, “components and logic reuse” model of three kinds of reuse design approach, and according to the different scenarios with different mode of reuse, can handle well across the differentiation problem, at the same time can take the performance experience, efficiency and maintainability.

3.3.1 Reuse mode under differentiation

Our self-developed multiplexing framework provides two multiplexing modes, as shown in the figure below:

Page reuse mode: page mode is based on page dimension, which can directly reuse all the network layer, logic layer, data layer and component set in the page. In this way, the maximum reuse can be achieved, and the code reuse rate can reach more than 90%, and the human efficiency is significantly improved. Component reuse mode: Component mode is based on component dimension. Reuse takes business components in the page as the target, and extracts all components of the page into reusable components after abstraction, decoupling and normalization. The component mode can only reuse the code within the component, and the logical interaction and network layer of the page container need to be realized by the small program itself. The code reuse rate is relatively low, but the component reuse is more flexible and controllable, and can be inserted, removed, spliced and customized at will.

Here are the pros and cons of the two reuse modes.

Page reuse mode

advantage

  1. Obvious improvement: the whole page including all components, page logic layer network layer package conversion reuse, high code reuse rate, greater improvement in development efficiency.
  2. Low access cost: the entire page is directly converted into synchronous reuse, without the assistance of small program students to access, reducing the risk of error caused by two-end assistance and interface communication.

disadvantage

  1. Low flexibility: Business differences and small program features are difficult to deal with, dual-end difference adaptation can only be done on RN, code is error-prone, high maintenance costs.
  2. Performance disadvantage: the whole page is multiplexed by RN conversion, and the page is rendered once, the performance will be slightly worse, and it is difficult to do page-level performance optimization.
  3. Large package size risk: In the case of full-page reuse, the package size is large and cannot be dynamically deployed (for example, a module in the page needs less iteration and does not want to be reused, but the page mode cannot be dynamically removed).

Component reuse pattern

advantage

  1. Lightweight and flexible: components can be plugged, spliced and customized at will like plug-ins, which can better solve the difference problem between App and small program. For the difference, the two ends can be independently implemented to improve the maintainability of the project.
  2. Good performance: the page container is still small program native components, such as rolling, sliding components using native can reduce performance loss, in addition, components distributed setData rendering has better performance, not like the whole page one-time rendering lead to a large amount of setData data affecting the first screen loading performance.
  3. Large space for performance optimization: it does not affect the performance optimization of page dimensions, such as first screen priority and request front-loading.
  4. Package size control: Component reuse can be dynamically adjusted, such as removing less iterated components from a page to reduce package size.

disadvantage

  1. Limited efficiency: the component mode can only reuse the code within the component, the code reuse rate is low, the page container, logic layer, network layer small program still need to maintain a code.
  2. High maintenance cost of reusable components: The compatibility and maintainability of component interfaces must be considered during component upgrade iterations. Improper management may cause quality risks.
  3. High access cost: Small programs need to implement THE page logic of RN and then access according to component interfaces, which has higher access cost.

The two reuse modes have their own advantages and disadvantages. Page mode has high reuse rate, but low flexibility and poor performance. The component mode is lightweight and flexible with controllable performance. It can better deal with platform differentiation, but has low reuse rate and high maintenance cost. We are wondering if there is a solution that preserves the flexibility of the component pattern while reducing component maintenance costs and increasing reuse. In business practice, we have explored a set of “component + logic reuse” mode, which can better solve the problems mentioned above.

3.3.2 Logic reuse under differentiation

The mode of “component + logic reuse” still retains the mode of component reuse, but on the basis of component reuse, it adds the reuse of logical layer (including page logic, network and data layer), so as to retain the flexibility of component and increase the reuse. The specific design is as follows:

The design diagram of the whole component + logic reuse mode is shown above, and we interpret one by one according to the serial number marked in the picture:

  1. Logical reuse interface instance: in the page container of the small program, the interface instance of logical reuse can be obtained by injection. Through this instance, the interface can be invoked to obtain, change and monitor the state of Redux, which in essence achieves the effect of logical reuse.
  2. Page reuse component set: pages can freely use reusable components, reusable components can be large or small, can be assembled layout, retain the good flexibility of the component pattern.
  3. Applet native component: the page can use reuse component, also can use the applet native component to realize the function and the feature of the applet differentiation, this can better deal with the difference between the two ends. Native components of applets can invoke logic layer functions through logical reuse interface instances, thus achieving the effect of logical reuse.
  4. Popover multiplexing components: Popover multiplexing components are the same as page multiplexing components, which mainly explains that reusable components can be classified according to various dimensions, so as to better manage reusable components.
  5. Reuse component library: the reuse component library can be more or less, can be large or small, if the difference between the two sides of the page is small, a large component can be satisfied. Each reusable component set packages a layer of ReUDX-Provider and sets the same Store, which can be automatically bound to the logical layer. Because RN components themselves are based on Redux, the reuse process is relatively easy.
  6. Business logic layer: The business logic layer on the right can be simply understood as three parts. One is the data layer based on Redux Store, where all the data, operation and interface of monitoring data of the whole page module are stored; the other is the network layer containing all the network requests in the page. Reducer and Redux-Saga, which are used for state flow and reuse, as well as various supporting tools. The business logic layer can divide Reducer and Saga into smaller units according to the differences between the two ends to achieve differentiated logic reuse and improve the code maintainability of the logic reuse layer.
  7. Encapsulating and multiplexing interface: The business logic layer contains the business logic of the whole page. As long as the interface is targeted and open to the small program, so that the small program can obtain, change, and monitor the state of Redux, the effect of logic reuse is achieved in essence. There are two ways to open interfaces to applets: logical API interfaces and stores.
  8. Logical API interface: based on Store to provide small program really need logical API interface, through these API small program can get data to render UI (such as: render not reused components), can also update the data, can also listen to reuse components internal data changes.
  9. Store: Expose Redux Store, small program can use Store instance through getState, Dispatch, subscribe to operate, listen to the state machine, also achieve the purpose of logic layer reuse.

The advantages of this scheme are obvious, it retains the flexible characteristics of component mode, which can be more convenient for differentiation and performance optimization. The logical reuse layer includes Redux, which is not only easy to transform and error-prone, but also the logical reuse interface based on Redux Store, which is better designed, easy to maintain and error-prone. For the logic layer, can do some differences according to the business Reducer and Saga of partition, screen out the don’t need to reuse the code logic, logic layer reuse can also do like components are hot-swappable, on-demand introduction, it is better to do difference code management, high maintainability of the project, at the same time also can reduce risk of packet size is preferred.

3.4 Cross-end reuse process specifications

In order to improve the development efficiency as much as possible and avoid introducing quality problems in the process of code cross-reuse, we formulated the development process specifications such as differentiated coding specification, requirement synchronization specification and reusable component specification. The following will be a brief introduction through the requirement synchronization process of RN to small program products.

1. Assess whether service requirements need to be synchronized

In response to PM’s requirement for synchronization, clients try to reuse RN service codes into small programs to improve development efficiency. Requirements that do not need to be synchronized will be controlled by differential coding specifications to avoid the potential risks and testing costs of synchronization to small programs. Generally, it can use platform determination (such as iOS, Android, and WX_Platform) to control whether the business code is inserted into the reusable component package. It can also realize different logic of the same interface through different suffix files of module.rn.js and module.wx.js.

2. Assess whether there are associated dependency requirements

If it is clear that a service requirement needs to be synchronized, determine whether the requirement has pre-requirement dependence and then evaluate the technical solution. If there is no dependence can directly start reuse adaptation work; If there are dependencies, determine whether the pre-dependent requirements can be synchronized or properly degraded, so as to recurse to avoid the problem that the pre-dependent requirements do not meet expectations due to the non-synchronization.

3. Develop RN component adaptation and small program access schemes

After the requirement synchronization scope assessment is defined, the following technical assessment work should be completed :(1) it should be clear whether the requirement needs to build new reusable components or iterate on the original reusable components. If a new NPM package of reusable components is needed, the technology selection should be made according to the component reuse specification, and the “component + logical reuse mode”, “page mode” or “component mode” should be determined, and the corresponding interface protocol of reusable components should be formulated. (2) Determine whether the requirement requires the development of RN-applets mapping methods and components, and evaluate the corresponding development volume. After completing the technical evaluation, communicate with the small program side in advance for access and scheduling.

4. Adaptation development of RN components

After the client completes the development of RN side requirements, it can develop reusable component adaptation applets. After the adaptation development is completed, test the reuse components on both the RN page and the small program Demo page to avoid introducing RN page bugs in the adaptation process. After testing the reusable component, NPM package and corresponding interface documents are provided to the applet access. However, before packaging, the DIFF between the current version and the last version should be strictly reviewed to avoid the code that does not meet the expectations being synchronized to the applet.

5. Applets connect to the RN adapter

After adaptation, package the components and provide them to the mini-program side for access. After access, perform self-test again in the mini-program environment of Meituan Homestay. In principle the client after students provide adapter RN components, side classmate of small programs and test access, but we also encourage the client at the completion of an RN component development and reuse after adaptation, together complete the side of the small program components connected to the work that needs development complete degree is higher, and can effectively reduce the communication cost across end under development. In the future, with the promotion of large front-end integration, the reuse rate of RN-small program code will gradually increase, and the client (iOS, Android) and small program code will tend to be developed by one student.

6. RN adaptation code merges into the iteration branch

It is required that after the small program test is completed, the RN component adaptation Feature branch code should be merged into the Release iteration branch, and packaged and put online on the client (iOS and Android).

3.5 Quality assurance for cross-end reuse

In the scenario of cross-end reuse, there are various quality risks, such as interface compatibility of reusable components, dependency between components, loss of testing and monitoring, and difficulty in troubleshooting. In business practice, we have also explored a series of quality assurance measures to solve these risks. Including component interface maintenance, component dependency management, dual self-test card control, anomaly monitoring fusion, dual-end fault SOP, cross-end reuse process specifications. These measures can effectively guarantee the online quality of double-terminal in the multiplexing scenario. In the cross-terminal multiplexing process of homestay business, there is no online failure due to the protection of these measures.

1. Maintain component interfaces

Reusable components will be updated and upgraded with business iteration. Component interface, input and output changes will be brought in the process of component upgrade, which will lead to compatibility risks, such as component input parameter type changes, and the small program or RN side is not timely compatible or unknown, which is very easy to cause online quality problems. To this end, we made component interface maintenance plan, including reuse component interface specification, component version management specification, component interface document construction and so on. Reuse component interface specifications require reuse component interfaces, and parameters must be strictly in accordance with the specifications, such as the basic type of parameter types, the principle of only increasing or decreasing, the interface name is clear, and the number of parameters is limited, so as to reduce the difficulty of dual-end access components and avoid quality risks caused by frequent parameter changes. The component version management specification requires that component version upgrades follow semantics 2.0 and have the corresponding version upgrade documentation. Component interface document construction is also very important. Each reusable component has corresponding document maintenance, which records the increase, deletion, change and check of parameters. The access party can see the changes of component interface clearly, which naturally reduces the access risk.

2. Component dependency management

There are two main problems with component dependency. First, the reuse framework itself is constantly being upgraded and optimized. New reusable components may be converted from new compiled versions and rely on new run-time renderers, but old reusable components may be incompatible, so we develop related tools. If the run-time renderer version that the component relies on is inconsistent with the applet’s built-in version, a warning is raised indicating component compatibility issues. Second, because different reusable components come from different RN modules, they may rely on different versions of third-party libraries, which is prone to inconsistent quality issues. The current solution is to separate these dependency libraries into their own packages, so that the reusable components are independent of each other. Combined with tree-Sharking optimization, the real package size is not large, and a small package size is used in exchange for more robust quality assurance.

3. Double self-test card control

In the case of cross-end reuse, the change of a reuse module should consider the problems of dual-end compatibility and the compatibility between new and old versions. Compared with the previous, there is a higher risk of error. A more comprehensive self-test can help us expose problems as soon as possible and reduce the risk of failure. Therefore, we have carried out code self-test coverage card control on the App side and small program side, requiring that the implementation coverage of modified code exceed 90% before testing and launching. The reusable component is self-tested once in RN side, and is forced to self-test again after the small program is connected. Dual self-test card control can better guarantee the quality of components and online quality.

4. Merge abnormal monitoring

Both RN and small programs have separate exception monitoring mechanisms, including JS exception monitoring, API exception monitoring, and custom exception monitoring. However, there is a big difference between the two exception monitoring mechanisms. In the multiplexing scenario, the cross-use of the two leads to confusion in the anomaly monitoring system, and inconsistency in data format, policies, and logs results in false or false alarms, troubleshooting difficulties, and operation and maintenance confusion in the monitoring system. Therefore, we integrated the two-end exception monitoring module, adapted the underlying exception reporting logic, and unified the two-end reporting standards, alarm policies, logs, and processing processes. After the dual-end fusion of the anomaly monitoring system, the anomaly reporting, monitoring, operation and maintenance are much smoother, and also help us find a lot of online anomalies, which is a solid barrier for the online quality of rN-small program cross-end reuse scenarios.

5. Double-end fault SOP

In view of the technical barriers and information asymmetry of dual-end students, how to troubleshoot problems quickly becomes a pain point when there are failures or anomalies of reusable components. RN students are not familiar with the error log of small program, and RN students are not familiar with the business code implementation of RN, so it is more difficult to troubleshoot errors at the framework level. To this end, we have sorted out the two-end fault SOP, which includes common log analysis to help identify the problems of reuse components, applets, and underlying reuse framework and corresponding solutions. Meanwhile, we have developed Source Map error unsolving tool to assist RN students to untroubleshoot applets logs to help fast troubleshooting and so on. These Sops and tools can help dual-terminal students to independently or assist troubleshooting related faults in the first time and quickly stop losses.

6. Cross-end reuse process specification

Process specifications, including the aforementioned reusable component specifications, coding specifications, requirements synchronization specifications, branch management specifications and so on, are also an important part of quality assurance. It makes every link of the R&D pipeline have strict legal constraints and ensures that the whole R&D pipeline can finally deliver complete products to users.

3.6 results

Rn-small program cross-end reuse design scheme is constantly improved in business practice, explore the efficiency of relatively maximum reuse mode. From the perspective of development efficiency, the improvement is significant. We summarize the code reuse rate and human efficiency improvement rate to evaluate the improvement of efficiency. The specific calculation formula of the two indicators is as follows:

  • Code reuse rate: ∑(number of code lines of RN module reused – number of code lines of RN and small program platform branch judgment in the module) / ∑(total number of lines of RN code + number of native code lines of small program); The number of RN reusable module lines is determined according to the components generated by the framework transformation.
  • Human efficiency improvement rate: ∑(RN development time + small program development time – (RN development time + conversion adaptation time)) / ∑(RN development time + small program development time); Before reuse, the development time of RN and small program is needed; after reuse, only the transformation and adaptation time of RN development and reuse components are needed. According to the time before and after reuse, the formula of human efficiency improvement rate can be obtained.

According to different transformation modes, code reuse rate and human efficiency improvement rate can be obtained, as shown in the following table:

Conversion mode Code reuse rate Human efficiency improvement rate
Component + logical reuse mode 76% 42.36%
Page reuse mode 91% 46.71%

It can be seen from the table that the page conversion mode reuses the code of the page and the component, and the code reuse rate can reach more than 90%. Component reuse mode reuse components and part of the business logic code, reuse rate can reach 76%. In terms of human efficiency improvement, all modes can achieve high human efficiency improvement rate, and the higher the code reuse rate, the higher the human efficiency improvement rate. Page conversion mode can reuse pages and data state processing logic, and the human efficiency improvement is higher than the component transformation mode.

4. To summarize

Homestay big front end team in order to solve the pain of double end research and development efficiency, leaning to find cross-end technology, taste 100 grass, well versed in its principle and then build it, lift partial remedy, finally solve the shackles of cross-end frame performance, blue and better than blue. Then practice in industry, flaws and disadvantages are clearly exposed. To this end, the framework is re-set to seek its change (reuse architecture design), to find new to make full use of its effect (reuse mode design), to establish new ways to consolidate its order (cross-end reuse process specification), sharpening tools to protect its city (cross-end reuse quality assurance), so the initial results. However, the day and night changes endlessly, the road is endless, I should hold the search to adapt to the change, follow its path. Cross-end reuse before the mirror, so remember to text, hope to have enlightenment, text.

Author’s brief introduction

Kai Lin, Sen Wei, Xi Chen, Ge Yi, shao Yuan, etc., are the front-end team r&d engineers of Meituan b&B.

Recruitment information

Meituan homestay long-term recruitment of Android, iOS, FE front-end engineers, coordinates in Xiamen, Fujian. If you are interested, please send your resume to: [email protected] (please note the subject of your email: Meituan Hotel).

Read more technical articles from meituan’s technical team

Front end | | algorithm back-end | | | data security operations | iOS | Android | test

| in the public bar menu dialog reply goodies for [2020], [2019] special purchases, goodies for [2018], [2017] special purchases such as keywords, to view Meituan technology team calendar year essay collection.

| this paper Meituan produced by the technical team, the copyright ownership Meituan. You are welcome to reprint or use the content of this article for non-commercial purposes such as sharing and communication. Please mark “Content reprinted from Meituan Technical team”. This article shall not be reproduced or used commercially without permission. For any commercial activity, please send an email to [email protected] for authorization.