NetEase Cloud Music React Native System Construction and Development

Insert picture description here

Author: Zhang Weidong (Netease cloud music large front-end team)

0.33 History

In March 2017, in order to solve the problem of mall performance and user experience, the cloud music technical team formed a 4-person ReactNative development team: I am responsible for RN front-end development, and Android and iOS developers are responsible for embedding RN Native in the cloud music app. SDK, and a Java developer is responsible for deploying the platform.

After the mall's RN application was launched, other teams expressed interest in trying, but at that time RN project development did not have scaffolding. The project was created through original copies, lacking forweb support, and RN preloading was only connected to the iOS side.

Various reasons have led to the low efficiency of RN development. The musician business was originally interested in using RN to develop new applications. Half of the development was changed to H5.

From March 2017 to September 19, the RN version was always 0.33, the core development team lost half of the staff, the deployment platform was unmaintained, the project development lacked scaffolding, lacked forweb support, and a total of 2.5 RN applications were launched (Mall, Music People, ternary speakers).

Stir history

Time is rolling forward and new technologies emerge in endlessly. Two and a half years is like a world away for front-end development. If nothing happens, RN technology will lie in the dust of history and no one cares about it. This awkward situation was not broken until the member cash register arrival rate optimization project.

The member cash register page is the following picture, which is the cloud music member purchase page, and its importance is self-evident. This page was originally an H5 page developed by React server-side rendering.
checkout counter

In order to allow users to purchase members more smoothly and improve user experience and arrival rate, the entire technical team adopted web general optimization technology combined with Cloud Music’s own technical facilities, and spent a month optimizing this H5 page, increasing the arrival rate from 72% to 89%, an increase of 17 percentage points. The comparison with competing products is as follows (in seconds).

Competitive product comparison

Arrival rate calculation formula = visible point of cash register / client click point

Although the optimization results are gratifying, there are several problems:

  1. The arrival rate target has not been completed. At the beginning, the technical team had set at least 90% or more, which was one percentage point behind.
  2. The ROI is too bad. H5 optimization has invested a lot of manpower in front-end and back-end development, which took nearly a month. If you go to optimize other pages, the current solution has a low degree of automation and still requires a lot of manual operations.
  3. The 0.33 RN arrival rate was 93%. We counted the arrival rate of the RN version of the mall, without any optimization, easily breaking 90.

There are 3 ways in front of the team at this time:

  1. Put more resources into optimization on the H5 page, and exceed 90% to complete the task. However, this solution consumes a lot of manpower and material resources and is not very useful for optimizing other pages. It is a one-shot deal.
  2. Reset the cash register page on RN 0.33 version. Although this can achieve the goal, the RN infrastructure is still stuck 3 years ago.
  3. Complete the RN infrastructure, upgrade to the latest version 0.6, implement a three-terminal solution, and build a complete RN development system. On this basis, the cash register was reset based on version 0.6, and the entire RN technology stack was updated with this project. Although this scheme has great benefits, it has a long time span, great difficulty, and high complexity.

After intense discussions and painful choices, the team decided to launch an impact on a higher goal. They were not satisfied with only achieving the goal of reaching rate. Instead, they wanted to rebuild the entire RN technology system to pave the way for future development and solve the performance and performance of the entire front-end development once and for all. Experience problems.

Automatic deployment

Old deployment platform

The original RN deployment platform did not implement automatic deployment. To publish an RN application, you need to do the following

Execute compatibility script

In order to support lower versions such as iOS8, you need to manually modify the relevant source code in the local node_modules.

    sed -i -e 's/function normalizePrefix(moduleName: string)/const normalizePrefix = function(moduleName: string)/g' ./node_modules/react-native/Libraries/BatchedBridge/BatchedBridgedModules/NativeModules.js

    sed -i -e 's/function normalizePrefix(moduleName: string)/const normalizePrefix = function(moduleName: string)/g' ./node_modules/react-native/Libraries/Utilities/UIManager.js

    sed -i -e 's/function handleError(e, isFatal)/var handleError = function(e, isFatal)/g' ./node_modules/react-native/Libraries/JavaScriptAppEngine/Initialization/InitializeJavaScriptAppEngine.js

Execute packaging script

Local execution release.test.sh(test) and release.sh(online). The release script calls the iOS and Android packaging scripts respectively, and then prints the corresponding bundle.

Packaging script

Pack the result

Because both ends of the bundle use the same name, it is easy to be mistransmitted, and every time you upload it, you must be careful.

Upload publishing platform

Screenshot of the old publishing platform

Here you need to fill in the relevant content, and then click Publish.

It can be seen that the above three steps have local pollution risks, the operation is cumbersome, and it is easy to miss steps and fill in errors.

Automatic deployment process

In response to the above manual deployment defects, we reorganized and designed the entire automatic deployment process

git 克隆 -> 依赖安装 -> 自动脚本执行 -> 压缩 -> 上传文件服务器 -> 保存版本信息 -> 发布

Then replaced Java with Node to develop a new RN deployment platform

rn Publishing platform

The new RN deployment platform will automatically handle compatibility, packaging, uploading, and publishing. It supports multiple environments and completes the entire process with one-click deployment.

Double-ended preload

RN loading process

RN application loading process

  • The APP starts the RN container first, and the RN container requests JSBundle from the server, and then performs preliminary rendering.
  • After the RN page is initialized, send a request to the server for dynamic data, and complete the remaining rendering logic

It can be seen from the figure above that JSBundle requests are the performance bottleneck in the entire process.
If you advance the loading of JSBundle (triggered when the App is initialized), and then open the RN application, the App will load the resource package directly from the local, which greatly improves the user experience and performance.

RN offline package platform

Based on the above reasons, we designed the RN offline package service platform to be responsible for the distribution of JSBundle. Offline package service is closely related to build and deployment. We connect the two platforms and automatically generate offline packages during the build and deployment stage to reduce the deployment work of developers.

The following is the entire flow chart of RN automatic deployment platform and offline package service platform

2 platforms

The main process is as follows:

  1. The RN automatic deployment platform first constructs a full package, transmits it to the CDN, and then informs the offline package service platform
  2. The offline package service platform receives the full package information, uses the diff algorithm to calculate the difference package, stores related information, and publishes the difference package.
  3. When the APP starts, it accesses the offline package service, and reads the local cache or remotely fetches the corresponding full package or differential package according to the returned information.

0.33 upgrade 0.6

The upgrade work is mainly divided into two parts: RN Native SDK upgrade + RN application upgrade.

RN Native SDK refers to the RN related native code (iOS and Android source code) integrated in the Cloud Music App. Since version 0.33 and version 0.6 are not compatible at the same time, we have adopted a strategy of only maintaining and not upgrading the old version.

RN applications refer to business applications such as shopping malls and speakers, and can also be equivalent to JSBundle. The application upgrade must be completed before the SDK upgrade, otherwise the 0.6 SDK will load the 0.3 application, causing the App to crash. Therefore, all applications must be upgraded at the same time

Upgrade facing problems

Dependency problem

RN 0.3 uses React 15.3 version, 0.6 uses 16.8. In addition to rely React, there are other dependencies need to upgrade, we according to the official version were compared created a scaffold, read package.json inside information, one by one than the right, and then modify the corresponding version.

Obsolete components

The RN0.6 version removed 2 components: Listviewand navigator-ios.

In this case, if we use the new components such as FlatListrewrite, not only need to understand the original business logic, but also to modify the source code and re-test. Therefore, in response to this situation, the team took measures: do not change the existing code, extract the corresponding components from the old version.
Finally, we released @music/rn-deprecated-navigator-iosand@music/rn-deprecated-listview

Syntax compatible

The RN grammar is not only written differently between 0.6 and 0.33, but is also not backward compatible. The result is that JSBundle of 0.33 will crash directly when running on RN Native SDK of 0.6. The following is an example of the background image.

Background image

In 0.33, in order to realize the background image, it was used to Imageinclude one View, but it was changed in 0.6 ImageBackground, and the attributes are also different.

In addition to the grammar of the background image that needs to be modified, we don't know how much grammar needs to be compatible. In the face of this situation where the scope is not clear and the change time is very tight, if manual methods are used, it is not only inefficient and the progress is also controllable. Therefore, we adopted an automated processing method and launched the industry's first RN codemod framework mrn-codemod

The main process is as follows:

  1. Use the framework to read the 0.33 source code first
  2. Convert 0.33 source code to AST tree.
  3. Perform corresponding operations on the 0.33 AST tree and transform it into a 0.6 AST tree.
  4. Regenerate the source code of the 0.6 AST tree.

The whole framework handles a total of 12 translation rules

mrn-codemod

After the completion of this framework, all RN application upgrades were completed within one day, which not only ensured accuracy, reduced labor costs and time, but also provided expansion for future upgrades.

3-terminal solution

After the above upgrades were completed, the team began to invest in the research of the 3-terminal solution. After the investigation, there were three main methods: direct conversion, bridge mode, and bottom construction.

Direct conversion

Because RN and React are only different in grammar at the rendering level, if RN's grammar can be directly translated into React grammar, then RN can be run on the browser.

For example, the RN will Viewturn React's div, RN's click event onPressinto the React onClickand so on.

The disadvantages of this scheme are:

  1. over work load. RN inside View, Text, Imagebasic components very much.
  2. There is no one-to-one correspondence. For example, Viewthere is a onStartShouldSetRespondermethod, and no corresponding event can be found in React.

Bridge mode

For RN applications, first find a three-party framework that supports forweb, and then convert the RN DSL to a third-party framework DSL to achieve the final goal.

The representative ones in this regard are Taro and ReactXP .

According to the RN specification, Taro has implemented a set of DSL and customized functions and events.

ReactXP's three-terminal support is very good, but there are very few components, so I had to give up.

Underlying construction

According to the definition of RN elements and components, the whole set of RN API is realized by WEB-related features from the bottom. This is react-native-web . This solution is also the mainstream model in the industry.

We encapsulated and extended this library, added unsupported components, fixed some bugs, and formed it @music/react-native-web-suffix.

New development process

Based on the three-terminal solution, we developed rn-cliscaffolding, rn-utilcommon tool libraries, rn-templateproject initialization templates and other supporting tools, forming a complete set of RN development infrastructure. The current new development process is as follows

Process

rn-cliCalled when the scaffolding is initialized rn-template. rn-templateBuilt-in android, ios and web development containers and some common engineering configurations, a collection of rn-util(processing request, environment judgment, general protocol) and three-terminal component library.

Reconstruction result of cash register RN

After the above efforts, the cashier has been refactored on the RN 0.6 version, and the arrival rate has increased from 89% to 99% in the previous H5 (optimized).

Arrival rate comparison

status quo

With the improvement of RN version and perfect infrastructure, more and more big front-end developers adopt RN technology stack in new projects.

More than 10 RN applications have been launched, such as:

future plan

At present, RN technology has become the key development direction of the big front end, and there is a special person to take charge of this matter. The follow-up specific planning is carried out around the three major directions of performance , efficiency , and monitoring , with the goal of becoming the industry's first echelon in this area.

Several special projects are currently in progress

Native RPC

The main purpose of this project is to get through the RN bridge and JS bridge, allowing a set of data communication mechanisms to support both RN and web.

The previous bridge had two main problems:

  1. Inconsistent usage. Need to write 2 sets of grammar to support RN and web respectively.
  2. Support is inconsistent. Some protocols do not have RN for web, and vice versa.

Therefore, in response to the above situation, the big front end unified the APIs at both ends and refactored the underlying protocol to support the above functions. Here is an example.

// 查看 net.nefetch 是否支持,
mnb.checkSupport({
    
    
    module: 'net',
    method: 'nefetch'
}).then(res => {
    
    

})

/* 手动添加方法 */
mnb.addMethod({
    
    
    schema: 'page.info',
    name: 'getPageInfo'
});

/* 添加之后即可调用 */
mnb.getPageInfo().then((result) => {
    
    
    // ...
}).catch((e) => {
    
    
    // ...
});

Both ends of RN and web are written uniformly, so developers no longer have to worry about compatibility issues.

RN unpacking

The RN application performs well on most mainstream models, but there is a stuttering phenomenon on some low-end Android devices. In order to solve this problem, start the unpacking special project, which is mainly divided into two parts.

  1. Unpacking. Disassemble the current complete JSBundle into a basic package and a business package, and load them separately.
  2. The container is preloaded. The RN container is preheated when the App starts, which can greatly reduce the container startup time and increase the loading speed.

other

In addition to the above-mentioned special projects, there are many special projects such as RN market monitoring, RN resource package targeted distribution, and document specification are in full swing.

Concluding remarks

At this point, are you curious about the real experience of RN in the Cloud Music App? If you are interested, please upgrade the Cloud Music App version to the latest for experience.

The team of NetEase technology lovers continues to recruit teammates! We have been hiring people, if you happen to be ready to change jobs and you happen to like Cloud Music, then send your resume to [email protected]! Join us!

Guess you like

Origin blog.csdn.net/m0_47390782/article/details/109163938