DEV Community

SameX
SameX

Posted on

Decoding Huawei HarmonyOS Next: A Detailed Explanation of Web Component Adaptive Layout and Rendering Modes

This article aims to deeply explore the technical details of the Huawei HarmonyOS Next system (up to API 12 as of now), and is summarized based on actual development practices.
It mainly serves as a vehicle for technical sharing and communication. Mistakes and omissions are inevitable. Colleagues are welcome to put forward valuable opinions and questions so that we can make progress together.
This article is original content, and any form of reprint must indicate the source and the original author.

Web Component Size Adapts to Page Content Layout

Using the Web component size adaptive page content layout mode layoutMode(WebLayoutMode.FIT_CONTENT) enables the size of the Web component to adaptively change according to the page content. This is suitable for scenarios where the Web component needs to expand according to the height of the web page and scroll together with other native components, such as browsing long articles and the home page of long pages.

@Entry
@Component
struct WebHeightPage {
  //...
  build() {
    Column() {
      //...
      Web({
        //...
      .layoutMode(WebLayoutMode.FIT_CONTENT) // Set to Web component size adaptive to page content
      .overScrollMode(OverScrollMode.NEVER) // Set the over-scroll mode to off
      })
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Web Component Rendering Modes

The Web component supports two rendering modes:

  • Asynchronous Rendering Mode (default): renderMode: RenderMode.ASYNC_RENDER
  • Synchronous Rendering Mode: renderMode: RenderMode.SYNC_RENDER

In the asynchronous rendering mode, the Web component acts as a graphics surface node and is independently rendered. It is recommended to use this mode in application pages composed only of Web components, as it has better performance and lower power consumption.

In the synchronous rendering mode, the Web component acts as a graphics canvas node, and the Web rendering is presented together with the system components. It can render longer Web component content but will consume more performance resources.

@Entry
@Component
struct WebHeightPage {
  //...
  build() {
    Column() {
      //...
      Web({
        //...
      .renderMode(RenderMode.ASYNC_RENDER) // Set to asynchronous rendering mode
      })
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Using Front-End Page JavaScript in the Application

Communication between the front-end page and the application side can be achieved by creating message ports using the createWebMessagePorts() interface.

@Entry
@Component
struct WebComponent {
  //...
  build() {
    Column() {
      //...
      Button('postMessage')
      .onClick(() => {
          try {
            // 1. Create two message ports.
            this.ports = this.controller.createWebMessagePorts();
            // 2. Register a callback event on the application-side message port (e.g., port 1).
            this.ports[1].onMessageEvent((result: webview.WebMessage) => {
              //...
            });
            // 3. Send the other message port (e.g., port 0) to the HTML side for the HTML side to save and use.
            this.controller.postMessage('__init_port__', [this.ports[0]], '*');
          } catch (error) {
            //...
          }
        })
      //...
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Mutual Invocation between the Application Side and the Front-End Page (C/C++)

Communication between the front-end page and the application side can be achieved using native methods in this article, which can solve the redundant switching in the ArkTS environment and also allow messages to be sent and callbacks to be reported in non-UI threads to avoid UI blocking. Currently, only the string and buffer data types are supported.

// ArkTS side code
//...
aboutToAppear() {
  console.info("aboutToAppear");
  // Initialize web ndk
  testNapi.nativeWebInit(this.webTag);
}
//...
build() {
  //...
  Web({ src: $rawfile('index.html'), controller: this.controller })
  .onConsole((event) => {
      if (event) {
        let msg = event.message.getMessage();
        if (msg.startsWith("H5")) {
          this.h5Log = event.message.getMessage() + "\n" + this.h5Log;
        }
      }
      return false;
    })
}
//...
Enter fullscreen mode Exit fullscreen mode
// NAPI side code
//...
static void WebMessagePortCallback(const char *webTag, const ArkWeb_WebMessagePortPtr port, const ArkWeb_WebMessagePtr message, void *userData) {
  //...
}
//...
Enter fullscreen mode Exit fullscreen mode

Summary

Through this article, you have learned about the advanced features and applications of Huawei HarmonyOS ArkWeb, including the Web component size adaptive page content layout, Web component rendering modes, using front-end page JavaScript in the application, and the mutual invocation between the application side and the front-end page (C/C++). These features can help you better control the behavior of the Web component and improve the performance and user experience of your application.

Top comments (0)