maq
maq
  • 发布:2016-03-10 17:20
  • 更新:2016-08-13 23:13
  • 阅读:3700

【BUG】新创建的 webview 在第一次 show 的时候会闪白

分类:HTML5+

注意到一个现象,新创建的 webview 在第一次 show 的时候会闪白,除非使用 pop-in 方式显示。测试源代码如下:

flicker-index.html

<!DOCTYPE html>  
<html>  
<head>  
<meta charset="utf-8">  
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />  
<title>main webview</title>  
<script src="js/mui.js"></script>  
<script type="text/javascript">  
mui.init();  
mui.plusReady(function() {  
    mui('#btn-load')[0].addEventListener('tap', function() {  
        plus.webview.create('flicker-subview.html', 'flicker-subview', {  
            hardwareAccelerated: true, // 这个选项对结果没有影响  
            render: 'always' // 这个选项对结果也没有影响  
        });  
    });  
});  
</script>  
</head>  
<body style="margin:0px">  
<button id="btn-load">load subview</button>  
<div style="height:300px; background-color:black; color:white">  
    验证结论:新创建的 webview 在第一次 show 的时候会闪白,除非使用 pop-in。  
</div>  
</body>  
</html>

flicker-subview.html

<!DOCTYPE html>  
<html>  
<head>  
<meta charset="utf-8">  
<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />  
<title>sub webview</title>  
<script src="js/mui.js"></script>  
<script type="text/javascript">  
mui.init();  
mui.plusReady(function() {  
    mui('#btn-close')[0].addEventListener('tap', function() {  
        plus.webview.currentWebview().close();  
    });  
    var me = plus.webview.currentWebview();  
    me.show('none'); // flicker  
//  me.show('slide-in-right', 300); // flicker  
//  me.show('pop-in', 300); // no flicker  
});  
</script>  
</head>  
<body style="margin:0px">  
<button id="btn-close">close me</button>  
<div style="height:300px; background-color:black"></div>  
</body>  
</html>

测试环境为 Genymotion 模拟器 + Android 4.2.2/4.4.4

2016-03-10 17:20 负责人:无 分享
已邀请:
maq

maq (作者)

我个人的理解是这样的:webview 被创建之后,DOM 已经加载完毕(plusReady),但实际上的渲染过程(render)只完成了 reflow 部分,而 repaint 部分由于 webview 尚未 show 所以被搁置了。

接下来,当 show 的时候,系统并没有先让 webview 完成首次 repaint 就直接把窗口内容拍到屏幕上了,这样实际显示的是窗口底色,也就是白屏,随后 repaint 动作,屏幕显示内容恢复正常。这就是闪白的原因。

而 pop-in 之所以没有问题,是因为 pop-in 首先对 webview 做了一次 capture,capture 本身就是一个 repaint 过程,所以拿到的直接是正确的内容。

  • 3***@qq.com

    我现在遇到的问题是,A页面我使用的预加载,先显示B页面。在B页面点击按钮,显示A关闭B。这时候在A显示的时候会白屏一会,然后A才会显示出来。

    2020-03-03 11:52

maq

maq (作者)

记得以前在另一个帖子里参与了一个相关的话题:页面切换后才渲染数据【已解决】

对比分析了一下,两个帖子描述的问题现象虽然是相反的(那个帖子的结论是只有 pop-in 有问题,而这里的情况是只有 pop-in 没问题),但其背后的原因很可能是紧密相关的。

running

running - 生命不息,折腾不止

预加载的界面,在性能稍微差点的手机上,第一次显示出来的时候,会闪白一下

该问题目前已经被锁定, 无法添加新回复