ホームページ > ウェブフロントエンド > jsチュートリアル > Honmeng JavaScript GUI テクノロジー スタックを見てみましょう

Honmeng JavaScript GUI テクノロジー スタックを見てみましょう

coldplay.xixi
リリース: 2020-09-14 13:28:55
転載
2745 人が閲覧しました
<p>Honmeng JavaScript GUI テクノロジー スタックを見てみましょう

<p>関連する学習の推奨事項: JavaScript ビデオ チュートリアル

<p>ご存知のとおり、新しくオープン ソースになった「Hongmeng 2.0」アプリケーション開発には IoT フレームワーク言語として JavaScript を使用します。これは、SpaceX の離陸後、JavaScript が再びニュース ネットワーク レベルでホットな話題になったことを示しています。このような良い機会に陰陽だけを使用するのは残念です。一般的な科学として、この記事では虫眼鏡を使ってコードの欠陥を見つけて欠陥を見つけるのではなく、その代わりに、それがサポートする GUI が何であるかを一般的な方法で説明したいと考えています。コンピューターの基本について一般的に理解している限り、この記事を読むのに問題はありません。

<p>「Hongmeng 2.0」では、開発者は JavaScript ビジネス ロジックを Vue コンポーネントの形式で記述するだけで済み、スマート ウォッチなどの組み込みハードウェア上の UI インターフェイスにレンダリングできることはすでにわかっています。このプロセスにはどのコア モジュールが関与する必要がありますか?これらのモジュールのうち、どれが自社開発で、どれが既成のオープンソース プロジェクトを使用していますか?これは、上から下に 3 つの抽象的なレイヤーに分割されて紹介されています:

  • JS フレームワーク レイヤー。これは、大幅に簡素化された Vue スタイルの JavaScript フレームワークとして理解できます
  • JS エンジンとランタイム レイヤー、大幅に簡略化された WebKit スタイルのランタイムとして理解できます
  • グラフィック レンダリング レイヤー、大幅に簡素化された Skia-スタイル グラフィックス描画ライブラリ
<p>これら 3 つの抽象化レイヤーは、組み込みハードウェア用の GUI テクノロジ スタックを形成します。 「不透明/理解不能」と叫ぶ多くの世論とは異なり、少なくとも GUI 部分については、現在の主流のハイブリッド クロスエンド ソリューションや JS ランタイム開発に慣れ親しんでいる中国の第一線の開発者であれば、誰でも簡単に開発できると個人的には考えています。ソースコードから始めて、それを理解しましょう。レイヤーごとに解釈と分析を行ってみましょう。

JS フレームワーク レイヤー

<p>トップレベルの観点から見ると、「Hongmeng 2.0」を使用してダイナミック テキストをレンダリングしたい場合は、次の HML (XML のような) を記述するだけで済みます。フォーマット コード:

<!-- hello.hml --><text onclick="boil">{{hello}}</text>复制代码
ログイン後にコピー
<p>次に、同じレベルのディレクトリに次のような JavaScript を記述します:

// hello.jsexport default {  data: {    hello: 'PPT'
  },
  boil() {    this.hello = '核武器';
  }
}复制代码
ログイン後にコピー
<p> このようにして、テキストがクリックされている限り、boil メソッドが実行されます。 PPT核兵器 に変更するために呼び出されます。

<p>この裏で何が起こったのでしょうか? Vue 2.0 に精通している学生は、次のことをすぐに考えるはずです。

  • では、XML を JS のネストされた関数構造に変換するために、XML の前処理メカニズムが必要です。この方法では、実行時に単純な評価を行うだけで済み、JS を使用して XML 構造に準拠した UI を生成できます。
  • #onclick イベントがトリガーされたときに対応するコールバックを実行できるように、イベント メカニズムが必要です。
  • 値を
  • this.hello に割り当てるときに対応するコールバックを実行できるように、データ ハイジャック メカニズムが必要です。
  • コールバックで UI オブジェクト コントロールを更新できる必要があります。
これらのことはどのように達成されるのでしょうか?簡単に言うと、これは次のとおりです。 <p>

  • XML 前処理 は、既製の NPM オープン ソース パッケージに依存して、XML の onclick 属性を次のように変換します。 JS オブジェクトの属性フィールド。
  • イベントの登録とトリガーは C で直接実装されます。前の手順で取得した JS オブジェクトの onclick 属性がチェックされ、C に登録されます。これは、すべてのコンポーネントがネイティブであることと同等です。
  • データ ハイジャック メカニズム は JS で実装されており、Object.defineProperty に基づく ViewModel (サイズは数百行) です。
  • UI コントロールの更新は、ViewModel によって自動的に実行される JS コールバックで C のネイティブ メソッドを呼び出すことで実装されます。この部分は完全に暗黙的に行われ、document.createElement スタイルの標準化 API は公開されません。
一般的な JS フレームワークの多くの機能が C に直接実装されているため、GUI テクノロジ スタック全体は純粋な JavaScript を使用して実装されています (主に、ウェアハウス ## の下の <p>ace_lite_jsfwk を参照してください) #core/index.jsobserver.js、および subject.js)、これは関数を 1 つだけ持つことと同等です: #監視できる ViewModel。

<p>純粋な JS フレームワーク部分の実装の複雑さと品質については、客観的に見て、個人のアマチュア作品であれば、学校の採用面接で良いボーナスとして使用できます。

JS エンジンとランタイム層<p>

JS フレームワーク層を理解した後、「Hongmeng 2.0」は高度に単純化された Vue を C に深くカスタマイズすることを選択したと考えることも、次のように考えることもできます。これは、高度に簡素化された (そしてプライベートな) DOM の周りにサポートするフロントエンド フレームワークをしっかりと実装します。したがって、この GUI の原理をさらに調べたい場合は、その C 部分に入り、その JS エンジンとランタイム層の実装を理解する必要があります。

<p>JS エンジンとランタイムの違いと関係は何ですか? JS エンジンは通常、ECMA-262 仕様に準拠するだけでよく、「副作用」のあるプラットフォーム API は定義されていません。 setTimeout から document.getElementByIdconsole.logfs.readFile まで、実際の IO 操作を実行できるこれらの関数はすべてです。 「エンジン API とプラットフォーム API を一緒に接着する 」のランタイムによって提供される必要があります。ランタイム自体の原理は複雑ではありません。たとえば、私の個人的な記事「JS エンジンから JS ランタイムへ」では、既製の QuickJS エンジンを利用して自分でランタイムを構築する方法が説明されています。

<p>では、「Hongmeng 2.0」では JS ランタイムはどのように構築されているのでしょうか?いくつかの重要なポイントがあります:

  • JS エンジンは、Samsung が開発した組み込み JS エンジンである JerryScript を選択しました。
  • <text> および <p> の形式の各 XML タグ コンポーネントは、 などの JerryScript にバインドされた C コンポーネント クラスに対応します。 TextComponentpComponent など。
  • UI ネイティブ オブジェクトに加えて、JS には @system というプレフィックスが付いた一連の組み込みモジュールもあり、JS で利用可能なルーター / オーディオ / ファイルなどのプラットフォーム機能を提供します。 (ohos_module_config.hを参照してください)。
<p> ルーターについては、ここで特に言及する価値があります。これは、vue-router などの一般的な Web プラットフォーム ルーティングの実装原則とは大きく異なり、実行時に特別に深くカスタマイズされます (router_module.cppjs_router.cpp および # # を参照) #js_page_state_machine.cpp)。簡単に言えば、この「ルーティング」は次のように実装されます。

    JS でページを切り替える
  • router.replace ネイティブ メソッドを呼び出し、C を入力します。
  • C で、新しいページ URI パス (
  • pages/detail など) に従って新しいページ JS をロードし、新しいページ ステート マシン インスタンスを作成し、Init 状態に切り替えます。 。
  • 新しいステート マシンの Init プロセスで、JS エンジンを呼び出して新しいページの JS コードを評価し、新しいページの ViewModel を取得します。
  • ルート パラメーターを ViewModel に追加し、古いステート マシンとその上の JS オブジェクトを破棄します。
したがって、ここでのいわゆる「ルートの切り替え」は、実際には Web ブラウザの「更新ページ」に近いことがわかります。では、この JS ランタイムの機能はすでに WebKit レベルのブラウザ カーネルのベンチマークを行うことができると考えることができますか? <p>

もちろん、それはまだ遠いです。 WebKit と比較すると、HTML と CSS の解析はサポートされていません (どちらも開発段階で解析され、同じ実行効果で JS に変換されます)。また、リソースを継続的に動的に読み込み、解析し、実行するという課題もありません。ブラウザ (小さなプログラムは、いくつかのローカル静的 JS ファイルにすぎません)。組版、レイアウト、レンダリングに関しては、当然大きなギャップがありますが、これについては最後のセクションで説明します。 <p>

さらに、多くの学生は JerryScript エンジンに興味があると思います。このセクションは、この問題に関するいくつかの個人情報を共有して終わります。 <p>

JerryScript エンジンは、組み込みハードウェア向けに特別に実装された JS インタープリターであり、ES5.1 標準のみをサポートします。 QuickJS Benchmark では、パフォーマンスの比較結果を確認できます。 <p>

Honmeng JavaScript GUI テクノロジー スタックを見てみましょう
パフォーマンスの点では、JIT を使用しないエンジンでは JerryScript が大幅に劣っていることがわかります。 QuickJSとHermes用。 JIT をオンにした V8 と比較すると、さらに 2 桁遅くなります。したがって、これはローエンド デバイス向けの非常に特殊なエンジンですが、React や Vue (またはそれらに対応するファミリー バケット) などの中大規模のフロントエンド プロジェクトで標準である基本ライブラリをサポートする必要がある場合でも、次のものが必要になる場合があります。より強力なエンジンを使用するため。 <p>

JerryScript の使用に関しては、RT-Thread 創設者の @midnightbear 氏が同様のシナリオでのアプリケーション経験が豊富であることは間違いなく、彼らが国内一流メーカーと協力して開発したスマート ウォッチでは JerryScript を使用して実装されていました。現在の製品は現在入手可能であり、まもなく発売されます。 JerryScript の使用に関するチームからのフィードバックの一部も、上記の評価と一致しています。要約すると、次のとおりです。
  • JerryScript 在体积和内存占用上,相比 QuickJS 有更好的表现。
  • JerryScript 的稳定性弱于 QuickJS,有一些难以绕过的问题。
  • JerryScript 面对稍大(1M 以上)的 JS 代码库,就有些力不从心了。
<p>那么师出名门的 QuickJS 和 Facebook 的 Hermes,是否就是无 JIT 式 JS 引擎的下一代标杆了吗?倒也未必如此。这方面可以参考个人的知乎回答:随着 TypeScript 继续普及,会不会出现直接跑 TypeScript 的运行时?这里提到的微软为教育项目 MakeCode 研发的 Static TypeScript,就相当有潜力成为下一代的高性能 JS 系语言环境。通过限定 TypeScript 的静态强类型子集并为其搭建工具链,STS 可以做到无需 JIT 也能接近 V8 的性能水平,同时内存占用比 V8 少两个数量级。这使得 STS 不光能用于开发普通 app 这类 IO 密集的应用,还能顺利在嵌入式硬件上开发小游戏这类更偏计算密集(需逐帧更新渲染)的应用,在工程能力上是一项很大的突破。

<p>所以说,当「鸿蒙 2.0」还需要熟练开发者勉强搭建出环境跑通 Hello World 时,微软已经让上百万小朋友都能用 TypeScript 在网页里给教学用的掌上游戏机写小游戏入门编程了。这里没什么唱反调的意思,只希望提醒一下我们在为国产「里程碑」欢呼时,也要清醒地看到业界前沿的动向,仅此而已。

图形绘制层

<p>理解 JS 运行时之后,还剩最后一个问题,即 JS 运行时中的各种 Component 对象,是如何被绘制为手表等设备上的像素的呢?

<p>这就涉及「鸿蒙 2.0」中的另一个 graphic_lite 仓库了。可以认为,这里才是真正执行实际绘制的 GUI。像之前的 TextComponent 等原生组件,都会对应到这里的某种图形库 View。它以一种相当经典的方式,在 C++ 层实现并提供了「Canvas 风格的立即模式 GUI」和「DOM 风格的保留模式 GUI」两套 API 体系(对于立即模式和保留模式 GUI 的区别与联系,可参见个人这篇 IMGUI 科普回答)。概括说来,这个图形子系统的要点大致如下:

  • 图形库提供了 UIView 这个 C++ 控件基类,其中有一系列形如 OnClick / OnLongPress / OnDrag 的虚函数。基本每种 JS 中可用的原生 Component 类,都对应于一种 UIView 的子类。
  • 除了各种定制化 View 之外,它还开放了一系列形如 DrawLine / DrawCurve / DrawText 等命令式的绘制方法。
  • 这个图形库具备名为 GFX 的 GPU 加速模块,但它目前似乎只有象征性的 FillArea 矩形单色填充能力。
<p>在基础 UI 控件方面,不难找到一些值得一提的自研模块特性:

  • 支持了简易的 RecycleView 长列表。
  • 支持了简易的 Flex 布局。
  • 支持了内部的 Invalidate 脏标记更新机制。
<p>至于 2D UI 渲染中的几项关键能力,则基本可分为路径、位图和文字三类。这个图形库在这几个方面都有涉及,最后简单介绍一下。

<p>首先对于位图,这个图形库依赖了 libpnglibjpeg 做图像解码,然后即可使用内存中的 bitmap 图像做绘制。

<p>然后对于路径,这个图形库自己实现了各种 CPU 中的像素绘制方法,典型的例子就是这个贝塞尔曲线的绘制源码:

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;
    }
}复制代码
ログイン後にコピー
<p>基于高中的数学知识,我们不难明白这种曲线是如何绘制出来的:取足够多的点(也就是那个默认 1000 的 INTERPOLATION_RANGE)作为插值输入,逐点计算出曲线表达式的 XY 坐标,然后直接修改像素位置所在的 framebuffer 内存即可。这种教科书式的实现是最经典的,不过如果要拿它对标 Skia 里的黑魔法,还是不要勉为其难了吧。

<p>最后对于文字的绘制,会涉及一些字体解析、定位、RTL和折行等方面的处理。这部分实际上也是组合使用了一些业界通用的开源基础库来实现的。比如对于「牢」这个字,就可以找到图形库的这么几个开源依赖,它们各自扮演不同的角色:

  • harfbuzz - 用来告诉调用者,应该把「牢」的 glyph 字形放在哪里。
  • freetype - 从宋体、黑体等字体文件中解码出「牢」的 glyph 字形,将其光栅化为像素。
  • icu - 处理 Unicode 中许多奇葩的特殊情况,这块个人不了解,略过。
<p>到这里,我们就可以理出一个非常概括性的渲染流程了:

  • JS で this.hello = 'PPT' のようなコードを実行して、依存関係の追跡をトリガーします。
  • JS 依存関係追跡コールバックは、ネイティブ関数をトリガーし、C の Component コンポーネントの状態を更新します。
  • コンポーネントは、バインドされた UIView サブクラスの状態を更新し、グラフィック ライブラリの更新をトリガーします。
  • グラフィックス ライブラリはメモリ内のピクセル ステータスを更新し、描画を完了します。
<p>これは、「Hongmeng 2.0」の GUI テクノロジー スタックに対する私の個人的な解釈です。時間が限られていたため、これ以上は掘り下げませんでしたが、(文明的な)批判や修正は歓迎です。

概要

<p>特記事項: この主観的なレビューは、「Hongmeng 2.0」の現在の GUI フレームワークのみを対象としています。勝手に誤解しないでください。

<p> 「Hongmeng 2.0」の GUI 部分のハイライトについては、個人的に次のことが考えられます:

  • 確かにプラグマティックなコードが含まれています (ただし、Hongmeng 2.0 とは完全に異なります)。当時の PPT 入門)。
  • WebView シェルではなく、レイアウトと描画は自分で行います。
  • スムーズに読んで理解するために、学部レベル以上のコンピューターの知識は必要ありません。
<p>明らかな (醜いコード行だけではない) 欠陥や問題については、現在次のようなものがあるようです:

  • JS フレームワーク層
    • 基本的なコンポーネント間通信 (props/emit など) 機能はありません
    • 基本的なカスタム コンポーネント機能はありません
    • いいえ基本的な依存関係追跡以外の状態管理機能
  • JS エンジンとランタイム層
    • 標準サポートが低すぎるため、Vue などのプロキシを必要とする次世代フロントエンドを実行できません3.0 フレームワーク
    • パフォーマンス レベルが弱く、中規模および大規模な JS アプリケーションをサポートするのは困難です
    • オープンな DOM スタイルのオブジェクト モデル API はありません。差分を平滑化する上位層には役に立たない
  • グラフィックス レンダリング レイヤー
    • 大幅な GPU アクセラレーションは利用できません
    • 高度なレンダリングはありませんSVG やリッチ テキストなどの機能
    • Canvas の完成度は低く、状態スタックの欠如と多くの API
<p> 欠点はたくさんあるようですが、車にジェットエンジンが搭載されていないと非難しますか?複雑さの異なるシナリオでは、当然、最適なアーキテクチャ設計も異なります。現時点では、この設計は確かに組み込みハードウェアや単純な「小さなプログラム」のシナリオに非常に適しているようです。しかし、いわゆる「分散型フルシナリオ クロスプラットフォーム」要件に従って見ると、このアーキテクチャの複雑さは、最新の Web ブラウザーや iOS および Android GUI とはまったく比較できません。 これを携帯電話に実装したい場合は、ほぼ確実に、多数の複雑なモジュールを追加し、大幅なアーキテクチャの進化と再設計を行う必要があります。

<p>もちろん、自動車メーカーは飛行機を作るとは言いませんよね?

<p>つまり、これは確かに私が作った麻婆豆腐の皿ですが、一部の人が言うような満州漢の宴会ではありません。

<p>最後に個人的な主観的なコメント:

<p>まず第一に、この GUI テクノロジ スタックは、オープン ソース製品を組み立てて描画するときに得られる主流レベルに達しています。ただし、パフォーマンスと表現力の点では、そのコア モジュールと Microsoft MakeCode などの産学研究の最先端ソリューションとの間には、依然として世代間のギャップがあります。

<p>第二に、多数の専門家による精密な計算が必要なロケット科学とは考えないでください。私は独自の研究開発を軽視しているわけではありませんが、皆様にご理解いただけることを心から願っています。「##」 #私も実際にこの件に参加することができます!" OS や GUI はそれほど謎ではありません。学習、使用、貢献のために利用できる国内の成熟したオープンソース製品が多数あります (ちなみに、RT-Thread は非常に簡単に体験でき、中国製なので早期導入者にお勧めします)。結局のところ、製品が技術的にどのようなものであるかを本当に理解している場合にのみ、下心を持つ人々によって操作される可能性は低くなります。

最後に、JavaScript に精通しているすべてのフロントエンド開発者に、<p>なぜあなたは今でもHongmeng を奇妙な方法で笑うのですか? Honmeng は中国の JavaScript の資産コードです。 JavaScript は、Hongmeng のような「国家兵器」によって採用されており、フロントエンドの道路の信頼性、理論的信頼性、文化的信頼性、テクノロジー スタックの信頼性を大幅に高めることができます。このように継ぎ足しと自主研究を組み合わせれば、一気に全国で高い評価を得ることができる、この道は本当に魅力的です(小声)

団結して精力的に宣伝・宣伝していかなければなりません大国間の競争における核抑止力としての JavaScript の地位は、JavaScript を書けると言う限り、誰もがあなたを尊敬するレベルにまで上昇する必要があります。フロントエンド プログラマーである限り、いつでも列に並ぶことができます。切符を買って、バスに乗ったら席を譲って、部屋を確保して、無料でセックスできる…良い時代が来ています! <p>

あなたは国の柱になりたいですか? JavaScriptを書いてみよう! <p>

もう言葉はありません、国を元気にするために一生懸命頑張ります! <p>

プログラミング学習について詳しく知りたい方は、<p>php training のコラムに注目してください!

以上がHonmeng JavaScript GUI テクノロジー スタックを見てみましょうの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:juejin.im
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート