ミニプログラム開発ツールのソースコードからの基本実装の分析

ミニプログラム開発ツールのソースコードからの基本実装の分析

ミニプログラム開発者ツールのソースコードを表示する方法

次に、WeChat ミニプログラム開発者ツールのソースコードを使用して、ミニプログラムの基本的な実装原則について説明します。開発者ツールのバージョン番号 State v1.02.1904090 のソース コードを使用して、ミニ プログラムの実装のアイデアを覗いてみましょう。 WeChat のソースコードを表示するにはどうすればいいですか? Mac ユーザーの場合は、WeChat ミニプログラム開発ツールのパッケージ コンテンツを表示し、Contents/Resources/app.nw/js/core/index.js に移動して、次のコードをコメント アウトし、開発ツールによってレンダリングされたコードを表示します。

// 検査ウィンドウを開く if (nw.App.argv.indexOf('inspect') !== -1) {
    ツール.openInspectWin()
}

次にミニプログラム開発者ツールを再起動すると、左側に次のページが表示されます。いずれかのページをクリックすると、下の図の右側に示すように、ビューレイヤーの DOM 構造が表示されます。

ミニプログラムアーキテクチャ設計

1. ミニプログラムは同じスレッドでレンダリングされていますか?デュアルスレッド機構

ミニプログラムを開発したことがある人なら誰でも、ミニプログラムはデュアルスレッド設計、つまりビューのレンダリングとビジネス ロジックがそれぞれ異なるスレッドで実行されることを知っています。この設計は主に、Web テクノロジーの問題点を解決することを目的としています。

Web ページ開発のレンダリング スレッドとスクリプト スレッドは相互に排他的です。スクリプトを長時間実行すると、ページが応答しなくなったり、白い画面が表示されたりして、エクスペリエンスが低下する可能性があります。

より良いエクスペリエンスを提供するために、ミニプログラムはページレンダリングスレッドとスクリプトスレッドを分離し、異なるスレッドで実行します。具体的な実装は次のとおりです。

  • ビューレイヤーはWebビューでレンダリングされ、1ページは1つのWebビューに対応します。
  • ビジネス ロジック Appservice レイヤーは同じ JSCore スレッド (具体的には iOS の場合は JavaScriptCore、Android の場合は X5 JSCore) で実行され、開発者ツールは Web ビュー内にあります。

これにより、スクリプトがページのレンダリングを長時間ブロックするという問題は解決されますが、いくつかの新しい問題も発生します。

  • 固有の遅延、スレッドは通信する必要がある
  • ビジネス ロジック レイヤーは JSCore で実行されるため、DOM および BOM API にアクセスできません。

開発者ツールは、WebView を使用してビジネス ロジック レイヤーのコードを読み込みます。依存環境には DOM および BOM API がありますが、一貫性を維持するために、ミニプログラムはすべてのモジュールをローカライズして、これらの API にアクセスできないようにします。このように、2 つのスレッドはネイティブで通過し、開発者ツールはバックグラウンドの Websocket サービスを通じて 2 つのスレッド間のメッセージ転送媒体として機能し、いくつかの基本的な機能を提供します。詳細は公式ウェブサイトのマップをご覧ください。

2. ミニプログラムは Web レンダリングされますか?インターフェースレンダリングメカニズム

ページをレンダリングするには、主に 3 つの方法があります。

  • 純粋なウェブレンダリング
  • 純粋なネイティブレンダリング
  • ウェブレンダリングとネイティブレンダリングを組み合わせたハイブリッドレンダリング

ミニプログラムのホスト環境は WeChat であるため、純粋なネイティブ レンダリングを使用することはほとんどありません。そうでない場合は、すべてのミニプログラムを WeChat と一緒にコーディングしてリリースする必要があります。高速なオンライン更新をサポートし、最新のリソースをローカルにインストールすることでレンダリングできる純粋な Web レンダリングを使用することは実現可能と思われます。ただし、複雑なインタラクションのある一部のページでは、純粋な Web レンダリングでパフォーマンスの問題が発生する可能性があります。これは、Web テクノロジでは、UI レンダリングと JavaScript スクリプトの実行の両方が単一のスレッドで実行されるため、一部の論理タスクが UI レンダリング リソースを占有しやすくなるためです。したがって、公式 Web サイトで説明されているように、アプレットはハイブリッド モードでレンダリングされます。

インターフェースは主に成熟した Web テクノロジによってレンダリングされ、豊富なクライアント ネイティブ機能を提供するための多数のインターフェースによって補完されます。

同時に、各ミニプログラム ページは異なる WebView を使用してレンダリングされるため、ネイティブ エクスペリエンスに近い、より優れたインタラクティブ エクスペリエンスを提供できるとともに、単一の WebView のタスクが重くなりすぎることを回避できます。

ハイブリッド レンダリングが使用されているため、ページはネイティブ レンダリングを使用してレンダリングされる可能性があります。どのような状況でネイティブ レンダリングが使用されますか?

答えは、ミニプログラムが提供するマップ、ビデオ、キャンバス、テキストエリアなどのコンポーネントを使用することです。ページ内のネイティブレンダリングのレンダリング原則は、公式サイトのネイティブコンポーネントを参照できます。ただし、ミニプログラム開発ツールでは、ネイティブ コンポーネントは HTML タグを使用してシミュレートされます。詳細については、次のセクションのマップ コンポーネントのレンダリング結果を参照してください。

3. ミニプログラムは Web HTML タグを使用してレンダリングされますか? Exparser コンポーネント フレームワーク

前述のように、ミニプログラムは主に成熟した Web テクノロジによってレンダリングされます。div、table など、HTML が提供するタグを直接使用してページを整理できるでしょうか? 答えは「いいえ」です。主な考慮事項:

  • 制御とセキュリティ: Webテクノロジーは、スクリプトを通じてページの機密コンテンツを取得および変更したり、他のページに自由にジャンプしたりすることができます。
  • 機能が制限されるとミニプログラムのプレゼンテーションが制限される
  • タグが多数あるため、理解にかかるコストが増加します。

したがって、ミニプログラムは HTML タグを直接使用してページをレンダリングすることはできません。Web タグを収束するための 10 を超える組み込みコンポーネントを提供し、js がブラウザー API にアクセスできないようにする JavaScript サンドボックス環境を提供します。

ミニプログラムは HTML タグを直接使用してページをレンダリングできないため、view や cover-view などの組み込みコンポーネントは、最終的にはレンダリング用に HTML によって提供される組み込みタグに変換されることになりますか?答えはノーです。次のコードを見てみましょう。

<view class="map-container">
  <map 緯度='39.9088230000' スタイル="高さ: 100%; 幅:100%;" 経度='116.3974700000' スケール='16' id="id" bindregionchange="onRegionChange"></map>
  <view catchtap="onTap">テスト</view>
</ビュー>

上記のコードは最終的に、開発者ツール内の要素を以下のようにレンダリングします。

ミニプログラムによって提供されるコンポーネントは、最終的にはレンダリング用の対応する HTML タグに変換されるのではなく、カスタム要素を使用してレンダリングされることがわかります。これらの組み込みコンポーネントはすべて、ミニプログラムの基本ライブラリに組み込まれ、ミニプログラムのさまざまなコンポーネントに基本的なサポートを提供する Exparser フレームワークによって管理されます。

Exparser フレームワークは、WebComponents の ShadowDOM と非常によく似た Shadow DOM モデルに基づいています。詳細については、公式 Web サイトのコンポーネント システムを参照してください。
組み込みコンポーネントの命名規則はすべて wx- で始まります。view などの組み込みコンポーネントへの外部参照は、最終的に基礎となる wx-view コンポーネントを呼び出します。Exparser の view コンポーネントは次のように作成されます。

4. ミニプログラムはDOMを操作できますか?データ駆動型

制御とセキュリティのために、ミニプログラムは JavaScript コードを実行するための JavaScript サンドボックス環境を提供します。js コードはブラウザ関連のインターフェイスにアクセスできないため、js は dom と bom を操作できず、操作するとエラーが報告される可能性があります。ミニプログラム用のサンドボックス環境を実装するにはどうすればいいですか?つまり、ビジネス ロジックをローカル環境にカプセル化することで、ローカル環境は DOM と BOM の関連する API ポインターを変更します。具体的な梱包形態は以下のとおりです。

そこで疑問になるのが、ミニプログラムはどのようにして上記のカプセル化をビジネス コードに追加するのかということです。実際には、非常に簡単です。ミニプログラム開発者ツールにはバックグラウンド サービスがあります。ミニプログラムの各モジュールのパスにアクセスすると、バックグラウンド サービスは wrapSourceCodeInDefine メソッドを呼び出して、要求された JS ファイルのコンテンツを定義フィールドにラップします。メソッドのコードを次の図に示します。

ここでのdefineメソッドは、ミニプログラムの最下層でモジュール化を実装するためのメソッドの1つです。もう1つはrequireメソッドです。defineはモジュールを定義するために使用され、requireはdefineで定義されたモジュールを参照するために使用されます。上記のアプレットのビジネス モジュール コードのカプセル化から、次のことがわかります。

define で定義されたモジュールは、window、document、localStroage など、ブラウザ関連のインターフェースと同じ名前の API を渡します。グローバル スコープの window オブジェクトには Function('return this')() を通じてアクセスできると言う人もいるかもしれませんが、アプレットはこのパスをブロックし、Function を書き換え、eval は undefined にリセットされます。たとえば、次の図:

モジュールを要求する場合、require、module、exports のみが渡されます。他のパラメータの値は未定義であり、これらのインターフェースはビジネス コードではアクセスできません。

require で定義されたソース コードを見ることができます。

実際のWeChat環境では、ビジネスロジック層はJSCoreで実行されており、ブラウザ関連の情報がなく、DOMにアクセスできません。ただし、ミニプログラム開発者ツールでは、WebViewを使用してビジネスロジックコードを実行しますが、WebViewにはDOM関連のインターフェースがあります。そのため、上記のサンドボックス環境を使用して、JSがDOMを操作することを均一に防止します。

ビジネス コードが DOM にアクセスできない場合、どのようにしてページを動的に更新できるでしょうか?

答えは、Vue のような MVVM フレームワークのデータ駆動型の考え方を採用すること、つまり、ビューの状態とビューを結び付けることです。状態が変化すると、ビューも自動的に変化するため、DOM を直接操作する必要がありません。

ビューの動的な更新は、仮想 DOM テクノロジによって実装されます。仮想 DOM については、すでに皆さんが理解していると思います。プロセスは次のとおりです。

実際の処理は簡単に説明すると次のようになります。

JS オブジェクトを使用して DOM ツリーをシミュレートし、2 つの仮想 DOM ツリーの違いを比較し、その違いを実際の DOM ツリーに適用します。

その中で、仮想 DOM は組み込みの wcc を介して wxml を js オブジェクト形式に変換し、DOM ツリー構造を表すことができます。

以下は、動的なビュー更新のプロセスを説明する公式 Web サイトからの画像です。

// wxml
 <view>{{msg}}</view>

// js
データ: {
   メッセージ: 'Hello World'
} 

上記では、ビューの更新方法について説明しました。実際、データ応答のプロセスには、ビジネス ロジック レイヤーが変更されたデータをビュー レイヤーに同期させる方法という、もう 1 つの最も重要なリンクがあります。これには、デュアル スレッド通信が関係します。

5. ミニプログラム基本ライブラリの機能は何ですか?

開発者ツールでミニプログラムを開発する場合、通常はミニプログラム開発者ツール選択インターフェースなどの基本ライブラリを選択します。

ミニプログラムの基本ライブラリは JavaScript で書かれていますが、ミニプログラムでは直接参照しません。では、基本ライブラリが提供する関数はどのように使用すればよいのでしょうか。答えは次のとおりです。

WeChat ホスト環境には、あらかじめ基本ライブラリが組み込まれています。ミニプログラムを開くと、基本ライブラリがミニプログラムのビュー層とビジネスロジック層に自動的に挿入されます。ミニプログラム開発者ツールは、基盤となる HTTP サービスによって挿入されます。

次の図は、スクリプトを通じてアプレットの基盤となる HTTP サービスによって挿入された関連コードを示しています。

ミニプログラムの基本ライブラリ関数には、2 つの部分ビュー レイヤー用の WAWebview.js と、ビジネス ロジック レイヤー用の WAService.js が含まれます。対応する機能の簡単な説明は次のとおりです。

WAServiceはビジネスロジック層の基本機能を提供する

WAService.js ソースコードの内容のサムネイルを見てみましょう。

ソースコードから、基本ライブラリが提供するWAService.jsには、主に次の部分を含む多くの機能があることがわかります。

  • WeixinJSBridge: メッセージ通信の統一されたカプセル化、呼び出しが容易。主に WeChat 環境とネイティブ間、開発環境と開発者ツール バックエンド サービス間の通信に使用されます。
  • wx: wx オブジェクトによる API メソッドのカプセル化
  • appServiceEngine: define、require、App、Page、Component、getApp、getCurrentPages などのグローバル メソッドを定義します。
  • virtualDOM: VirtualDOM、Diff、Render UI の実装
  • expraser: expraser フレームワーク コンポーネントのメソッド定義。つまり、ロジック レイヤーには特定のコンポーネント ツリー編成機能もあります。
  • レポーター: ミニプログラム ログ コンポーネント

WAWebviewはビュー層の基本機能を提供する

ビュー層用のミニプログラム基本ライブラリが提供する基本機能の一部は、WAService のものと同じです。主な機能は次のとおりです。

  • メッセージ通信のカプセル化はWeixinJSBridge
  • ログコンポーネントレポーターのカプセル化
  • wx オブジェクトの API は、そのほとんどが UI 表示の処理に関連するメソッドであるという点で、WAService の API とは異なります。
  • Mini Program Expraserコンポーネントフレームワークの実装と組み込みコンポーネントの登録
  • VirtualDOM、Diff、Render UI の実装
  • ページ関連のイベントトリガーを定義する

上記は、ミニプログラム開発ツールのソースコードから原理実装を分析する詳細な内容です。ミニプログラム開発ツールのソースコードから原理実装の詳細については、123WORDPRESS.COMの他の関連記事に注目してください。

以下もご興味があるかもしれません:
  • WeChatミニプログラムカルーセルの実装原理と最適化の詳細な説明
  • WeChatアプレットボタンタグのオープン型属性原理の分析
  • WeChatアプレットのイベントフロー原理の分析
  • WeChatアプレットwxmlリストのレンダリング原理の分析
  • WeChatミニプログラムのプルダウンリフレッシュとプルアップロードの原理の分析
  • WeChatミニプログラムにおけるバブルイベントの原理分析
  • WeChatミニプログラムのデータバインディング原則の分析
  • JSによるWeChatアプレットの監視原理

<<:  MySQLのMERGEストレージエンジンの詳細な説明

>>:  CentOS 8 インストール図 (超詳細なチュートリアル)

推薦する

MySQLデータベースでゼロ値を含む日付の問題について簡単に説明します

デフォルトでは、MySQL は日付に 0 値を挿入することを受け入れますが、実際には日付の 0 値に...

WeChat 8.0の爆発的な特殊効果を実現するために300行以上のCSSコードが必要

WeChat 8.0 アップデートの主な特徴は、アニメーション絵文字のサポートです。送信するメッセー...

手の動きをリアルタイムで監視するための Handtrack.js ライブラリ (推奨)

【はじめに】: Handtrack.jsは、ブラウザ上で直接リアルタイムの手の動きの追跡と検出を実...

Vue.js スタイルレイアウト Flutter ビジネス開発共通スキル

シャドウスタイルにおけるフラッターとCSSの対応UIによって指定されたCSSスタイル 幅: 75px...

MySQLデータ損失の原因と解決策

目次序文問題の説明原因分析拡大する総括する序文最近、データの欠落やデータの損失に関するフィードバック...

Docker ベースの Jenkins のデプロイに関する詳細なチュートリアル

このドキュメントを作成した当時は2019年12月頃で、er2.200が最新バージョンでした。 1.画...

Kubernetesでポッドを作成する方法

目次ポッドを作成するには? kubectl ツールポッドを作成するには?前回の記事では、コンテナとポ...

Macにmysql5.7.18をインストールする詳細な手順

1. ツール今必要なツールは2つあります: MySQLサーバー (mysql-5.7.18)、MyS...

VMware12.0 インストール Ubuntu14.04 LTS チュートリアル

私は、デスクトップ バージョンとサーバー バージョンの両方で、仮想マシンにさまざまなイメージを何度も...

知っておくべきHTML最適化テクニック

Web ページのパフォーマンスを向上させるために、多くの開発者は、JavaScript、画像の最適化...

Vue Element-ui テーブルはツリー構造テーブルを実現します

この記事では、ツリー構造テーブルを実現するためのElement-uiテーブルの具体的なコードを参考ま...

DockerにNginxをインストールする方法

DockerにNginxをインストールするNginx は、IMAP/POP3/SMTP サービスも提...

MySQL の大きなテーブルで大量のデータを一括削除する方法

質問はhttps://www.zhihu.com/question/440066129/answer...

MySQLでレコードを変更する場合、更新操作フィールド = フィールド + 文字列

シナリオによっては、varchar 型のフィールドを変更する必要があり、変更の結果は 2 つのフィー...

JavaScript で実装された 6 つの Web ページ画像カルーセル効果の詳細な説明

目次1. マウスがカルーセル モジュール上を通過すると、左右のボタンが表示され、モジュールを離れると...