Mobile Development 11 min read

Flutter Dynamic Template Rendering for Xianyu App

To meet Xianyu’s rapid UI change demands and curb its swelling Android package, the team built a Flutter‑specific dynamic template system that compiles Dart widget code into JSON, streams it to the client, reconstructs the widget tree at runtime, and maintains 55‑60 fps performance while planning further widget support and caching.

Xianyu Technology
Xianyu Technology
Xianyu Technology
Flutter Dynamic Template Rendering for Xianyu App

Background: Xianyu’s rapid business growth creates many UI modification and operation‑slot requests. With a two‑week release cycle, the team needs a way to iterate quickly and reduce the Android package size, which has nearly doubled since 2016. Dynamic delivery of UI is proposed as the solution.

Dynamic solutions on Android are mature (e.g., Google’s Android App Bundles), while iOS limits dynamic code. Therefore the team explored hybrid approaches (WebView, React Native, Weex) and finally a Flutter‑specific dynamic solution.

Initial research looked at Google’s CodePush. CodePush loads two files ( isolate_snapshot_data and isolate_snapshot_instr ) at runtime; by replacing them the app can be updated without a full reinstall. The official Flutter source already contains a prototype (see ResourceExtractor.java ), but it is still under development.

Dynamic templates are defined via a DSL that creates native Views (e.g., LuaViewSDK, Tangram‑iOS/Android). In Flutter this would require a Texture bridge, which is costly and performance‑heavy, so the team designed a custom solution that converts Dart files directly into JSON templates.

@override Widget build(BuildContext context) { return new Container( child: Column( children: [ new MenuTitleWidget(data), new Column( children: [ new MenuItemWidget(data.menus[0]), new MenuItemWidget(data.menus[1]), new MenuItemWidget(data.menus[2]), ], ), new Container( child: new HintItemWidget(data.hints[0]), ), ], ), ); }

Key points of the template format:

Every widget must be prefixed with new or const .

Data access starts with data , using [] for arrays and . for maps.

Compilation process uses the Dart Analyzer library. The source is parsed into a CompilationUnit AST, then transformed into a JSON structure of ConstructorNode objects:

class ConstructorNode { String constructorName; List argumentsList = []; Map arguments = {}; }

The parser walks the AST, extracts constructor names, arguments, and handles different expression types (named expressions, function expressions, property accesses, string interpolations, literals). Example of argument extraction:

for (Expression exp in argumentList.arguments) { if (exp is NamedExpression) { String name = ASTUtils.getNodeString(namedExp.name); if (name == 'children') continue; // handle function or property } // other cases omitted for brevity }

On the client side, the JSON template is received, parsed into a ConstructorNode tree, and recursively converted into a Flutter widget tree. Parameters are stored in WidgetCreateParam :

class WidgetCreateParam { String constructorName; dynamic context; Map arguments = {}; List argumentsList = []; dynamic data; }

Event handling is achieved by mapping an actionName (e.g., OpenURL ) to a runtime handler via TeslaEventManager . Arguments are resolved from the data model using a key‑path lookup before invoking the handler.

Performance: After enabling two dynamic cards on the “My Page” screen, frame rates remained stable at 55‑60 fps over a half‑month period, indicating that the dynamic rendering does not noticeably degrade UI smoothness.

Future plans include extending the system to support more widget types, caching identical widgets to reduce parsing overhead, adding error‑tracking in the bridge and native layers, and integrating UI2Code to automatically generate Dart templates from design drafts.

DartFluttermobile developmentcode generationtemplatedynamic rendering
Xianyu Technology
Written by

Xianyu Technology

Official account of the Xianyu technology team

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.