CSS Sprites Performance

I have a static image 500x640 sitting in a folder in which 20 pieces 20 pieces with css-sprites, I set the background position for each part to be displayed, I need this kind of display to be able to manipulate each part later.

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; } 

I have performance issues. For example, in Opera and FF, images load very fast for about 1 second, in IE for about 3 seconds, but in Chrome it loads very slowly enter image description here

It takes about 17 seconds to display all fragments in Chrome.

The browser only makes one request to get the image, and not cut small pieces, why can it take so long in Chrome?

Can performance be improved? enter image description here

just did CTRL + Update and here is the weird download result: enter image description here

UPDATE: I just posted a sample here: http://bit.ly/TrcCdp

UPDATE: In my example, there is a JSON array, it contains 800 elements, so Iโ€™ll just find out if it has decreased, for example, 600-700 elements, the performance improves, but I donโ€™t care about 800 elements.

For example, when there are only 600 elements, this reduces the load in Chrome by about 6 seconds ....

Perhaps there might be a problem somewhere at the point where the note iteration of the template is performed?

+7
source share
3 answers

The problem is not the image. The image can be captured by preloading it at the top of any type of style sheet or script:

 <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 --> 

After that, the image is loaded in 170 ms (locally). However, the page still twitches after another 10-15 seconds, trying to decide what to do.

The root problem is that javascript is an absolute mess. File / file / function names are cryptic. Things in the middle of the page depend on the code at the end, depend on the code at the beginning, depend on the code at the end. The controller / view / model logic is all over the map. Global variables and multi-file communication ... hokay, </soapbox> , now to treat the symptom.

Problem 1: knockout binding before loading DOM

Put applyBindings in the domready callback:

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

Problem 2: foreach slow

Foreach knockout binding is incredibly slow with large datasets. You can try jQuery templates and move foreach inside the template as described in this SO question . It seems that time is reduced to about 3 seconds.

I really donโ€™t understand why this is necessary, since it seems to work perfectly with your current foreach, it just hangs forever, and the knockout does some magic in the background, as far as I can tell, it happens after the foreach completes.

Side Note: Do I need to reverse the visible array? I assume that you intend to use this later, since nothing in the current code needs it. If not, take it out and it will help performance (although it will not solve this problem).

Hi, hope this helps.

+4
source

This is kind of a weird rendering error between foreach binding and Chrome. I tried just adding a character to my template before the div and fixed the delay (but also messed up the layout).

A good way to fix this is to use something other than foreach . My repeat binding works well here and solves the delay problem.

Here is this section of your code using 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> 

Since repeat does not use the observable for $index , you will also need to change the getTopValue and getLeftValue functions to remove the parentheses () after index .

+2
source

You should also consider ordering the code that is called by the foreach loop. I do not know how often you call the getLeftValue and getTopValue , but they are rather unoptimized.

  • Try limiting function calls that give you the same result, use local caching vars as they are cheap
  • don't concatenate strings in large loops; this is slower than using an array to concatenate them.

I tried to optimize your two functions. You should see at least some improvement:

 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(""); } 
+1
source

All Articles