1. ホーム
  2. Web制作
  3. html5

HTML5ページシームレス点滅オープン問題と解決策

2022-02-06 07:28:12

従来のWeb最適化では、圧縮、解凍、ダイナミックローディングなどにより、最初の画面のリソースサイズを小さくすることができます。また、オフラインパッケージ、ページダイレクトアウトなどにより、htmlのリターンを高速化することができます。h5 second open bookの前回の記事で簡単な分析があります。ほとんどの場面で、これらのプログラムは十分であり、優れた結果を得ることができます。しかし、まだ2種類の不完全さがあります:一つは短い白い画面の現象は避けられない、もう一つは超大型のウェブアプリケーションを数秒で開くのは難しいということです。クライアントサイドの機能と合わせて、さらに一歩進んで、ウェブページとクライアントサイドのページを体感的に差なく開く方法はないでしょうか。

従来のソリューションのジレンマ

htmlオフライン、ストレートアウト、ネットワークリクエストと並行してWebviewを起動させるなど、ページを切り替えたり開いたりする際に、htmlの読み込み処理を避けることはできません。大規模なアプリケーションでは、jsの膨大な初期パースと実行に膨大な時間がかかることがあります。

新しい考え方の方向性?

スピード最適化の本質は、空間と時間を交換することです。このアイデアを利用して、Webビューを開いてhtmlを解析する処理を省略できないでしょうか。答えは「イエス」です。

コンテナ化ソリューション

Containerization これが、最終的に探って実践した解決策です。通常のWebページを閉じた後、webviewコンポーネントは破壊され、次に開くときに再起動する必要があります。通常、webview を常駐させることでwebview の起動時間を節約できますが、単純な常駐 webview ではページを数秒で開くことはできず、ページを再パースする必要があることに変わりはないのです。

私たちのアプリケーションの機能では、ページ切り替えは実際にはコンテンツデータの変更に過ぎません。例えば、ドキュメントを切り替える場合、htmlコンテナやスタイルは同じセットで、違いはデータの中だけです。webviewコンポーネントとそのコンテナ内のhtmlページを常駐させ、ドキュメント切り替えの過程でデータだけを入れ替える、これがコンテナ化ソリューションです。コンテナ化されたソリューションは、webviewの起動とhtmlのレンダリングを繰り返す問題を解消し、データを置き換えるだけのドキュメントを開くので、本当に数秒で開くことができるのです。

コンテナ切り替え

異なるページ同士が切り替わっていることを、Web側はどのように感知し、どのようにデータを置き換えているのか。

まず、アプリが開かれると、ドキュメントリストが事前に引き出され、コンテナをオンデマンドで起動できる他のシナリオに加えて、クライアントが事前に起動されます(これについては後で詳しく説明します)。コンテナは html でプリレンダリングされ、js で実行され、この時点ではデータは空です。ユーザーがドキュメントをクリックすると、クライアントはurlを開くという行為を聞き、urlを解析してユニークな識別子を取り出し、ローカルデータがすでに存在し条件を満たしているかどうかを判断し、条件を満たしている場合は開いたコンテナを直接使って切り出し、コンテナ内のウェブに通知します。ウェブはその通知を受け、urlを介して識別子を取り出し、ローカルからデータを取得し、そのデータを レンダリングします。 ウェブはその通知を受け、urlを介してローカルサイトから識別子を取り出し、そのデータを代わりにレンダリングし、ページ切り替えを完了します。

コンテナ型データ置換

コンテナの直接置換のアイデアは、コードの読み込みと解析の時間を節約しますが、フロントエンドのコードでは、データの直接置換をサポートする必要があります。ほとんどのフロントエンド・プロジェクトのコードは Self-executing calls to コンテナ化をサポートするための前提条件として、コードを変換して data assembly and destruction .

// Most scenarios where the app loads the page initialization
class App {
    public init() {
     initA();
     initB();
        // Initialize various modules
        ...
    }
}
 
const app = new App();
app.init();

呼び出しの実行以降、内部の多数の従属モジュールも順次初期化され、メモリ上にデータが常駐する。通常、通常のWebページの読み込みでは、毎回新しいページを開き、htmlを読み込み、再解析・再初期化を行うため、特に問題は生じない。しかし、コンテナ化の考え方によれば、ページの再読み込みは行わず、データの入れ替えのみを行います。大規模なアプリケーションでは、数千のモジュールがメモリ解放やデータ入れ替えに対応する必要があり、一度適切に処理されないと、メモリリークやコードの堅牢性に重大な問題が発生します。このコードをどのように整理して管理し、プラガブルに対応させ、ページの初期化処理全体をチェーンで組み立て、設定できるようにするか、これがコンテナ化したコード変換を行う上での難しいところです。

  • 依存関係の反転

依存関係逆転の原則とは、内部モジュールは外部モジュールに依存すべきではなく、下位モジュールは上位モジュールに依存すべきではないことを意味する。

ボトムモジュール、トップモジュールとは何ですか?一般的には、安定した不変のロジックほど下位に、ユーザーとの対話に近い部分は上位に、変化しやすい部分は下位に配置するのが良いとされています。具体的な階層は、アプリケーションの構造や依存関係などの観点から分析する必要があり、階層をきちんと定義することが、コンテナ型変換の前提条件となる。

  • Chain of Responsibilityモデル

chain of responsibilityパターンは、各オブジェクトがリクエストを受け取る可能性を持ち、それらのオブジェクトが連鎖して、あるオブジェクトが処理されるまでリクエストが受け渡されるというもので、受け手と送り手の直接的な結合を減らすことができるという利点がある。例えば、ページロードのライフサイクルでは、内部から外部のモジュールに適切なライフサイクルの責任を実装させ、起動と破棄の処理を適用し、リクエストは外部から内部へと指定されたチェーンに沿って渡される、あるいは、要求に応じてモジュールをジャンプするように指定すれば、モジュール間の結合を大幅に削減でき、コードの管理もうまくいきます。

export default interface IRestart{
    emitter: EventEmitter;
    startDestroy(): void;
    destroy(): void;
    restart(): void;
    restartEnd(): void;
    // ...
}

class Page {
    next: PageFlow|null;
    cache: {
        start: (() => Promise<any>)[];
        end: (() => Promise<any>)[];
    };
    waitStart(callback: () => Promise<any>) {
        this.cache.start.push(callback);
    };
    waitEnd(callback: () => Promise<any>) {
        this.cache.end.push(callback);
    };
    setNext(flow: PageFlow) {
        this.next = flow;
        return flow;
    }
     // ...
   }

  • 依存性注入(Dependency Injection

依存性注入とは、Aオブジェクトが別のBオブジェクトに依存する場合、BをAオブジェクト内で直接初期化するのではなく、外部環境を通して初期化し、Aオブジェクトにパラメータとして渡すことです。Bモジュールの初期化などの条件が変わっても、Aオブジェクトの変更を繰り返す必要がないという利点がある。このような互いに依存し合う数百のモジュールを管理するコードでは、依存性注入マネージャを統一することで、依存性の管理が容易になる。

// Module loaders
class ServiceLoader {
    source: CONFIG;
    loaded: boolean; // whether it is loaded
    initialized: boolean; // whether initialized
    module: any;
    constructor(source: CONFIG) {
        this.loaded = false;
        this.initialized = false;
        // ...
    }
    async load(params?: any): Promise<any> {
     // . . load module
        return this.module;
    }
    // ...
}

// Module Manager
class ServiceCollection {
    stack: ServiceLoader[];
    private services = new Map<CONFIG, ServiceLoader>();
    constructor() {
        this.stack = [];
    }
    createLoader(config: CONFIG): ServiceLoader {
        const loader: ServiceLoader = new ServiceLoader(config);
        this.services.set(config, loader);
        return loader;
    }
    // ...
}

initA () {
    const ALoader= this.serviceCollection.createLoader(CONFIG;)
    const discussMobile = ALoader.init(this.app);
}

データプリプルサービス

コンテナがヒットするかどうかは、対応するオフラインのパッケージコードがダウンロードされているかどうか、対応するバージョンのデータが事前にプルされてキャッシュされているかどうか、という2つの条件に依存します。

ユーザーが文書管理のホームページに入ると、まずリストインデックスデータを引き、リストデータIDで文書内容データをあらかじめ引き、ローカルデータベースに格納し、オフラインでフロントエンドで探索できるようにします。

ウェブビューサービス

データのプリプルプロセスを通じて、クライアントサイドのバックエンドのWebビューサービスの個別のセットを通じて特定のタスクを実行します。別サービスの利点は、様々なコンテナ化されたベースサービスを文書管理リスト自体から切り離し、データのプル、パース、保存といったパフォーマンスを消費するプロセスをバックエンドサービスに置くことで、リストのユーザーインターフェース層へのパフォーマンス圧力を軽減できることです。

一方、マルチエンドで共通のサービスとして、ビルドプロセスを個別に展開することで、他のページに依存しないコード更新が可能になり、柔軟性が高まります。

データスナップショット

純粋な dom 構造を持つドキュメントベースのカテゴリの場合、ドキュメントを開き、データをパースし、その結果の html をローカルデータベースのスナップショットテーブルにキャッシュしています。次にコンテナを切り替えたときに、ローカルデータのパースを取りながら、対応するidがスナップショットテーブルに存在するかどうかを判断し、存在する場合は直接取り出してhtml上に上書きすることで、ユーザーは最後にレンダリングしたデータを事前に確認でき、ローカルデータが本当にパースされてからインタラクティブなインターフェースを表示することができるようになります。データを解析してレンダリングの準備をするのに数百ミリ秒かかるので、この戦略によってユーザーはより早くコンテンツを見ることができるのです。

プリ・クリエーション

究極のオープンスピードで、新規作成のスピードをいかに最適化するか。通常の新規作成は、ユーザーが新規作成ボタンをクリックし、フロントエンドがcgiの作成を依頼し、バックエンドが新規文書のURLを正常に返すのを待ち、フロントエンドが新しいWebビューを開いて表示ページをロードする、という流れになります。作成インターフェイスの返送を待つ必要があるため、通常のドキュメントを開くよりも新規作成への処理に時間がかかることがわかります。

どうすればnew openも数秒でできるようになるのでしょうか?アイデアはデータの事前取得と同じです。ユーザーがドキュメントのホームページにいる間に、作成IDのバッチを事前要求し、ローカルにキャッシュし、作成IDに基づいて空のドキュメントを生成し、ローカルに保存し、ステータスに未使用とマークします。ユーザーが新規作成ボタンをクリックすると、基本的にローカルから未使用のドキュメントURLを取得し、コンテナスイッチで直接開き、バックエンドと同期させるという流れになっています。

セカンドオープン効果

コンテナ化構想の前。

コンテナ化スキームの後。

監視・交換システム

コンテナソリューションはデータプリフェッチシナリオを使用しており、ヒットモニタリングが非常に重要です。ページを切り替える処理のため、コンテナがヒットした場合はクライアントから通知を受け、このタイミングでエスカレーションを行うことができます。

もう一つ非常に重要なのは、コンテナ能力の切り替えシステムです。リリース当初は既存のネットワークの安定性を保つために非常に重要な施策ですが、どんなプログラムもバグがないことは保証できません。このコンテナソリューションの様々な機能をカテゴリーごとに有効にするかどうかは、内部のセピア設定システムでコントロールしており、この設定もグレースケールやロールバックシナリオに対応して、様々な想定外のトラブルに対応できるように配慮しています。

グレースケール時のコンテナ間ヒット率

最適化すべき課題

コンテナ化ソリューションでは、開く速度と引き換えに、ウェブビューを事前に作成するさまざまな方法が使用され、アプリのメモリフットプリントは、コンテナ化ソリューションを使用しない場合よりもはるかに大きくなることが予想されます。

概要

HTML5ページシームレス点滅ソリューションのこの記事はこれで終わりです、より関連するHTML5ページシームレス点滅コンテンツは、スクリプトハウスの過去の記事を検索するか、次の関連記事を閲覧を続けてください、あなたは将来的にもっとスクリプトハウスをサポートして願っています!.