目录

Lifecycle of the Web Component

Overview

You can use Web components to load local or online web pages.

The Web component provides lifecycle callbacks for detecting status changes and processing services.

The statuses of a Web component include binding a controller to it, the start, progress, and end of page loading, and the state when the page is about to be displayed.

For details about how to keep web pages alive, see Using Offline Web Components.

When a custom component is destructed, the aboutToDisappear function is executed. The Web component is then destroyed, the Web component is unbound from WebviewController, and the JS runtime environment is destroyed as well.

Figure 1 Callback events during the normal web page loading of the Web component

Statuses of the Normal Web Page Loading

Statuses of the Abnormal Web Page Loading

Performance Indicators of Web Component Page Loading

Pay attention to some important performance indicators during web page loading. Such as First Contentful Paint (FCP), First Meaningful Paint (FMP), and Largest Contentful Paint (LCP). The Web component provides the following APIs for notifying you of these indicators of online non-PDF web pages. Local web pages and PDF web pages are not supported.

How can I prevent page suspension when the Web component's rendering child process exits unexpectedly

ArkWeb is a Web component platform designed to display web page content for applications and provide capabilities such as page loading, interaction, and debugging. When an ArkWeb application is used, the page may be suspended due to various reasons. For example, the ArkWeb child rendering process crashes due to front-end exceptions, or the background ArkWeb child rendering process is terminated due to insufficient system resources. In this case, you need to open the page again or restart the application.

If the web page is suspended when the ArkWeb child process exits abnormally, the application can listen for the onRenderExited event to obtain the specific exit cause RenderExitReason and handle the exception in the callback correspondingly.

Development in Practice

import { webview } from '@kit.ArkWeb';

@Entry
@Component
struct WebComponent {
  needReloadWhenVisible: boolean = false;  // Prevents the page from being reloaded after render exits when the Web component is invisible, and reloads the page when it becomes visible.
  webIsVisible: boolean = false;            // Check whether the Web component is visible.

  // The child process crash is distinguished from other exceptions. You can refine the exception handling policy based on the actual service.
  renderReloadMaxForCrashed: number = 5;    // Set the maximum number of retries for reloading after a crash. The application can set this parameter based on service characteristics.
  renderReloadCountForCrashed: number = 0;  // Number of reload times after a crash.
  renderReloadMaxForOthers: number = 10;    // Set the maximum number of retry times for exiting due to other exceptions. The application can set this parameter based on service characteristics.
  renderReloadCountForOthers: number = 0;   // Number of reload times after exit due to other exceptions.

  // Create a Web component.
  controller: webview.WebviewController = new webview.WebviewController();

  // Specify the page to be loaded.
  url: string = "www.example.com";
  build() {
    Column() {
      Web({ src: this.url, controller: this.controller })
        .onVisibleAreaChange([0, 1.0], (isVisible) => {
          this.webIsVisible = isVisible;
          if (isVisible && this.needReloadWhenVisible) { // Reload the page when the Web component is visible.
            this.needReloadWhenVisible = false;
            this.controller.loadUrl(this.url);
          }
        })
        // The application listens for the callback triggered when the child rendering process exits abnormally and handles the exception.
        .onRenderExited((event) => {
          if (!event) {
            return;
          }
          if (event.renderExitReason == RenderExitReason.ProcessCrashed) {
            if (this.renderReloadCountForCrashed >= this.renderReloadMaxForCrashed) {
              // Set the maximum number of reload times to prevent the page from being cyclically loaded.
              return;
            }
            console.info('renderReloadCountForCrashed: ' + this.renderReloadCountForCrashed);
            this.renderReloadCountForCrashed++;
          } else {
            if (this.renderReloadCountForOthers >= this.renderReloadMaxForOthers) {
              // Set the maximum number of reload times to prevent the page from being cyclically loaded.
              return;
            }
            console.info('renderReloadCountForOthers: ' + this.renderReloadCountForOthers);
            this.renderReloadCountForOthers++;
          }
          if (this.webIsVisible) {
            // Reload the page immediately when the Web component is visible.
            this.controller.loadUrl(this.url);
            return;
          }
          // Do not reload the page immediately when the Web component is invisible.
          this.needReloadWhenVisible = true;
        })
    }
  }
}