【问题标题】:CSS Sprites performanceCSS Sprites 性能
【发布时间】:2012-08-23 06:30:45
【问题描述】:

我有 500x640 的静态图像位于由 20x20 块和 css 精灵组成的文件夹中,我正在设置背景位置来显示每一块,我需要这样的显示以便以后能够对每一块进行操作。

css:

   .piece
        {
            width: 20px;
            height: 20px;
            display: inline-block;
            //display: inline;
            //zoom:1;
        }        

    .ob { background-image: url("/Images/ob.jpg");}

js:

<script id="flipTemplate" type="text/html">
    <div class="piece ob" data-bind="style: { backgroundPosition: viewModel.getLeftValue($index) + ' ' + viewModel.getTopValue($index) }, attr: {cond: Cond, id: Id }, click: viewModel.setClick ">
                </div>
</script>
<script type="text/javascript">
    viewModel = {
        flips: ko.observableArray([]),      

        setClick: function (data, e) {
            e.preventDefault();            
            //doing click
        },

        getLeftValue: function (index) {

            var position = 0;

            var currentLine = div(index(), 25);

            if (currentLine > 0)
                return '-' + (index() - (currentLine * 25)) * 20 + 'px';
            else
                return '-' + index() * 20 + 'px';
        },

        getTopValue: function (index) {

            return '-' + (div(index(), 25)) * 20 + 'px';
        }
    };    

    ko.applyBindings(viewModel);
</script>
function div(val, by){
    return (val - val % by) / by;
}

所以我遇到了一些性能问题。 例如,在 Opera 和 FF 中加载非常快,大约 1 秒,在 IE 中大约 3 秒,但在 Chrome 中加载非常慢

在 Chrome 中显示所有片段大约需要 17 秒...

浏览器只执行一个请求来获取图像,而不是从中切割小块,为什么在 Chrome 中可能需要这么长时间?

有什么方法可以提高性能吗?

刚刚做了 CTRL+Refresh 和这里奇怪的加载结果:

更新: 我只是在这里放了一个示例:http://bit.ly/TrcCdp

更新: 在我的示例中有 JSON 数组,它包含 800 个元素,所以我只是找出如果我减少它,例如 600-700 个元素,性能会变得更好,但无论如何我需要 800 个元素。

例如,当只有 600 个元素时,它会将 Chrome 中的负载减少到大约 6 秒....

所以可能是淘汰迭代模板的某个地方的问题?

【问题讨论】:

  • 抱歉,图片有点小。你的精灵有多大?
  • @canon 如果您右键单击图像并按打开,它将以实际大小打开 (i.stack.imgur.com/WGdAr.jpg)。我的精灵是 83.78kb。
  • @SLaks 我会看看我能做什么,这可能需要一些时间。
  • 这很奇怪,你得到一个 304 Not Modified 响应,但它需要 17 秒才能加载。手动加载图像(例如导航到它)是否也需要很长时间?
  • 我认为问题与您的图片无关。你为什么在js之后请求图像?先放css和图片再放js,看看问题会不会继续..

标签: javascript css performance css-sprites knockout-2.0


【解决方案1】:

问题不在于图像。可以通过在顶部任何样式表或脚本标记之前放置预加载来修复图像:

<meta name="viewport" content="width=device-width">

<script type="text/javascript">
    var img = new Image();
    img.src = 'TestApp_files/obm000.jpg';
</script>

<link href="TestApp_files/jquery00.css" rel="stylesheet">
<link href="TestApp_files/jquery01.css" rel="stylesheet">
<!-- ad nauseum -->

在此之后,图像会在 170 毫秒(本地)内加载。但是,在尝试决定要做什么之后,该页面仍然会再混乱 10 到 15 秒。

根本问题是 javascript 绝对是一团糟。图像/文件/函数名称是神秘的。页面中间的东西取决于末尾的代码取决于开头的代码取决于末尾的代码。控制器/视图/模型逻辑遍布地图。全局变量和多文件耦合...呵呵,&lt;/soapbox&gt;,现在开始治疗症状。

问题 1:在 DOM 加载之前绑定敲除

将 applyBindings 放入 domready 回调中:

jQuery(function($) {
   ko.applyBindings(viewModel);
});

问题 2:foreach 很慢

对于大型数据集,淘汰赛 foreach 绑定非常慢。您可以尝试使用 jQuery 模板并将 foreach 移动到模板中,as described in this SO question。它似乎将时间缩短到大约 3 秒。

我真的不明白为什么这是必要的,因为它似乎与您当前的 foreach 渲染良好,它只是永远挂起,而淘汰赛在后台做了一些魔法,据我所知,发生在 foreach 完成后.

旁注:是否有必要将翻转放入可观察数组?我假设您打算稍后使用它,因为当前代码中不需要它。如果没有,把它拿出来,它会提高性能(虽然它不会解决这个问题)。

干杯,我希望这会有所帮助。

【讨论】:

    【解决方案2】:

    这是foreach 绑定和 Chrome 之间的某种奇怪的渲染错误。我尝试在 div 之前的模板中添加一个字符,这修复了延迟(但也弄乱了布局)。

    解决此问题的一个好方法是使用foreach 以外的其他内容。我的repeat binding在这里运行良好,解决了延迟问题。

    这是使用 repeat 的代码部分:

    <div class="condListHolder" style="width:558px">
        <div class="cond2" title="Click to flip" data-bind="repeat: flips">
            <div class="piece obm" data-bind="
              style: { backgroundPosition: getLeftValue($index) + ' ' + getTopValue($index) },
              attr: {cond: $item().cond, id: $item().Id },
              click: setClick "></div>
        </div>
    </div>
    

    因为repeat 不使用$index 的可观察对象,所以您还需要更改getTopValuegetLeftValue 函数以在index 之后取出括号()

    【讨论】:

      【解决方案3】:

      您还应该考虑简化由 foreach 循环调用的代码。我不知道你多久调用一次getLeftValuegetTopValue 方法,但它们都没有经过优化。

      • 尝试限制给您相同结果的函数调用,使用本地变量进行缓存,因为它们很便宜
      • 不要在大循环中连接字符串,这比使用数组连接它们要慢。

      我尝试优化您的两个功能。您应该至少会看到一些改进:

      getLeftValue: function (index) {
      
          var position = 0,
              realIndex = index(),
              currentLine = div(realIndex, 25);
      
      
          if (currentLine > 0)
              return ["-", (realIndex - (currentLine * 25)) * 20, "px"].join("");
          else
              return ["-", realIndex, "px"].join("");
      },
      
      getTopValue: function (index) {
      
          return ["-",(div(index(), 25)) * 20,"px"].join("");
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-09-26
        • 1970-01-01
        • 1970-01-01
        • 2011-06-30
        • 2010-10-24
        • 1970-01-01
        • 2012-10-02
        • 2012-09-06
        相关资源
        最近更新 更多