1, the background

Earlier this year, we published an article on InfoQ entitled Practice of Flutter motility in right-most App [1], which mainly describes the solution of right-most Flutter motility. Since the publication of this article, more and more students in the industry have contacted me, wanting to know more details about the right-most Flutter motility. In particular, the IDEA for a series of articles on the JS2Flutter framework on iOS came up.

This article is the opening chapter of the JS2Flutter framework, and will gradually introduce the core technical points of the framework such as rendering mechanism, communication mechanism, and implementation of animation and mini-games that rely on Vsync mechanism. First, share practical experience for the reference of interested students; Two to count in the process of their own work in the summary.

2. Design concept

The original intention of Flutter dynamics is to realize the capability of mini-programs and mini-games, meet incremental independent business scenarios, and provide more possible technology choices for Flutter dynamics. For example, some activities or small games with high requirements for interactive experience are very suitable for this scheme. We do not plan to migrate the functions of the main version at the right (too expensive and unnecessary), but to steadily extend the capabilities of the App to undertake some non-core business scenarios.

At the beginning of doing this, we also decided on some design concepts.

  • Transparent to Flutter developers, with no additional learning cost and zero cost to enjoy Flutter ecological resources.

  • The Flutter side is only responsible for UI rendering, the control logic is on the JS side.

  • The trade-off between rendering efficiency and flexibility is skewed towards efficiency.

3. The birth of JS2Flutter

3.1 Scheme Selection

The first problem to make Flutter dynamic is the technical solution selection. The product replacement solution is the simplest and most direct one, which is adopted on Android. However, due to the provisions of Apple developer Agreement, dynamic updates and executable code running are not allowed, this approach cannot be adopted on iOS. In addition, the implementation of JIT via AOT also faces similar risks. Left some possible solution is that static analytical Dart language to generate the UI description or similar RN runtime generates the UI description, the biggest problem is that the former quantity huge, support for dynamic logic high difficulty, such a right at the most entrepreneurial team, obviously not enough manpower to finish this thing, so we chose the similar RN scheme, Except instead of N being Native, it’s a Flutter. RN controls Native rendering through JS, what we want to achieve is to control Flutter rendering through JS.

3.2 Be developer friendly

Rn-like schemes need to rely on JS to realize logical control. How to not affect the development habits of Flutter developers and enjoy the ecological resources of Flutter is the core issue in the early stage of the framework’s birth.

We learned from the implementation ideas of the Flutter Web project and implemented Code In Dart with the help of dart2JS, Compile It To JS. With Dart 2JS, we are transparent to Flutter developers, allowing them to maintain their Dart development and debugging habit, support the Flutter Plugin at zero cost, and develop the IDEA Plugin to easily compile and generate two-terminal dynamic products.

3.3 Hello World

Let’s start with the simplest Hello World:

void main() => runApp(Text('Hello World'));
Copy the code

What do we need to accomplish in this process?

1. Compile to JS

2. Dynamic delivery

3. Run JS

4. Pass Text information and content to Flutter

5.Flutter parsing constructs the real Text and renders it

The first three steps are nothing to talk about. The fourth step is the creation of UI description. We need to tell Flutter what type of Widget to render with Flutter via JS, so this step we need to digitize the information expressed. Like this:

  {    'className': 'Text',    'data': 'Hello World',  }
Copy the code

Step 5 We parse the data and construct the real Text(‘Hello World’). Of course, the fourth and fifth steps also involve data transfer, that is, the communication channel between JS and Flutter should be established. The communication between JS and Native should be established through JSCore, and the communication between Native and Flutter should be established through PlatformChannel. This completes communication between JS and Flutter.

3.4 Framework Birth

The JS2Flutter framework comes into being when we think about how to maintain this system if more widgets need to be implemented and different communication scenarios have different requirements. From the implementation process of Hello World, we can understand that the framework must contain several parts. One part provides mirror Flutter widgets, which are responsible for building a virtual tree of widgets and transferring data to Flutter. One part parses the passed data to build the actual Widget tree; There is also a part between the two to do communication channel correlation, as well as to provide JS running environment, some of the ability to complete JS.

As the framework evolved and improved, the structure shown below was formed.

3.5 Framework Details

As mentioned above, this article is the introduction of the JS2Flutter framework and aims to outline it. The following series of articles will be completed:

JS2Flutter frame — rendering mechanism

Second, the right-most JS2Flutter framework — communication mechanism

3. Right-most JS2Flutter framework — implementation of animation and mini-game

4. Practical experience and achievements

Every business landing is a test of the framework, from the business practice, gradually discover the problems of the framework, promote the improvement of the framework. Business practice can not only test the framework, but also promote the birth of some tool chains outside the framework, gradually complete process automation, improve r&d efficiency, etc. With constant iteration and polishing, the JS2Flutter framework has been applied in dozens of activity requirements and mini-games since its birth. It has also withstood the test of heavy traffic and has been running stably online for nearly a year.

Here’s how the framework landed at the fifth anniversary event in 2019.

Far right 5th anniversary event — Android

Far right 5th anniversary event – iOS

Both ends of the experience are very similar to the native experience, very smooth. There is no significant performance degradation on iOS with the JS2Flutter framework.

5. Recent development of the industry

Currently known Flutter dynamic projects include Tencent’s open source MXFlutter[2] and Meituan’s Flap[3], both of which are active in the direction of Flutter. MXFlutter’s 2020 RoadMap shows that they have set clear goals in terms of developer-friendliness, starting to support business development with Dart, as well as usability improvements. Flap has more information than last year. It is a huge project, and it is not easy to build such a comprehensive system.

Although they all aim to make Flutter dynamic, different teams differ greatly in their implementation schemes.

6. Conclusion

At the beginning of the year, we were based on Flutter1.9.1+ Hotfix.6. Now we have upgraded to Flutter1.17.2. The JS2Flutter framework is the most technical precipitation on the way to explore the dynamic behavior of Flutter. It will be explained in detail in the following series of articles, and interested students can follow it.

7. References

[1]: The practice of Flutter dynamics in the right-most App www.infoq.cn/article/MIa…

[2] : MXFlutter github.com/mxflutter/m…

[3] : Meituan take-out Flutter mp.weixin.qq.com/s/wjEvtvexY dynamic practice…