【问题标题】:Javascript and DOM manipulation efficiency on RPi Win10 IoTRPi Win10 IoT 上的 Javascript 和 DOM 操作效率
【发布时间】:2026-02-12 06:45:01
【问题描述】:

背景

我使用 asp.net (C#) 和 html5/css3/javascript(带有一点 jQuery)创建了一个幻灯片应用程序。我正在尝试在 Windows Universal WebView 组件内运行 Windows 10(IoT 版本)的 Raspberry Pi 2 设备上显示此内容。

我遇到了幻灯片滞后的问题。我的幻灯片基于一个带有 3 个背景图像的 div:

  1. 顶部图片是幻灯片图片。显示为background-size: contain
  2. 中间图像是一种透明渐变,用于覆盖底部图像以产生影响。
  3. 底部图像是服务器在图像上传时生成的,是一个缩放和模糊的图像,旨在提供一种颜色热区的渐变飞溅映射。此过程中留下的任何图像伪影都将通过图像 #2 进行平滑处理。

问题

我用一行代码切换背景图片:

slide.style.backgroundImage = "url(" + slides[slideIndex % slides.length] + "), " +
                              "url(../images/egg-shell.png), " +
                              "url(" + blurred[slideIndex % blurred.length] + ")";

在我的浏览器中运行良好,但是,在 Raspberry Pi 上,底部图片中间图片叠加显示在顶部图片之前。

异常

我必须做几件事才能使这项工作与 Raspberry Pi 和 Webview 组件一起使用,我只列出这些是因为它们可能会导致我的问题:

  • 更改背景图片后,我必须将幻灯片元素的显示属性设置为无,然后返回块以重绘背景图片,否则它不会改变。
  • 我正在通过加载一组 JS Image 对象来预加载图像,这些对象具有由 web 服务指定的路径,然后等待每个图像完成报告 .onload 以开始幻灯片放映。

整个应用程序非常轻巧。如果需要,我可以提供它,但必须有一些简单的东西我错过了。如果我将每个图像加载到单独的 <img> 元素中然后设置 z-indexs,我不知道效率。我也不知道通过让图像加载到当前幻灯片后面的单独幻灯片中是否会提高效率。这就是为什么问题是关于 DOM 操作和 Javascript 的问题。无论如何,感谢您阅读这篇冗长的解释,希望您能提供帮助!

【问题讨论】:

  • 如果您要预先加载所有内容,为什么不在每张幻灯片上使用一个元素呢?这也为您提供了在幻灯片之间转换的各种不错的选择。
  • 如何过渡以获得最佳性能? Translate3d 将利用硬件加速,但与 z-index 相比,RPi 可能太难了。但我也不知道。
  • “最佳”取决于您可能需要试验的 WebView 的实现。对于即时过渡,您可能需要request an animation frame 并在回调中隐藏最后一张幻灯片并使用 CSS 显示下一张。如果不清楚,我可以写一个简单的例子。
  • 拜托,我试试看它是否有效。请记住,Windows 通用 WebView 组件以 IE11 文档模式呈现(有一些警告)。 Css3 动画在 RPi 上运行非常缓慢。我探索的大多数可行的解决方案都失败了这两个类别之一(IE11 兼容性或对 RPi 足够有效)。

标签: javascript performance dom background raspberry-pi


【解决方案1】:

像这样:http://jsfiddle.net/utwqsb45/ 或者如果你喜欢

$(function($){

var $slides = $('.slide');
  
function transition(){
    var $current = $('.slide.showing'),
        $next = $('.slide[data-number="' + parseInt($current.data('number') + 1) + '"]');
    if (!$next.length) {
        $next = $('.slide[data-number="1"]');
    }
    requestAnimationFrame(function(){
      $current.removeClass('showing');
      $next.addClass('showing');
    });
}
  
setInterval(transition, 1000);

})($);
.slide {
  width: 99%;
  height: 99%;
  position: absolute;
  top: 0;
  right: 0;
  left: 0;
  bottom: 0;
  display: none;
  margin: 0 auto;
}

.slide.showing {
  display: block;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
<div class="slide showing" data-number="1">one</div>
<div class="slide" data-number="2">two</div>
<div class="slide" data-number="3">three</div>

【讨论】:

  • 我已经有一些与此非常相似的东西,但它不起作用。我在制作幻灯片时没有问题。我在使幻灯片中的图像(使用 CSS3 多个背景堆叠)一次加载时遇到问题,即使使用预加载,绘制图像似乎也需要很长时间。
  • 您是否尝试过通过简单地将三个图像绝对定位在一个容器中来堆叠它们?
  • 是的,但这是行不通的,因为图像具有动态大小,因此将主幻灯片图像居中将非常困难。我最终删除了中间图像,并将底部元素设置为绝对位置,然后将顶部图像设置为显示块,最大宽度和最大高度为 100% 和边距:自动!虽然仍然存在性能问题。我将尝试加载事件驱动的操作(我已经做过,但我会再重构几次哈哈)
  • 哦,您可以将纯图像居中设置宽度容器中:jsfiddle.net/oLv6L99q 我认为更大的问题是欺骗 WebView 将图像预加载到它从中提取的任何缓冲区中,这可能如果你让它们在屏幕外“可见”(如顶部:-1000px)然后将它们移动到视图中,是否有可能?也许?