Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I prevent my WebView from causing lag in the parent Composable?

I have the following code:

@Composable
fun WebTest(modifier: Modifier) {
    val url = "https://www.google.com"
    val ctx = LocalContext.current

    Column(modifier = modifier) {
        Text("title", fontSize = 22.sp, modifier = Modifier.fillMaxWidth().height(44.dp))
        AndroidView(
            modifier = Modifier.fillMaxWidth().fillMaxHeight(), 
            factory = { WebView(ctx) }, 
            update = {
                it.loadUrl(url)
            }
        )
    }
}

In this case, the "title" Text always show after the WebView was loaded into the AndroidView, but it is supposed to be shown immediately.

If I comment out the code it.loadUrl(url), the "title" Text will never show.
If I change WebView to FrameLayout, it work fine.

Why the "title" Text cannot be show immediately?

like image 691
Jade Avatar asked Oct 21 '25 10:10

Jade


1 Answers

The AndroidView invocation is the bottleneck here. Even if you construct the View outside of the composition, there is a significant lag when the View is applied to the AndroidView. This results in a very slow recomposition, where the whole Composable will go blank until all nested Composables were laid out.

However, the LazyColumn is an exception here - as it lazily loads and lays out its children without affecting the recomposition of the parent Composable. This allows the following workaround:

@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun WebTest(modifier: Modifier = Modifier) {
    val url = "https://www.google.com"
    val ctx = LocalContext.current

    Column(modifier = modifier) {
        TopAppBar(
            title = { Text(text = "WebView Demonstration") },
        )
        LazyColumn(
            modifier = Modifier.weight(1f).fillMaxHeight(),
            userScrollEnabled = false  // to let the AndroidView consume scrolling

        ) {
            item {
                AndroidView(
                    modifier = Modifier.fillParentMaxSize(),
                    factory = { WebView(ctx) },
                    update = {
                        it.webViewClient = WebViewClient();
                        it.loadUrl(url)
                    }
                )

            }
        }
    }
}

Comparison without / with LazyColumn:

no LazyColumn with LazyColumn

like image 116
BenjyTec Avatar answered Oct 22 '25 23:10

BenjyTec



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!