How HarmonyOS 2.0 Renders UI with a Simplified Vue‑like JavaScript Stack
This article dissects HarmonyOS 2.0's embedded GUI stack, explaining its three abstraction layers—JS framework, JS engine/runtime, and graphics rendering—while detailing the underlying open‑source components, custom C++ integrations, performance trade‑offs, and practical code examples for developers.
Overview
HarmonyOS 2.0 adopts JavaScript as the primary language for IoT UI development, allowing developers to write Vue‑style component logic that is rendered on embedded devices such as smart watches. The GUI stack is organized into three abstraction layers: a simplified JS framework, a lightweight JS engine/runtime, and a graphics rendering layer.
JS Framework Layer
The top‑most layer behaves like a heavily trimmed Vue framework. UI is described with an XML‑like markup (HML) and a corresponding JavaScript module. For example, a simple component can be written as:
// hello.js
export default {
data: {
hello: 'PPT'
},
boil() {
this.hello = 'nuclear weapon';
}
}When the user clicks the text, the boil method runs and changes the displayed value. Implementing this behavior requires four mechanisms:
XML preprocessing that converts HML attributes (e.g., onclick) into JavaScript object fields using an existing NPM package.
Event registration and dispatch, which are implemented in C++ and expose native callbacks to the JS objects.
A data‑watching system built on Object.defineProperty that triggers callbacks when this.hello changes.
UI updates performed by the ViewModel’s JS callbacks, which call native C++ methods to modify the rendered component.
The only pure‑JS feature that remains is a watchable ViewModel located in the ace_lite_jsfwk repository (files core/index.js, observer.js, subject.js).
JS Engine & Runtime Layer
The runtime bridges the ECMA‑262‑compliant engine with platform‑specific APIs. HarmonyOS 2.0 uses the embedded JerryScript engine, originally developed by Samsung. Each XML component tag (e.g., TextComponent, DivComponent) maps to a C++ class bound to JerryScript.
Built‑in modules prefixed with @system expose platform capabilities such as routing, audio, and file access (see ohos_module_config.h). The routing implementation differs from typical web routers; a call to router.replace triggers C++ code that loads a new page’s JS, creates a new state machine, evaluates the script, attaches the resulting ViewModel, and destroys the previous one. This process resembles a full page refresh rather than a lightweight SPA navigation.
Performance comparison (QuickJS benchmark) shows JerryScript lagging behind QuickJS, Hermes, and especially V8 with JIT, making it suitable only for low‑end devices.
Graphics Rendering Layer
The graphics layer lives in the graphic_lite repository. It provides a C++ UIView base class with virtual methods such as OnClick, OnLongPress, and OnDrag. Concrete UI components inherit from UIView and are driven by the JS runtime.
Two API styles are offered:
An immediate‑mode “Canvas” style where drawing commands ( DrawLine, DrawCurve, DrawText, etc.) are issued directly.
A retained‑mode “DOM” style where component trees are maintained.
Basic UI features include a simple RecycleView, a minimal Flex layout, and an invalidate‑based dirty‑region update system.
Bitmap handling relies on libpng and libjpeg. Text rendering uses open‑source libraries harfbuzz (glyph positioning), freetype (glyph rasterization), and icu (Unicode handling).
Example of a cubic‑bezier drawing routine:
void DrawCurve::DrawCubicBezier(const Point& start, const Point& control1, const Point& control2, const Point& end, const Rect& mask, int16_t width, const ColorType& color, OpacityType opacity) {
if (width == 0 || opacity == OPA_TRANSPARENT) return;
Point prePoint = start;
for (int16_t t = 1; t <= INTERPOLATION_RANGE; ++t) {
Point point;
point.x = Interpolation::GetBezierInterpolation(t, start.x, control1.x, control2.x, end.x);
point.y = Interpolation::GetBezierInterpolation(t, start.y, control1.y, control2.y, end.y);
if (prePoint.x == point.x && prePoint.y == point.y) continue;
DrawLine::Draw(prePoint, point, mask, width, color, opacity);
prePoint = point;
}
}The algorithm samples a configurable number of points (default 1000) and writes pixel data directly to the framebuffer.
Assessment
Subjective comments apply only to the current GUI implementation of HarmonyOS 2.0.
Strengths
Pragmatic, readable code that can be understood by developers familiar with mainstream hybrid frameworks.
No WebView wrapper; layout and rendering are native.
Requires only basic computer‑science knowledge to grasp.
Weaknesses
JS framework lacks component communication (props/emit), custom component definition, and advanced state management.
Engine supports only ES5.1; cannot run modern frameworks like Vue 3 that rely on Proxy. Performance is insufficient for medium‑to‑large JS applications.
No DOM‑style API exposure, limiting portability.
Graphics layer provides only a minimal GPU‑accelerated fill operation; no SVG, rich‑text, or full Canvas feature set.
Overall, the stack is well‑suited for embedded devices and simple “mini‑program” scenarios, but it falls far short of the capabilities of modern desktop browsers or mobile OS GUI frameworks. Substantial engineering effort would be required to adapt it for complex, high‑performance applications.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
IT Architects Alliance
Discussion and exchange on system, internet, large‑scale distributed, high‑availability, and high‑performance architectures, as well as big data, machine learning, AI, and architecture adjustments with internet technologies. Includes real‑world large‑scale architecture case studies. Open to architects who have ideas and enjoy sharing.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
