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

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

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

次に、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 インストール図 (超詳細なチュートリアル)

推薦する

ウェブページ作成時のHTMLタグの使用に注意してください

HTML はプレゼンテーションからコンテンツへの移行を試みており、コンテンツの意味(HTML) とプ...

JSはカード配布アニメーションを実現します

この記事の例では、カード配布アニメーションを実装するためのJSの具体的なコードを参考までに共有してい...

Docker Consul の概要とクラスター環境構築手順(グラフィカルな説明)

目次1. Dockerコンサルの概要2. nginxとconsulをベースにした自動検出と高可用性の...

CSSをiPhoneのフルスクリーンに適応させる方法

1. メディアクエリ方式 /*iPhone X への適応*/ @media 画面のみ、(デバイス幅:...

Vue.js を学ぶ際に遭遇する落とし穴

目次クラス void のポイントES6 矢印関数ヴュートファイvue-cli非同期と同期実行と展開ヒ...

MySQL テーブルを作成するためによく使用される SQL ステートメントの概要

最近、私はプロジェクトに取り組んでおり、背景を記述するために SQL ステートメントを使用する必要が...

Vue 開発者向けの VSCode 拡張機能ベスト 7

適切な VS Code 拡張機能を Visual Studio に追加すると、開発者としての作業がは...

画像比較を実現するjQueryプラグイン

この記事の例では、画像比較を実現するためのjQueryプラグインの具体的なコードを参考までに共有して...

js が CSS 属性 (値) のサポートを決定して通知する状況の分析

新しい CSS 機能を使用する場合、その互換性は常に考慮されます。おそらく、その互換性、どのブラウザ...

CSS を使用して画像の色を変更する 100 の方法 (収集する価値あり)

序文「画像処理というと、PhotoShop などの画像処理ツールを思い浮かべることが多いです。フロン...

MySQLのkillがスレッドをkillできない理由

目次背景問題の説明原因分析シミュレーションする総括する背景日常の使用において、MySQL で個別また...

Web開発で使用される基本的な概念と技術の紹介

本日は、Web 開発で使われる基本的な概念と技術を初心者向けに紹介します。A から Z まで合計 2...

ウェブページをデザインする際に注意すべきいくつかの問題

Web デザインは、個人の好みや Web ページの内容に応じて、デザインのレイアウトが常に変化します...

MySQL パフォーマンスの最適化: インデックスを効率的かつ正しく使用する方法

実践こそが真実をテストする唯一の方法です。この記事では、インデックスの全体的な使用法についてのみ説明...

レイアウトサイズを変更するために左右にドラッグする純粋なCSS

ブラウザの非overflow:auto要素resize伸縮機能を利用して、JavaScript を使...