草庐IT

javascript - 检测在不可见和在视口(viewport)外时是否对canvas/css3动画进行了优化

coder 2025-03-09 原文

我假设使用HTML5中的所有这些硬件加速动画,实际上不会渲染在视口(viewport)之外运行的动画。我希望能够检测到是否正在发生。

我尝试在每秒移动100px的对象上循环使用webkitCSSMatrix来尝试确定每个刻度线移动了多少像素,但是如果我将动画移出视线则没有区别。

有任何想法吗?

最佳答案

您可以使用单独的计时器测试来查看伪经验方面在外部和内部绘制的对象之间的差异(计时器实际上并不能证明任何东西,但可以为您提供强大的indisium)。

但是,了解 Canvas 的工作原理也可以为您提供坚实的指导。例如, Canvas 是一个简单的位图,没有任何内部管理(屏幕刷新之外)。这意味着您不可能实际写任何超出其范围的内容,因为这会破坏内存。换句话说,由于这个非常基本的原因,会发生裁剪。

对于计时器测试,您可以运行一个简单的测试,在该测试中您在边界内绘制某些内容,然后在边界外绘制相同的偏移量:

更新:似乎是因为我误解了这个问题,所以问题通常在 Canvas 位图之外,而不是在视口(viewport)之外。

因此,无论外部视口(viewport)是 Canvas 还是外部视口(viewport),都进行了一次小小的更新-

描述浏览器更新的过程比仅 Canvas 要复杂一些,但原则上:屏幕上不可见的所有内容都会被裁剪(未绘制)。似乎很明显,而且有点类似,但这并不意味着其他地方没有任何更新。

浏览器可能会(也可能不会)保留要绘制到屏幕上的元素的内部位图(如果部分 View ,则将其剪裁;如果外部 View ,则将其剪断)。

主要区别在于,即使有必要,浏览器也可以(取决于实现方式)更新此内部位图,即使该位图不可见。受此元素的位置,尺寸和堆栈位置影响的DOM重排。

因此,您可能会在某些浏览器中看到性能下降的消息。浏览器还可以选择仅在可见时更新位图内容,而在不可见时仅调整大小。

不幸的是,由于它取决于许多因素(固定/绝对元素与非固定/绝对,什么内容,浏览器实现,硬件是否加速等),因此没有准确的方法来衡量是否发生这种情况。

canvas元素是朴素的,因此很容易预测,但是如果在 Canvas 位于视口(viewport)之外时在 Canvas 上绘制一些东西,它将被绘制到其位图并在再次查看 Canvas 时显示。但是,尝试调整窗口大小, Canvas 的内容将消失(在某些浏览器中),您将需要重新绘制。这意味着与其他元素相比, Canvas 在该过程中的参与至少少一层。

我希望这是有道理的-道歉,我有点没准备好做这个解释,因为我刚刚意识到自己误解了这个问题。

更新结束

Here is a simple online test

在此测试中,我们在一个按钮内部,另一个按钮内部绘制了10,000个填充的矩形。这不是一项科学准确的测试,但是它清楚地显示出一种差异,因为当绘图超出其所做的所有事情时,它就是检查边界并且不更新位图数组中的任何内容-

function draw(x) {

    console.time('timer');
    var cnt = 10000, w = ez.width, h = ez.height;

    while(cnt--) {
        ctx.fillRect(x, 0, w, h);
    }

    console.timeEnd('timer');
}

inside.addEventListener('click', function(){draw(0)}, false);
outside.addEventListener('click', function(){draw(ez.width)}, false);

使用控制台计时器和Chrome在蜗牛计算机上执行此操作的结果是:

timer: 3156.000ms
timer: 112.000ms



这是(内部:外部)3156:112的比率-或-实际绘制内容时,它花费了28倍的时间。这表明浏览器仅花费时间检查边界,但如果超出边界,则实际上不会移动内存中的任何数据。

另一种方法类似于已经回答的方法,以使用内置工具。但是为此,请使用探查器:

转到控制台,然后选择配置文件和CPU配置文件:

  • 开始记录一个配置文件,然后单击“内部”按钮。完成后停止
  • 开始记录第二个配置文件,然后单击“外部”按钮。完成后停止

  • 现在您可以比较两个轮廓-对于内部图纸,我得到了以下结果:

    在这里,您可以看到它使用了大约9.92%的比例绘制填充的矩形(未针对空闲时间进行调整)。

    在第二个配置文件中,我得到了:

    在这里只有1.24%被用来“绘制”。

    比率是9.92:1.24或8倍。在这两种情况下,当您将某些内容更新到内存(位图缓冲区)而不是更新到内存时,您都可以看到性能上的巨大差异。

    那么屏幕外的 Canvas 呢?这些情况也是一样,因为需要在屏幕外 Canvas 的缓冲区中更新某些内容。它保存的“唯一”内容是对浏览器主缓冲区的更新,该更新可能会或可能不会进行优化。

    关于javascript - 检测在不可见和在视口(viewport)外时是否对canvas/css3动画进行了优化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17937516/

    有关javascript - 检测在不可见和在视口(viewport)外时是否对canvas/css3动画进行了优化的更多相关文章

    1. ruby - capybara field.has_css?匹配器 - 2

      我在MiniTest::Spec和Capybara中使用以下规范:find_field('Email').must_have_css('[autofocus]')检查名为“电子邮件”的字段是否具有autofocus属性。doc说如下:has_css?(path,options={})ChecksifagivenCSSselectorisonthepageorcurrentnode.据我了解,字段“Email”是一个节点,因此调用must_have_css绝对有效!我做错了什么? 最佳答案 通过JonasNicklas得到了答案:No

    2. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

      我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

    3. css - 用 watir 检查标签类? - 2

      我有一个div,它根据表单是否正确提交而改变。我想知道是否可以检查类的特定元素?开始元素看起来像这样。如果输入不正确,添加错误类。 最佳答案 试试这个:browser.div(:id=>"myerrortest").class_name更多信息:http://watir.github.com/watir-webdriver/doc/Watir/HTMLElement.html#class_name-instance_method另一种选择是只查看具有您期望的类的div是否存在browser.div((:id=>"myerrortes

    4. Unity 3D 制作开关门动画,旋转门制作,推拉门制作,门把手动画制作 - 2

      Unity自动旋转动画1.开门需要门把手先动,门再动2.关门需要门先动,门把手再动3.中途播放过程中不可以再次进行操作觉得太复杂?查看我的文章开关门简易进阶版效果:如果这个门可以直接打开的话,就不需要放置"门把手"如果门把手还有钥匙需要旋转,那就可以把钥匙放在门把手的"门把手",理论上是可以无限套娃的可调整参数有:角度,反向,轴向,速度运行时点击Test进行测试自己写的代码比较垃圾,命名与结构比较拉,高手轻点喷,新手有类似的需求可以拿去做参考上代码usingSystem.Collections;usingSystem.Collections.Generic;usingUnityEngine;u

    5. ruby - 在参数为 `yield self` 的方法中使用 `&block` 和在没有参数 `yield self` 的方法中使用 `&block` 有什么区别吗? - 2

      我明白了defa(&block)block.call(self)end和defa()yieldselfend导致相同的结果,如果我假设有这样一个blocka{}。我的问题是-因为我偶然发现了一些这样的代码,它是否有任何区别或者是否有任何优势(如果我不使用变量/引用block):defa(&block)yieldselfend这是一个我不理解&block用法的具体案例:defrule(code,name,&block)@rules=[]if@rules.nil?@rules 最佳答案 我能想到的唯一优点就是自省(introspecti

    6. ruby-on-rails - 使用 javascript 更改数据方法不会更改 ajax 调用用户的什么方法? - 2

      我遇到了一个非常奇怪的问题,我很难解决。在我看来,我有一个与data-remote="true"和data-method="delete"的链接。当我单击该链接时,我可以看到对我的Rails服务器的DELETE请求。返回的JS代码会更改此链接的属性,其中包括href和data-method。再次单击此链接后,我的服务器收到了对新href的请求,但使用的是旧的data-method,即使我已将其从DELETE到POST(它仍然发送一个DELETE请求)。但是,如果我刷新页面,HTML与"new"HTML相同(随返回的JS发生变化),但它实际上发送了正确的请求类型。这就是这个问题令我困惑的

    7. ruby - 检测由 RSpec、Ruby 运行的代码 - 2

      我想知道我的代码是否在rspec下运行。这可能吗?原因是我正在加载一些错误记录器,这些记录器在测试期间会被故意错误(expect{x}.toraise_error)弄得乱七八糟。我查看了我的ENV变量,没有(明显的)测试环境变量的迹象。 最佳答案 在spec_helper.rb的开头添加:ENV['RACK_ENV']='test'现在您可以在代码中检查RACK_ENV是否经过测试。 关于ruby-检测由RSpec、Ruby运行的代码,我们在StackOverflow上找到一个类似的问题

    8. ruby - 使用 Ruby Daemons gem 检测停止 - 2

      我正在使用rubydaemongem。想知道如何向停止操作添加一些额外的步骤?希望我能检测到停止被调用,并向其添加一些额外的代码。任何人都知道我如何才能做到这一点? 最佳答案 查看守护程序gem代码,它似乎没有用于此目的的明显扩展点。但是,我想知道(在守护进程中)您是否可以捕获守护进程在发生“停止”时发送的KILL/TERM信号...?trap("TERM")do#executeyourextracodehereend或者你可以安装一个at_exit钩子(Hook):-at_exitdo#executeyourextracodehe

    9. ruby-on-rails - Assets 管道损坏 : Not compiling on the fly css and js files - 2

      我开始了一个新的Rails3.2.5项目,Assets管道不再工作了。CSS和Javascript文件不再编译。这是尝试生成Assets时日志的输出:StartedGET"/assets/application.css?body=1"for127.0.0.1at2012-06-1623:59:11-0700Servedasset/application.css-200OK(0ms)[2012-06-1623:59:11]ERRORNoMethodError:undefinedmethod`each'fornil:NilClass/Users/greg/.rbenv/versions/1

    10. ruby-on-rails - Rails - 理解 application.js 和 application.css - 2

      rails新手。只是想了解\assests目录中的这两个文件。例如,application.js文件有如下行://=requirejquery//=requirejquery_ujs//=require_tree.我理解require_tree。只是将所有JS文件添加到当前目录中。根据上下文,我可以看出requirejquery添加了jQuery库。但是它从哪里得到这些jQuery库呢?我没有在我的Assets文件夹中看到任何jquery.js文件——或者直接在我的整个应用程序中没有看到任何jquery.js文件?同样,我正在按照一些说明安装TwitterBootstrap(http:

    随机推荐