Flutter Dev Podcast with CTO Meduza Boris Goryachev: the main thing about the Meduz application and media development

Not every day there is a chance to discuss a Flutter project with more than 100 thousand DAUs in the application. The new Meduza app is just such a project. At the moment, this is the most popular and discussed Flutter application in Russian stores. We invited Boris Goryachev to Flutter dev podcastto find out why the team decided to leave the native to the cross-platform and chose Flutter. Below we have collected the most interesting: attempts to make friends with the native web, the first cross-platform experience, media development features, font games, and the complexities of working with WebView / Backend Driven UI.



“Idea, site, two applications”. Initially, at the launch of Meduza in 2014, the team relied on a convenient mobile application, the site was as simple as possible. As it turned out later, the audience at that moment was not yet ready to give up news on the web. The application gained its audience, but in absolute numbers was inferior to the web (both to the mobile site and the desktop). Therefore, it was decided to improve the technical equipment of the site.

Audience Meduza. In the internal metrics, Meduza clearly distinguishes between mobile and desktop users of the site, as well as users of the application. The latter are the least, but their activity is significantly higher than in all other categories. This is the core of the Meduza audience.

What was the first version of the application?. Meduza started in just a couple of months. The bet was on beautiful content that was downloaded from the browser. The principle of creating media applications is the same for everyone: natively, the main and other distributing pages are done. When a person taps on the material, a WebView opens, in which various HTML, CSS and other modules are displayed.

“Has the development approach changed over time?”. No, the mechanics have remained the same: at first the native view, then the user “fails” in the WebView, in which it scrolls the content from the browser. This approach has its drawbacks. When the content is controlled by the browser, you have to pay a lot of attention to the communication between the native code and the web form. For example, to draw some kind of native component that will appear with a beautiful effect and follow the user. On this team filled a lot of cones.

“What were the problems in interacting web with native”. Web developers and native developers speak different languages. During development, there were problems with serialization, deserialization, Java crashed, because some wrong object came, the wrong structure, etc. There were also difficulties with embedding elements depending on the scroll position. For example, there is a WebView limited in height, which should integrate with a piece of native. You have to make a composition from an element that will scroll by itself, then it intercepts another scroll and so on.

When I first decided to discuss a cross-platform with a native team, I met with serious resistance. The arguments were standard: slowly, the performance is bad, there is no support for such and such a feature that we do not need now, but it will suddenly be needed in the future and so on. Perhaps they wanted to learn something new or just was comfortable with Java, Kotlin, etc. As a result, after some time we had to say goodbye to the native team

“Rendering Meduza content natively is like repeating the browser so that it works. Not the easiest task “. The team managed to transfer some of the materials to native rendering. For example, in the “Online” category, the material is filled in by the editor in real-time: after sending the information is immediately rendered on the reader’s screen. We did it all on the native. For example, a client receives dynamic data in a different format. The client must process them correctly and not fall. There were a lot of problems with the coordination of all the nuances – it was necessary to decide how to move on.

At that moment, the only thing I could do was backend apps. They showed what already ceased to work in the native. I’m like this: “Hey, now we are pushing crutches there.” For 2 years, they threw all sorts of different features into the backend, because there was no desire to update applications or find the right library.

“The first cross-platform experience – React Native”. Meduza has its entire frontend written in React. Boris wrote his first mobile prototype on React Native in a couple of weeks. The prototype worked fine: showed, rendered, imposed styles, etc. When the full development of the application on React Native began, new problems got out. For example, JavaScript on Android does not work as it does on iOS. There is valid JavaScript, it does not swear, but you open and see the void, and the problem is in JSX. There were also problems with tags that map into containers or text, but close somehow in a tricky way. At first, it seemed like there was a chance to fix all the bugs after the fact. But the farther, the more development stumbled on trifles.

The fact that native applications worked for these 2 years suggests that they were written really well. They withstood what few software can withstand. 2 years without updates is a serious period.

“They learned about Flutter on Google I / O in 2018, but decided to hold back”. We talked with Andrew Brogdan (Flutter). Meduza needed a backend driven architecture for the API to dictate what would happen in the UI. The key point is having a WebView that integrates into the widget tree. The media application needs to show the user the video from the social. networks and YouTube. Unfortunately, at that time, Flutter did not have WebView support, and the cross-platform was put on hold. Native applications have lived without support for almost 2 years. During this time, there were many different edits on the backend side, but the applications worked more or less stable.

Hello, I’m the technical director: “Do we have two applications that people use? Well, they will be without support. ” And in the end, they lived without support for almost 2 years, but used them.

“In December 2018, Google added the WebView library to Flutter and the development of a new Meduza application began.”. It took almost a year only because the team several times invented the entire application anew. Screens, concept changed, experiments were conducted. Flutter allows you to quickly make interfaces, and thanks to hot reload, designers could quickly comment on changes and make edits, many edits. In total, the application code and the backend took no more than 6 months. At the same time, Boris was not completely focused on Flutter, but was distracted by the development and launch of other projects.

Media is a type of human activity where everything constantly goes wrong. Something is constantly happening in the world: the journalist is being held up by the authorities, the regime is changing, the COVID-19 pandemic is starting, etc. Because of this, the development of services is hindered, meetings are postponed, and creative suffers.

“Features of the development of media applications in Russia”. In our country, there are very few media developers, there are practically no colleagues in the workshop who could learn from and borrow the best practices. Programmers in this area think differently. Where an ordinary specialist sees simple text, media programmers notice paragraphs without typography, a short minus instead of a long dash, quotation marks “paws” instead of “Christmas trees” and so on. Such details distinguish a serious publication from a random site on the Internet.

People in the media are constantly “tired of the agenda.” Probably, plus or minus all people in Meduza suffer from this. Every day you are immersed in the agenda, which is usually not very pleasant. And under these conditions, various technical problems occur. Then Google changed something in the indexes, the Facebook or VKontakte API refused, and they wrote about it in Change Log.

“The ability to fine-tune fonts in Flutter was very useful for Meduza.. The publication has long been using the same pair of fonts (Proxima Nova and PF Regal), but designers often make small changes to them, which were very difficult to support at home. The developers did not want to touch the default components, did not see the changes on a number of devices and so on.

A. Lebedev did not appreciate the new application. Well, I did not like it and did not like it. Comments are valid, at the moment I have not yet been able to fix only one moment. In the application, the footnotes are highlighted in blue, and on CSS the stroke effect was more interesting. As a result, they came to a compromise with the designer, which Artemy did not appreciate. Well, not rated, and not rated.

“Are there plans to scale a team or one Flutter developer enough to write media applications”. The framework really allows you to write a project in solo. In the case of Meduza, the “block API” is used, i.e. the backend dictates the UI what to show. The bottom line is that any Meduza material is an array of typed blocks. As a constructor, from which you can assemble paragraphs, but inside there will be a media player or something else. Plus or minus any block can be displayed in any configuration. The whole application is built on this. At one point, you can take and replace something at any point in the application: send other text, indents, colors, etc. through the backend.

“Application development plans: optimization and support of new formats before they appear in production”. In the near future, optimization of performance and podcasts for older devices. In the future – to support the launch of new formats exclusively by the backend. That is, so that you can make any changes and features without changes on the Flutter side.

In this case, formats mean types of publications: news, cards, long-reads, etc. All of them are actively used by the editors. The main pain since the native was the support of new formats in the application. In the old Webview was used, and there were always situations when the editors came up with a cool format, it was supported on the web, but was not supported by the application. I had to wait until users were updated, and only after that new materials began to be displayed to users on a smartphone. To avoid this, the application should go ahead of the product plan and support features that are not yet in production. So people will have time to update and everything will be realized plus or minus at the same time.

“At Flutter, it was possible to make the process of launching new features as painless as possible”. In Meduza, the process is as follows. The backend programmer writes the API, opens the application on the phone / simulator. Then he checks that everything matches, and goes on to make the application. No need to write and customize new widgets. Such a scheme has trade-off for performance and trade-off for readability of the code. When the logic of one component or block becomes serious enough, they simply make a widget out of it and the block becomes a new entity. For example, a podcast player was implemented that way.

“Which part of the application is rendered on Flutter, and which part through WebView”. Most elements are rendered on Flutter: containers, texts, typography. The exceptions are embed elements (Twitter, YouTube, Facebook, TikTok) and games that are fully made through WebView. For example, tests for Meduza or custom games with cars, etc. All of them are done from scratch. It is important to know that the WebView in Android on some phones crashes if the WebView is higher in height than the ViewPort device. In the future, get away from WebView in favor of something more “Flutter-native”, render the same Twitter using data from JSON.

“What are your plans for podcasts, how are you planning to improve”. Initially, the audioplayers plugin was used, but then it was decided to switch to a bunch of just_audio and audio_service. The player had no problems with the processes, and the second library supported the notifications needed for podcasts. For example, you turn on something to play, and a module comes out on top where you can tap on stop or seek audio, etc. The most difficult thing was to synchronize the UI with something that happens in a separate thread, and also to realize the moment with a curtain and swipe.

“An application in terms of architecture or why we stopped at Provider”. To maintain the work of such a structure, fewer actions are required: no infinite constants and functions that mutated global states’s and so on. Of the options considered, the logic of the provider approached Meduza the most. There are 8 of them in the application. For example, one is responsible for the user’s bookmarks, the other is for synchronizing read history and podcasts. With its help, they remember the position at which the listener stopped. So he can return on another device and listen to the podcast there. Another provider is responsible for the topics, substitutes where necessary colors are needed or gives them where necessary in the UI.

“Because of what, the application shows different performance and rendering of the UI on Android and iOS”. The first problem was the initial data fetching, which was implemented through the Provider, but was not involved in Compute. There are quite a few operations: go for the data in the API, pick up a fairly large JSON, process it, convert it to data and push the result into the model. Because of what, at the start of the application, we observe a drawdown of FPS.

Another problem is the integration of ads, from which the FPS drawdown on iOS occurs. On Android, there is simply no advertising. When choosing libraries for the application, we stopped at the official AdMob. But, as it turned out, you can’t integrate a banner into the widget tree there. The developers do not want to use banners on top of the widget tree or fullscreen advertising, as this will greatly affect readers’ loyalty.

The Meduza team turned to Google and hit the beta test, where the desired ad format on iOS is already being tested. In the current version, when the transition is animated, AdMob ads are loaded. The benchmark shows that there is a performance drawdown, but not everywhere and not always. We are waiting for a fix from the Flutter team. The moral is simple: if something needs to be removed from Main Isolate, use Compute.

As a result, despite all the difficulties, Flutter fully met the expectations of the Meduza team. Look for the full version of the podcast here and ask questions in the comments!

Similar Posts

Leave a Reply

Your email address will not be published. Required fields are marked *