一个非常非常非常大的div

时间:2014-12-08 10:48:19

标签: javascript html css google-chrome

对于我的项目(请参阅BigPictu.rebigpicture.js GitHub project),我必须处理一个非常非常非常大的<div>容器。

我知道使用我使用的简单方法可能会导致性能不佳,但我并不认为它主要存在于......仅限Chrome!

如果您测试this small page(请参阅下面的代码),则平移(点击+拖动)将为:

  • Firefox上的正常/平滑
  • 即使在Internet Explorer上也能正常/平滑
  • 在Chrome上非常慢(几乎崩溃)!

当然,我可以添加一些代码(在我的项目中),当你进行大量放大时,可能会隐藏可能非常大的字体大小的文本。但是,为什么Firefox和Internet Explorer正确处理它而不是Chrome?

在JavaScript,HTML或CSS中是否有办法告诉浏览器不要尝试为每个操作呈现整个页面(这里宽度为10000像素)?(仅渲染当前视口!)


<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="utf-8">
        <style>
            html, body {
                overflow: hidden;
                min-height: 100%; }

            #container {
                position: absolute;
                min-height: 100%;
                min-width: 100%; }

            .text {
                font-family: "Arial";
                position: absolute;
            }
        </style>
    </head>

    <body>
        <div id="container">
            <div class="text" style="font-size: 600px; left:100px; top:100px">Small text</div>
            <div class="text" style="font-size: 600000px; left:10000px; top:10000px">Very big text</div>
        </div>

        <script>
            var container = document.getElementById('container'), dragging = false, previousmouse;
            container.x = 0; container.y = 0;

            window.onmousedown = function(e) { dragging = true; previousmouse = {x: e.pageX, y: e.pageY}; }

            window.onmouseup = function() { dragging = false; }

            window.ondragstart = function(e) { e.preventDefault(); }

            window.onmousemove = function(e) {
                if (dragging) {
                    container.x += e.pageX - previousmouse.x; container.y += e.pageY - previousmouse.y;
                    container.style.left = container.x + 'px'; container.style.top = container.y + 'px';
                    previousmouse = {x: e.pageX, y: e.pageY};
                }
            }
        </script>
    </body>
</html>

7 个答案:

答案 0 :(得分:60)

更改为position: fixed似乎可以加快速度。

答案 1 :(得分:42)

使用transform代替top/left

container.style.transform = 'translate(' + container.x + 'px, ' + container.y + 'px)';

A live demo at jsFiddle

答案 2 :(得分:22)

  1. 回答第一个任务&#34;为什么&#34;。其中一个问题是字体大小。你有600000像素的字体大小,大多数浏览器会看到它太高并渲染得更小,而chrome尝试渲染原始大小。看起来像Chrome无法快速重绘您要求的样式的大字母。
  2. 但是结合Teemu和geert3的答案 - 使用变换和位置:固定,即使使用大字体也能让Chrome工作更加快速。

    1. 回答第二个问题:&#34;有没有办法......不要试图渲染整个页面&#34; - 您可以尝试对容器中的元素应用鼠标操作,而不是整个容器。
    2. 最大字体大小:http://jsfiddle.net/74w7yL0a/

      firefox 34 - 2 000 px
      chrome 39 - 1 000 000 px
      safari 8 - 1 000 000 px
      ie 8-11 - 1 431 700 px
      

答案 3 :(得分:4)

除了Teemu使用翻译的答案:

container.style.transform = 'translate(' + container.x + 'px, ' + container.y + 'px)';

你还应该使用其他供应商前缀,你可以通过在身体上使用它来解决这个问题:

height: 100%;
width: 100%;
position: relative;
overflow: hidden;

,这在html上:

height: 100%;
但是,这将禁用滚动。所以我要做的是,向主体添加mousedown事件,并在触发mousedown时使用css类应用这些样式,并在mouseup上删除该类。

答案 4 :(得分:2)

@ Teemus&#39;答案几乎可以做到。

transform translate3d 一起使用,而不是top/left

translate3d启用硬件加速。

container.style.transform = 'translate3d(' + container.x + 'px, ' + container.y + 'px, 0)';

A live demo at jsFiddle

答案 5 :(得分:1)

我对此进行了分析,发现原始问题与Chrome显示架构有关,并且使用后台线程来渲染页面。

如果你想要快速渲染,请进入chrome:flags,滚动到设置Impl-side绘画,然后设置&#34; Disabled&#34;,然后重新启动浏览器 - mousemove将是平滑的。

我发现如果你启用了FPS计数器,那么在这种情况下报告的FPS仍然非常高,即使实际的屏幕性能非常低。我的初步解释(不是Chrome显示架构专家)是,如果UI线程和显示在不同的线程上,那么在div的渲染中可能存在争用 - 在UI线程和渲染线程位于其上的情况下相同的线程,UI线程无法比UI线程可以呈现的更快地发送消息。

我建议将其归为Chrome错误。

答案 6 :(得分:1)

在div或包含div的表格上使用display: tabletable-layout:fixed。在HTML中:

  

HTML表模型的设计使得在作者的帮助下,用户代理可以递增地呈现表(即,当表行到达时),而不必在开始呈现之前等待所有数据。

     

为了让用户代理在一次传递中格式化表,作者必须告诉用户代理:

     

表格中的列数。有关如何提供此信息的详细信息,请参阅有关计算表中列数的部分。      这些列的宽度。有关如何提供此信息的详细信息,请参阅有关计算列宽的部分。

     

更确切地说,当使用COLGROUP和COL元素的组合指定列宽时,用户代理可以在单个过程中呈现表。如果以相对或百分比的形式指定任何列(请参阅有关计算列宽度的部分),则作者还必须指定表本身的宽度。

     

对于增量显示,浏览器需要列数及其宽度。表的默认宽度是当前窗口大小(width =“100%”)。这可以通过设置TABLE元素的width属性来更改。默认情况下,所有列都具有相同的宽度,但您可以在表数据开始之前指定具有一个或多个COL元素的列宽。

     

剩下的问题是列数。有些人建议等到收到表的第一行,但如果单元格有很多内容,这可能需要很长时间。总的来说,当需要增量显示时,更有意义的是让作者明确指定TABLE元素中的列数。

     

作者仍然需要一种告诉用户代理是否使用增量显示或自动调整表格大小以适应单元格内容的方法。在两次通过自动调整大小模式中,列数由第一次通过确定。在增量模式中,必须预先说明列数(使用COL或COLGROUP元素)。

和CSS:

  

17.5.2.1固定表格布局

     

使用此(快速)算法,表格的水平布局不依赖于单元格的内容;它只取决于表格的宽度,列的宽度,边框或单元格间距。

     

可以使用'width'属性显式指定表的宽度。值'auto'(对于'display:table'和'display:inline-table')表示使用自动表格布局算法。但是,如果表是正常流程中的块级表('display:table'),则UA可以(但不必)使用10.3.3的算法来计算宽度并应用固定表格布局,即使指定的宽度为“auto”。

<强>参考