On November 23, byte technique salon | Flutter special technology End of the back art space in Beijing. We invited Huihui Yuan, Bytedance mobile Platform division’s Flutter architect, Justin McCandless, Google’s Flutter team engineer, Mengyun Li, Bytedance mobile Platform Division’s Flutter senior engineer, And Shubin Wang, Alibaba’s senior technology expert, to share their ideas with us.

The following is the precipitation of the theme shared by Alibaba senior technical expert Wang Shubin, “Idle fish Flutter Architecture Evolution and Practice”.

Outline of speech content:

  1. Why do idle fish choose Flutter
  2. The architecture and evolution of idle fish
  3. Review and Outlook

Today, the main content to share is the evolution of Flutter for one and a half years. I hope that there will be a certain stage and a certain scene that will fit with everyone and give us some inspiration and discussion.

Personal introduction

First, I would like to introduce myself. I am the person in charge of the structure of Xianyu. I joined Ali in 2009, which was the year when Taobao achieved the revenue balance for the first time and also the year of the first Double 11. I made an online analysis system and marketing system for tens of billions of data of merchants, and then used wireless. In the era of wireless, I made a project of 0-1 geographic fence and LBS wireless characteristics on mobile shopping.

Xianyu was founded in 2014. I came to Xianyu in 2015 and experienced the development of Xianyu from its early stage to the present stage of over 20 million DAUs. In the past four years, I have seen the rise of Xianyu like this. When the team size reached a certain level, I took charge of the structure of Idle Fish to adapt to its rapid development.

Why do idle fish choose Flutter?

Flutter is not the most perfect frame. There is no best frame but the most suitable one. What is the situation that makes idle fish choose Flutter?

Idle fish is behind the rapid development of THE C2C market

The big business context is this. First of all, Idle fish is a C2C trading market. With the continuous enrichment of online shopping goods in China, there are more and more idle goods in the society, and such a stock market has emerged. How large is the market scale? From the perspective of idle fish, in the 2019 fiscal year, more than 60 million users released their idle products, and the number is still growing, to now there are 1 million people to release more than 2 million products every day. Then, because it is a C2C peer-to-peer transaction, such users will form more interactions and community attributes. It can be seen that more than 1.3 million fish ponds have been deposited in Xianyu, forming such communities. This is a big background, is the high-speed development of the stock market.

The business characteristics of xianyu client side

What are the end – side business characteristics? There are several characteristics:

  1. Business mind. Xianyu is an independent business mind, which urges us to invest the main development force in Xianyu APP. There are some external scenes, such as online shopping, Alipay or external scenes, which are a small number of pages.

  2. High percentage of Apple users. Xianyu is characterized by a high proportion of Apple users. This feature led to extreme design requirements at the early stage. The design requirements at both ends were consistent and based on Apple design. At this time, students who are engaged in Android development can imagine the pain of Android.

  3. C2C, community business background. This resulted in a lot of interaction, product photos and video requirements, and a lot of big business attempts during the rapid growth period.

The end technology choice of idle fish

These features led us to make the big decision to move to Flutter at the end of 2017. I tried Weex in the middle.

Now the technology stack of idle fish is like this: the product page of activity class and outcast class is developed with H5, small program and Weex; The main link and productized pages are developed with Flutter, which has more than 80% coverage in Xianyu. All the students from Native development have switched to Flutter development. These are technical factors, in addition to the team is also very important factors, Native students can write Flutter conversion faster, idle fish have Native staff basis, so they are determined to make Flutter in depth.

The architecture and evolution of idle fish

This is the architecture that has evolved to the present: from project management, packaging platforms, continuous integration to automated testing; The middle includes page components, Native mixing, audio and video components, etc. A little further up are containers that host the business and allow the business to sink its business processes (Dynamic and Serverless).

Evolution of the Idle Fish architecture

How did this architecture evolve? There are about three stages: first, mixed development, introduction. Second, scale, development period, more and more pages and staff input, will face some new problems. Third, integration and new exploration. After maturity, we will consider how to explore the next step. In the past, we only improved efficiency from the perspective of both ends, but now we also consider the cloud (Server), and consider the space for further improvement of efficiency from the perspective of cloud integration.

I. Mixed development and introduction period

What do introductory periods usually do? It took 3-4 months from the beginning of the Flutter to the final launch of the Flutter, because there were few lessons from the past. However, this year, a start-up company in Hangzhou decided to use Flutter and launched it in about a month. We can see that the cost of Flutter has come down during the introduction period. Although this has been reduced, the biggest work during the introduction period will be in the mix development area, that is, how to mix Flutter into your existing APP, unless you are developing a new pure Flutter APP.

Mixed development may include:

  • The first, the hybrid stack, which is unavoidable, is how to mix pages together. The hybrid stack is the Boost in this architecture diagram, which is open source.

  • The second, engineering, links from code management to continuous integration, packaging, monitoring, and high availability.

  • The third is the integration of audio and video and resources, which mainly considers the reuse of high-performance pictures and video components and Native.

1. Mixed stack concerns

(1) Single page stack and multi-page stack. From a Native perspective, when a new Flutter page is opened, should the page be opened in the new Activity (Android for example), or should the Flutter page be switched back and forth within the same Activity? If every Flutter page is attached to a new Activity, the design of multiple page stacks counts. The reverse is a single page stack. Which is better? If you want to work well with Native stacks and have exactly the same logic and order, then multi-page stacks are the best choice. So what is a single page stack suitable for? For example, when a Flutter page pops up a float layer or Dialog, using navigator. push directly inside a Flutter can achieve the desired effect, but otherwise, most scenarios require multiple page stacks. Flutter_boost supports both.

(2) Single engine and multiple engines. The multiple page stacks mentioned above involve the problem that every Flutter page is attached to a new Activity (take Android as an example). Should the Flutter engines of these pages use the same engine or multiple engines? This is also an important consideration for hybrid stacks. Intuitively, to accommodate multiple page stacks, multiple engines should be used, one for each page is the easiest, but the biggest problem is memory explosion. Although the official wants to reuse this engine in depth to make the engine lightweight, it is not Ready yet. Therefore, in terms of single and multiple engines, the current scheme we use is still a single engine scheme. The advantage of the single-engine solution is the memory savings, as all the Flutter is in one engine.

(3) Although the single Flutter engine solves the problem of memory inflation, because the page life cycle of the stack inside the engine is different from that of the external Native stack, using a single Flutter engine is equivalent to moving the Flutter page between the Native pages. The life cycle of a Native should be exactly the same as the life cycle of a Flutter. If the life cycle of a Flutter is not correct, there will be all kinds of strange problems such as transition blank screen, missing buried points, and improper page destruction. For a single-engine design, implementing the basic flow is usually fine, but the most important thing is that there are a lot of details that need to be carefully addressed. For this, see Flutter_boost.

2. Engineering problems of mixed development

This problem is usually caused by students who originally had a Native but now have a Flutter to develop together. This question was also raised by a student just now. How should the project be done? Is a Flutter package Native, or a Flutter package Native? These are two ways of thinking. The standard Flutter is to attach android and iOS projects to a Flutter in such a way that Flutter packages Native. There is also another way to add Flutter to Native, which can be reversed. Xianyu made a flutter_boot tool with this idea, which has been open source and can be referred to if you are interested.

3. Integration of audio and video and resources

In the Native period, there were mature image libraries and mature video components for filters, codec optimization and other optimizations. These components had to be reused on Flutter. If the official default mode was used, performance problems would be found in the production environment.

This is about video reuse scheme, the first official direct to the default implementation, in the absence of format conversion is not a problem, but when format conversion is required, performance will be a problem. The first option is to extract the Texture into Java or the Buffer object of the Flutter runtime. Each frame is channeled to the Flutter and then pasted to the Texture. The disadvantage of this method is that there is a read, a write process, the performance is not optimal. According to our test, 720P video on iPhone 7, this scheme consumes 5-6ms more per frame on average.

Later, we tried two schemes to improve the performance. The first scheme is like “New Scheme 1”, which tries to reuse the Texture of the Native side with the Texture of the Flutter side and directly pass the Texture ID. This advantage is that there is no up-dump process of memory. The downside of this approach is that you need to change the code of the Flutter and make Patch. There is also a better solution, which we found later. This solution does not need to make Patch, but can directly reuse the Surface Texture mechanism. If the Surface Texture is the same in Native and Flutter side, it can be reused. It’s better to do it this way.

Ii. Scale

As projects become more complex and pages become more numerous, it is important to focus on how to decouple people and modules. Larger teams have more parallel development, and there are several teams that need to develop in parallel, not just one large group. Also, focus on code standardization.

Speaking of decoupling, there are roughly two levels of decoupling: one is the decoupling of “Card”, where each line of a long page is a business component Card, and cards are kept as interdependent as possible between them. Another part is the internal decoupling of Card, mainly to solve the problem of UI, logic and data separation. There is a Redux solution to this problem in the industry. Fish_redux is designed to add the decoupling ability between component cards to Redux, that is, to split a large page into multiple components. Components can also be decoupled from each other.

Another consideration in the scale phase is high availability. Flutter has a feature that the Crash of the whole APP caused by Flutter is very small. A more effective way is to monitor its abnormality, which requires clustering and information clipping at this stage. In addition, it is necessary to monitor the page FPS, interaction duration and so on.

In addition, in terms of CI and automated testing, there are also some things to be done in the scale phase. Some of the original automated tests cannot be applied to Flutter, such as Instrumentation and UiAutomator based test solutions. Only monkey-based ones can be used directly.

Here’s a closer look at the AOP technique used for decoupling. AOP is a means of breaking in. It’s easy in JAVA and OC, but there’s no proven solution in Dart. One solution to AOP is based on code generation, and another is to modify it in Dill, the language in between Dart and the final product.

What’s the idea here? There is an APP project and you want to add some functionality to it. This will be cut in the AOP way so that the original APP project will not be aware of it. The solution is to have the aOP-project Main refer to the Main of the app-project. Choose to generate aop.dill when packaging, containing all the code for both projects, and then through AspectD processing, weaving together the two project aspects to become the final product.

How to change this aop.dill? Flutter has a nice design for compilation. It provides conversion capabilities that allow you to perform your own conversion on a syntax object once it has been acquired in the compilation process. Based on this principle, read the tree of syntactical code, and then iterate over it, parsing the AOP annotations in the project and weaving them together. When doing AOP, consider whether, for example, you want to insert an interface outside of foo, the first and last lines inside foo, or even a row in the middle of foo. These are different AOP weaving actions, with different annotations for each operation.

Iii. Integration

The first concept, dynamic templates, is used when the business layer wants to do business process sinking. For example, there may be a lot of components in a transaction link, such as customizable preferential module, logistics module, commodity information module, etc., which can precipitate this process into a middle stage, so that the upper businesses can reuse and assemble, and make their own extension points in the process of this trunk. One solution is to allow Flutter to support templating by using dynamic templates.

The second concept is the Serverless framework, which aligns the server-side business layer code with the client-side code.

The above is the concept of an integrated end-to-end, the bottom part is the server-side container, and the important infrastructure is the FaaS platform and ServiceMesh. We do not need to build the standard Faas by ourselves, both on the cloud and inside Ali. What we need to do is to make Dart run on Faas and make a Dart Runtime container that conforms to the Faas specification. What are the core problems to solve? One is to make the Runtime adaptable to different Faas platforms, which is decoupled enough. The Dart language is bound to run into a Java ecosystem or a Java ecosystem, so how to deploy these heterogeneous services is a language independence issue. The idea is similar to that of Servicemesh, which uses Sidecar to solve language independence problems.

In the middle is the channel service Response framework. This framework is mainly channel layer abstraction. Why channel layer abstraction? Originally based on the wireless gateway interface, now based on Faas, you can regard this Faas as a local interface to call, and even the function on the Faas as the local function, so to call.

The evolution process of integration: The first step is the process of logic down. The original end-to-end logic is written into the Faas layer, which is the process of logic down. The template mentioned in the second step belongs to SSR category and belongs to the process of moving the rendering down. Finally, there is the vision, which automates UI generation. Integration of business before use may have many doubts, exactly this kind of development pattern we can not accept, can really bring efficiency has increased, but this out later, we have several business based on this, the effect is very good, originally a very heavy cloud logic normalization, such as the logical order page, place the order with the client is favorable, Component linkage, there is a very heavy logic side, the server side is also very heavy logic, now the business students order the integration of the two logic together, when they go to Faas to solve the logic, it will become much better maintainability.

Some students may wonder how to solve the problem of on-end state in FaaS after integration.

The solution to this problem has several ideas. First, for client programming, we use the framework to unify the local function and FaaS function to encapsulate the route, and only the case that needs to access the remote will route to the remote. In addition, based on Redux Action method to call FaaS, the Action can first transmit the complete State of the client to FaaS, FaaS function can know the complete State of the client. Some of the side effects are increased number of requests, so be careful in this particular case.

Another important aspect of integration is the engineering of uniformity, so that developing FaaS is like writing client-side code in local engineering. There is open source software Serverless Framework that can be reused in engineering normalization industry. Amazon and Google cloud have CLI tool components in Faas layer. It is easier to get through engineering integration based on open source products.

Review and Outlook

Just to recap what we’re going to talk about today:

Firstly, the factors of Flutter selection are given for our reference. The following business features of Flutter include: independent APP, two-end consistency requirement, high proportion of Apple users; The APP is dominated by productized pages. Team composition is also an important factor.

Second, the evolution process of Xianyu architecture, from the introduction stage, to the development stage, to the exploration of integration, issues and key technical points to be considered in each stage.

Finally, looking ahead to what’s next:

The integration that Flutter and Faas just talked about has just started. There are some typical business scenarios that have been implemented, but they have not been rolled out on a large scale. UI2code attempt. In addition, we want to open up Flutter’s infrastructure and basic components to allow very large apps to use it. Finally, the community ecology of Flutter needs to be built and improved together.

Q&A

Question: I’m an iOS developer currently working on cross-platform. Cross-platform developers all know that Alibaba has a well-known Weex. You also mentioned that Weex is the main business of Xianyu in 2016. We also do Weex related work, which can achieve multi-terminal isomism. From Weex more in line with the trend of large front-end, integration, Weex in the cross-platform and the original platform have considerable performance. My question is, as an excellent cross-platform engine owned by Alibaba, what happened when you decided to fully embrace Flutter? Can give us a better reference.

Answer: This question is about the scene. Weex is a triangle with Flutter in terms of cross-terminal, dynamic and performance. For example, you just said that Weex is very good and can solve these three problems perfectly. However, the key advantage of Flutter is better performance than Weex. Weex’s advantage is its front-end ecology and container universality and its dynamic nature. In the final analysis is the scene problem, idle fish 80% is the main link scene, more is the performance of the consideration, only 20% is belongs to the external activity class, this part we use Weex, H5, small program to do, the main link or higher performance choice. The hangzhou startup example is also like this. It chose between RN and Flutter and finally landed on Flutter. Indeed we have this consideration, or to see their own scene to take which aspect.


Question: I saw UI2code on the Official account of Xianyu before. I would like to see your latest progress. What is the actual usage rate of UI2code on the pages of Xianyu APP?

Answer: We have our own intrapreneural APP, a brand new APP, which is done with UI2Code, and it works very well. Personally, I think the current technical level of UI2code is suitable for making a new APP or a new page. The biggest problem with old pages is the problem of modification and merging. So UI2code is very useful for the new APP page, because that’s all generated with this. The current technique is more suitable for such scenarios.


Q: You are probably the first to use Weex. We also have Weex in our APP. I would like to ask if you have the relevant technology for Weex compatibility with Flutter? For example, I had some business done by Weex before, but now I want to do it in Flutter. Is there any relevant technical research?

Answer: These two calls are actually independent of each other. Weex renders to Native controls just as standard Native does to Flutter. But Weex, if it eventually degrades to a Web View, becomes a problem of Web View and Flutter. They are actually compatible. Now it is ok to use a Web View on a Flutter. So it all comes down to the question of the relationship between Native and Flutter. If you want to associate a control pole with a Flutter, for example, Weex controls can interact with Flutter controls. Both of them can appear on the same page. This is difficult and currently impossible. Furthermore, there is no good way to make Flutter as dynamic as Weex.


Question: Is the Faas layer equivalent to the process of converting the Server database Model into the front-end View Model? Another question, is there a componentized solution for Flutter client co-development? Or is there something else? For example, what is the solution for debugging during development? Flutter has multiple business lines developing an APP at the same time. There are many independent components. How is Flutter debugged during development? For example, running in the free fish shell APP, what kind of way can you run?

Answer: Does Faas refer to the problem of leaking server DB data to the client? In terms of business development layering, there are client, intermediate business glue layer, and domain layer. The glue layer is to take the interface of each domain and assemble it into the data required by the page and return it to the client. What FaaS does is this layer, the glue layer.

Question (continued) : Which end of the domain is maintained by the interface or the Server? Finally, the output is more like the data output by the Server. If the client needs to configure something, it needs to encapsulate another layer on this layer and assemble another layer of the form that the client needs?

Answer: The FaaS layer is the glue layer mentioned above. Before there was no FaaS, this layer was written by the server, but now it is written by the client using FaaS. The Faas layer can be understood as the BFF layer at the front end, but it is actually more than THE BFF layer. Faas solves the smokestack logic. Faas has less horizontal dependencies. The difference of domain layer is that it has a lot of horizontal dependence between domains and uses a lot of book data storage, so the model is complex, so it is not suitable for FaaS. It is not used in FaaS yet.

Question (continued) : How to determine whether Faas is running on the Server or the client?

Answer: Faas is actually on the Server side, but there is an action-based client framework that allows both the local logic and Faas logic to be written as a function during client development. The idea is to put a comment on the Faas function, and the rest is the same, in this direction.


Q: I often follow some technical articles about idle fish. You just raised two points, noUI and dynamic template delivery. When writing pages in Flutter, refer to the Website of Flutter Design, which dynamically drags and drags all the components to generate static templates. Whether the Flutter trend can evolve to focus only on data sets and business logic, leaving the rest to the toolset or tools. This greatly frees up the page writing productivity of Flutter. Do you have this consideration? Or provide such a compilation tool for the community to use?

Answer: This actually works internally, but it’s not publicly available yet. The way you are talking about is probably more instrumentalized, using tools to generate such a page whose code is also the code of Flutter. UI2code that has intersection in this way is UI2code. It is true that the Flutter code is generated directly, but it is not completely generated by taking an image. There is also the drag process as you mentioned, making some modifications, setting simple properties, and then generating the Flutte page code.

More wonderful sharing

Flutter salon review | cross-platform technology trends and bytes to beat Flutter architecture practice

Review | how to cut close to 50% of the Flutter Flutter salon package volume

Flutter salon review | Custom Widgets in a Flutter

Shanghai salon review | core of bytes to beat on the Spark SQL optimization practice

Bytedance Technology Salon

Bytedance Technology Salon is a technical exchange activity sponsored by Bytedance Institute of Technology and co-sponsored by Bytedance Institute of Technology and Nuggets Technology Community.

Bytedance Technology Salon invites technical experts from Bytedance and Internet companies in the industry to share hot technical topics and front-line practical experience, covering technical fields such as architecture, big data, front-end, testing, operation and maintenance, algorithms and systems.

Bytedance Technology Salon aims to provide an open and free exchange and learning platform for technical talents, helping them learn and grow, and keep advancing.


Welcome to Bytedance Technical Team