Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Preload a WebView page #1

Open
QingAn opened this issue Jan 10, 2023 · 1 comment
Open

Preload a WebView page #1

QingAn opened this issue Jan 10, 2023 · 1 comment

Comments

@QingAn
Copy link

QingAn commented Jan 10, 2023

{{Preload a WebView page}} explainer

Authors:

  • Qing An, Alibaba

Use-case / Challenge

Load a WebView page

Introduction

The goal is to support Preload a WebView page.
The basic idea is to change the serial execution in loading a WebView page to parallel execution, and part of the execution is running by Native.

Goals [or Motivating Use Cases, or Scenarios]

To reduce the time duration of white screen when loading a WebView page.

Non-goals

Pre-request the data (JSON, XML, etc.) is not covered.

[API 1]

An independent JS Engine needs to be created, to support the native side render. It is similar to the Service Worker in PWA. Here we call it App Worker.

App worker generates HTML string.

const content = renderToString();

[API 2]

App Worker sends message to WebView page, or vise versa.

postMessage({
message: 'hello world'
}, 'page1');

[API 3]

App Worker or WebView receive message.

addEventListener('message', (event) => {
if (event.origin === 'page1') {
console.log(`data: ${event.data}`);
    }
});

Key scenarios

Scenario 1

Native side render generates the HTML string and send to WebView page.

// App Worker listens to the page appear event, to ensure WebView is ready.
addEventListener("pageappear", (event) => {

	// Generate HTML string
	const content = renderToString();

	// Send HTML string to WebView page
	const params = {
		type: 'nsr_msg',
		content: content
	};
	
	postMessage({
		message: params
	}, 'page1');
});

Scenario 2

WebView listens to the Native side render event, and display the content.

addEventListener("message", (event) => {
const data = event.data;
if ('nsr_msg' === data.type) {
document.body.innerHTML = data.content;
}
});

Detailed design discussion

[Tricky design choice #1]

This proposal aims to bring auxiliary function in Native side to enhance the performance on loading a WebView page.

The reason of long white screen is due to serial execution in loading a WebView page. The duration of white screen directly depends on the time cost from routing intercept to JS download & parse & exec.
image

The goal is to change the serial execution in loading a WebView page to parallel execution, and part of the execution is running by Native.
image

In detail, the concept of native side render is introduced, which is to run the fetch docs, JS downloads & parse & exec, and request data in Native side instead of in WebView.

In the step of Routing intercept, the WebView initialization and native side render are both started in parallel. There will be two possible cases. One is native side render has successfully generated the first page HTML string before WebView initialization is completed, and the other is native side render has not generated the first page HTML string in time or confronted error. If the former case, WebView obtains the first page HTML string from native side render and run the loadHTMLString to render the first page. If the latter case, WebView still runs the normal procedure and run the loadURL.

Considered alternatives

[Alternative 1]

To support preload a target URL in WebView.
Note: this needs input from WebView vendors.

References & acknowledgements

Many thanks for valuable feedback and advice from:

  • Rayan Kanso
@QingAn
Copy link
Author

QingAn commented Jan 31, 2023

Copy comment from Rayan in previous email:

  • The AppWorker is a bit under-specified, I'm not sure I understand the difference with a regular ServiceWorker.
  • The solutions oversimplify the interaction with request/response headers & cookies, which are vital to how web pages work.
  • It would be nice to also propose a WebView-level API, rather than only changes from the web platform side of things. Maybe something as simple as populating the WebView with Request/Response pairs from the host app?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant