Cordova 在长时间 Javascript 期间冻结 UI 而
Cordova freeze UI during long Javascript while
我无法创建工作示例,但代码很简单。
配置
IDE: Visual studio 2017
目标平台: Windows x64
系统: Win 10
我的项目: Javascript // 空白应用程序 (Apache Cordova) // 版本。 6.3.1
HTML // index.html
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<header></header>
<main>
<div id="cal">
</div>
</main>
<footer>
<!-- ## this creates a simple pure css loader ## -->
<div class="progress">
<div class="indeterminate"></div>
</div>
<a href="#" class=".addItem">Add</a>
</footer>
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="scripts/platformOverrides.js"></script>
<script src="frameworks/jquery-3.2.1.min.js"></script>
<script src="frameworks/materialize/js/materialize.min.js"></script>
<script type="text/javascript" src="scripts/index.js"></script>
</body>
</html>
Javascript // index.js
(function () {
"use strict";
document.addEventListener( 'deviceready', onDeviceReady.bind( this ), false );
function onDeviceReady() {
$(document).ready(function () {
$('.addItem').on('click', function () {
setTimeout(function () {
loadCalendar();
}, 5000);
});
});
};
function loadCalendar() {
var i=0;
while (i <= 10000) {
var html = '<div class="row"></div>';
$('#cal').append(html);
i++;
}
}
} )();
应用程序启动并且 UI 按预期工作,progress
加载程序显示他的 css 动画。单击按钮 addItem
后全部工作 5 秒,然后 UI 冻结直到 while loop
结束。我觉得不正常,怎么解决?
谢谢
编辑
重要说明
我不希望在循环中更新DOM,上面这段代码不是真正的代码,它只是用于理解和测试。真正的循环要短得多,快得多,但仍然是个问题。
发生的情况是整个界面冻结,整个应用程序。 CSS 动画应该完全独立于 Javascript,但是它会卡住!
Here an example of what I expected
我希望这能更好地阐明这一点。
我认为这是意料之中的。您拨打
$('#cal').append(html)
10,001 次。每次执行此操作时,您都在修改 DOM,这是一项昂贵的操作。
如果你真的需要写出 10001 div class='row' 个元素,你最好将它们全部写入一个字符串,然后再进行一个追加。它仍然不理想,但如果不了解您要实现的目标,就很难找到更好的解决方案。
function loadCalendar() {
var i=0;
var html = '';
while (i <= 10000) {
html += '<div class="row"></div>';
i++;
}
$('#cal').append(html);
}
如评论中所述,所有循环声明都是阻塞程序,在循环完成之前-即使是最微不足道的悬停效果也无法响应。
JavaScript是线性的、同步的、单线程的进程。要避免冻结情况,您需要将循环操作移至单独的线程。
例如:在另一个文档的单独实例上!
我无法创建工作示例,但代码很简单。
配置
IDE: Visual studio 2017
目标平台: Windows x64
系统: Win 10
我的项目: Javascript // 空白应用程序 (Apache Cordova) // 版本。 6.3.1
HTML // index.html
<!DOCTYPE html>
<html>
<head>
</head>
<body>
<header></header>
<main>
<div id="cal">
</div>
</main>
<footer>
<!-- ## this creates a simple pure css loader ## -->
<div class="progress">
<div class="indeterminate"></div>
</div>
<a href="#" class=".addItem">Add</a>
</footer>
<script type="text/javascript" src="cordova.js"></script>
<script type="text/javascript" src="scripts/platformOverrides.js"></script>
<script src="frameworks/jquery-3.2.1.min.js"></script>
<script src="frameworks/materialize/js/materialize.min.js"></script>
<script type="text/javascript" src="scripts/index.js"></script>
</body>
</html>
Javascript // index.js
(function () {
"use strict";
document.addEventListener( 'deviceready', onDeviceReady.bind( this ), false );
function onDeviceReady() {
$(document).ready(function () {
$('.addItem').on('click', function () {
setTimeout(function () {
loadCalendar();
}, 5000);
});
});
};
function loadCalendar() {
var i=0;
while (i <= 10000) {
var html = '<div class="row"></div>';
$('#cal').append(html);
i++;
}
}
} )();
应用程序启动并且 UI 按预期工作,progress
加载程序显示他的 css 动画。单击按钮 addItem
后全部工作 5 秒,然后 UI 冻结直到 while loop
结束。我觉得不正常,怎么解决?
谢谢
编辑
重要说明
我不希望在循环中更新DOM,上面这段代码不是真正的代码,它只是用于理解和测试。真正的循环要短得多,快得多,但仍然是个问题。
发生的情况是整个界面冻结,整个应用程序。 CSS 动画应该完全独立于 Javascript,但是它会卡住!
Here an example of what I expected
我希望这能更好地阐明这一点。
我认为这是意料之中的。您拨打
$('#cal').append(html)10,001 次。每次执行此操作时,您都在修改 DOM,这是一项昂贵的操作。
如果你真的需要写出 10001 div class='row' 个元素,你最好将它们全部写入一个字符串,然后再进行一个追加。它仍然不理想,但如果不了解您要实现的目标,就很难找到更好的解决方案。
function loadCalendar() {
var i=0;
var html = '';
while (i <= 10000) {
html += '<div class="row"></div>';
i++;
}
$('#cal').append(html);
}
如评论中所述,所有循环声明都是阻塞程序,在循环完成之前-即使是最微不足道的悬停效果也无法响应。
JavaScript是线性的、同步的、单线程的进程。要避免冻结情况,您需要将循环操作移至单独的线程。
例如:在另一个文档的单独实例上!