<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>BBProject.net &#187; optymalizacja</title>
	<atom:link href="http://www.bbproject.net/tag/optymalizacja/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.bbproject.net</link>
	<description>Programowanie, webmastering, informatyka</description>
	<lastBuildDate>Tue, 01 Mar 2011 20:35:37 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Optymalizacja działań matematycznych w Delphi</title>
		<link>http://www.bbproject.net/2010/06/optymalizacja-dzialan-matematycznych-w-delphi/</link>
		<comments>http://www.bbproject.net/2010/06/optymalizacja-dzialan-matematycznych-w-delphi/#comments</comments>
		<pubDate>Tue, 01 Jun 2010 05:29:36 +0000</pubDate>
		<dc:creator>M@ster</dc:creator>
				<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[delphi]]></category>
		<category><![CDATA[optymalizacja]]></category>
		<category><![CDATA[potęgowanie]]></category>
		<category><![CDATA[power]]></category>
		<category><![CDATA[sqr]]></category>
		<category><![CDATA[sqrt]]></category>

		<guid isPermaLink="false">http://www.bbproject.net/?p=353</guid>
		<description><![CDATA[Mnożenie, potęgowanie, pierwiastkowanie, wszystkie te operacje trwają ułamek sekundy na obecnych maszynach, ułamek sekundy do czasu gdy nie musimy wykonać tysięcy czy miliony iteracji danego działania. W takiej sytuacji odpowiedni dobór użytych funkcji może mieć duży wpływ na czas trwania całej operacji. W tym wpisie pokaże jakich błędów unikać pisząc w Delphi skomplikowane działania, aby [...]]]></description>
			<content:encoded><![CDATA[<p><img class="size-thumbnail wp-image-354 alignleft" title="Sqrt" src="http://www.bbproject.net/wp-content/uploads/2010/05/sqrt-160x87.png" alt="" width="160" height="87" />Mnożenie, potęgowanie, pierwiastkowanie, wszystkie te operacje trwają ułamek sekundy na obecnych maszynach, ułamek sekundy do czasu gdy nie musimy wykonać tysięcy czy miliony iteracji danego działania. W takiej sytuacji odpowiedni dobór użytych funkcji może mieć duży wpływ na czas trwania całej operacji.</p>
<p>W tym wpisie pokaże jakich błędów unikać pisząc w Delphi skomplikowane działania, aby nie marnować czasu użytkownika końcowego naszej aplikacji. Do dzieła!</p>
<p><span id="more-353"></span></p>
<h4>Stałe</h4>
<p>Zacznijmy od rzeczy najprostszej, wykluczania operacji których wynik jest zawsze taki sam. Głupota? Prosty przykład, obliczenia w których występuje liczba PI podniesiona do kwadratu. Wartość tego wyrażenia jest zawsze taka sama, gdyż PI wynosi zawsze tyle samo.</p>
<pre class="brush: delphi">procedure TForm1.Button1Click(Sender: TObject);
var
  k: Double;
begin
  k := GetTickCount * Sqr(PI) + 4;
end;</pre>
<p>W takiej sytuacji zamiast podnosić 3,14 za każdym razem do kwadratu, najlepiej wyliczyć sobie tą wartość chociażby na systemowym kalkulatorze i zadeklarować nową stałą. Rzecz jasna, jak wcześniej wspomniałem, ma to sens tylko gdy wykonujemy naprawdę dużo obliczeń &#8211; inaczej jest to sztuka dla sztuki.</p>
<pre class="brush: delphi">procedure TForm1.Button1Click(Sender: TObject);
const
  PI_2 = 9.8696044010893586188344909998762;
var
  k: Double;
begin
  k := GetTickCount * PI_2 + 4;
end;
</pre>
<h4>Unikanie dzielenia</h4>
<p>Swego czasu, wyczytałem iż lepiej jest przykładowo mnożyć razy 0,5 niż dzielić przez 2. Próbowałem potwierdzić to różnymi testami, ale za każdym razem dostawałem identyczny wynik. Strzelam że obecne procesory lepiej sobie radzą z dzieleniem w stosunku do mnożenia liczb zmiennoprzecinkowych niż kiedyś.</p>
<p>Dlatego też porada ta nie ma dzisiaj większego sensu, ale warto o niej pamiętać.</p>
<h4>Power, Sqr, Sqrt</h4>
<p>Funkcja <em>Power</em>, analogicznie do swojej nazwy kryje w sobie dużą moc <img src='http://www.bbproject.net/wp-includes/images/smilies/icon_wink.png' alt=';)' class='wp-smiley' /> , nie mniej, należy się jej wystrzegać jak ognia. <em>Power</em> przyjmuje 2 argumenty, pierwszym jest liczba którą chcemy podnieść do potęgi, a drugim wykładnik potęgi.</p>
<p>Daje to ogromne możliwości z uwagi na fakt iż jest to liczba zmiennoprzecinkowa. Nie mniej, w sytuacji w której podnosimy liczbę do potęgi drugiej, bądź wyciągamy pierwiastek stopnia drugiego bezwzględnie stosujmy funkcje <em>Sqr</em> oraz <em>Sqrt</em>. Pierwiastek 4 stopnia? Zagnieżdżone dwie funkcję <em>Sqrt</em> będą na pewno szybsze niż jeden <em>Power</em>.</p>
<p>Oto małe porównanie szybkości wykonywania się poszczególnych operacji:</p>
<table>
<tbody>
<tr>
<th>Funkcja</th>
<th>Czas wykonania</th>
</tr>
<tr>
<td>Sqr(x)</td>
<td>0,0547ms</td>
</tr>
<tr>
<td>Sqrt(x)</td>
<td>0,6396ms</td>
</tr>
<tr>
<td>Power(x, 2)</td>
<td>0,8642ms</td>
</tr>
<tr>
<td>Power(x, 0.5)</td>
<td>3,9702ms</td>
</tr>
</tbody>
</table>
<p>I na koniec wynik testu z pierwiastkiem czwartego stopnia:</p>
<table>
<tbody>
<tr>
<th>Funkcja</th>
<th>Czas wykonania</th>
</tr>
<tr>
<td>Sqrt(Sqrt(x))</td>
<td>1,7472ms</td>
</tr>
<tr>
<td>Power(x, 0.25)</td>
<td>4,5896ms</td>
</tr>
</tbody>
</table>
<h4>Podsumowanie</h4>
<p>Liczę że te kilka porad pozwoli Wam na optymalizację wielokrotnie wykonywanych działań matematycznych w Delphi. Oczywiście należy też pamiętać o doprowadzeniu danego równania do jak najprostszej postaci przed przystąpieniem do implementacji w programie.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bbproject.net/2010/06/optymalizacja-dzialan-matematycznych-w-delphi/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>If&#8230;else czy return?</title>
		<link>http://www.bbproject.net/2010/03/if-else-czy-return/</link>
		<comments>http://www.bbproject.net/2010/03/if-else-czy-return/#comments</comments>
		<pubDate>Mon, 15 Mar 2010 11:03:18 +0000</pubDate>
		<dc:creator>M@ster</dc:creator>
				<category><![CDATA[Laboratorium]]></category>
		<category><![CDATA[Programowanie]]></category>
		<category><![CDATA[funkcja]]></category>
		<category><![CDATA[instrukcja warunkowa]]></category>
		<category><![CDATA[optymalizacja]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://www.bbproject.net/?p=112</guid>
		<description><![CDATA[Trudno wymyślić sensowny tytuł dla zagadnienia które chcę opisać. Zawsze zastanawiało mnie czy pisząc w PHP funkcję która początkowo przeprowadza walidację przekazanych argumentów, stosować konstrukcję typu: function nazwa($argument) { if (warunek) { return FALSE; } ... ciało funkcji } &#8230;czy też: function nazwa($argument) { if (warunek) { return FALSE; } else { ... ciało funkcji [...]]]></description>
			<content:encoded><![CDATA[<p>Trudno wymyślić sensowny tytuł dla zagadnienia które chcę opisać. Zawsze zastanawiało mnie czy pisząc w PHP funkcję która początkowo przeprowadza walidację przekazanych argumentów, stosować konstrukcję typu:</p>
<pre class="brush: php">function nazwa($argument)
{
  if (warunek)
  {
    return FALSE;
  }
  ... ciało funkcji
}</pre>
<p>&#8230;czy też:</p>
<pre class="brush: php">function nazwa($argument)
{
  if (warunek)
  {
    return FALSE;
  }
  else
  {
    ... ciało funkcji
  }
}</pre>
<p>Intuicyjnie może się wydawać że pierwszy metoda będzie działać szybciej, gdyż po spełnieniu warunku wychodzimy od razu z funkcji &#8211; parser nie musi przetwarzać reszty kodu. Z kolei w drugiej, mimo iż to co znajduje się w bloku <em>else</em> się nie wykona i tak musi zostać przeczytane przez PHP. Jak jest w rzeczywistości? Sprawdźmy to!</p>
<p><span id="more-112"></span>Pierwsza konstrukcja, w której po spełnieniu warunku wykluczającego dalsze przetwarzanie, od razu zwracamy wartość jest na pewno bardziej przejrzysta. Nie musimy ciągnąć za sobą nawiasu kończącego blok <em>else</em> przez całą resztę instrukcji. Drugi fragment kodu z kolei charakteryzuje się bardziej logiczniejszą strukturą &#8211; gdyż wyraźnie widzimy co się stanie w przypadku spełnienia warunku jak i jego odrzucenia.</p>
<p>Przejdźmy zatem do testów. Przygotowałem na tą okazję dwie, identyczne pod względem działania, funkcje korzystające z dwóch w/w konstrukcji zapisu:</p>
<pre class="brush: php">function test_return($arg)
{
  if ($arg % 2 == 0)
  {
    return 0;
  }
  $arg = $arg*7+2;
  $a = $arg+3;
  $b = 1024;
  $arg = $a - $b*$arg;
  $arg =- 500;
  $arg *= 2;
  return $arg+256;
}</pre>
<p>&#8230;oraz:</p>
<pre class="brush: php">function test_else($arg)
{
  if ($arg % 2 == 0)
  {
    return 0;
  }
  else
  {
    $arg = $arg*7+2;
    $a = $arg+3;
    $b = 1024;
    $arg = $a - $b*$arg;
    $arg =- 500;
    $arg *= 2;
    return $arg+256;
  }
}</pre>
<p>Jak można zauważyć, funkcje te nie mają zbytniego sensu, nie mniej ich głównym celem jest odrzucanie liczb parzystych a przetwarzanie jedynie nieparzystych.</p>
<p>Procedura testowa polegała na wykonaniu jednego miliona iteracji każdej z funkcji, podając kolejne liczby całkowite jako argument poczynając od 0.</p>
<pre class="brush: php">for ($i = 0; $i &lt; 1000000; $i++)
{
  test_return($i);
}</pre>
<p>Wyniki jakie otrzymałem prezentują się następująco:</p>
<table>
<tbody>
<tr>
<th>Nazwa funkcji</th>
<th>Czas wykonania 1 000 000 iteracji</th>
</tr>
<tr>
<td>test_return()</td>
<td>~760ms</td>
</tr>
<tr>
<td>test_else()</td>
<td>~760ms</td>
</tr>
</tbody>
</table>
<p>Jak widać, wyniki są identyczne. W praktyce występowały pewne wahania w zależności od wywołania skryptu, nie mniej średnio, obie funkcje wykonują się w tym samym czasie. Nie ma więc znaczenia jakiego typu konstrukcji użyjemy &#8211; najlepiej tej która bardziej nam w danej chwili odpowiada.</p>
<p>Dlaczego tak się dzieje? Przyczyny braku różnicy w czasie wykonania można dopatrywać się tym, iż parser PHP bądź co bądź musi przeczytać całą zawartość skryptu przed jego kompilacją i uruchomieniem. Skompilowany kod jednej i drugiej funkcji nie różni się zatem niczym, co mogło by w istotny sposób wpłynąć na czas jego wykonania.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bbproject.net/2010/03/if-else-czy-return/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Co zrobić gdy reklama blokuje wyświetlanie strony?</title>
		<link>http://www.bbproject.net/2010/03/co-zrobic-gdy-reklama-blokuje-wyswietlanie-strony/</link>
		<comments>http://www.bbproject.net/2010/03/co-zrobic-gdy-reklama-blokuje-wyswietlanie-strony/#comments</comments>
		<pubDate>Tue, 09 Mar 2010 06:07:39 +0000</pubDate>
		<dc:creator>M@ster</dc:creator>
				<category><![CDATA[Webmastering]]></category>
		<category><![CDATA[absolute]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[optymalizacja]]></category>
		<category><![CDATA[position]]></category>
		<category><![CDATA[reklama]]></category>

		<guid isPermaLink="false">http://www.bbproject.net/?p=220</guid>
		<description><![CDATA[Otwieramy stronę internetową, widzimy nagłówek i czekamy&#8230; czekamy&#8230; po chwili pojawia się reklama a za nią interesująca nas treść. Brzmi znajomo? Zdecydowana większość systemów reklamowych opiera się na załączaniu zewnętrznego kodu JavaScript, który w przypadku wolnego serwera dostawcy reklam, może powodować niepotrzebne spowalnianie ładowania się naszej strony. O ile w sytuacji takich gigantów jak Google [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-thumbnail wp-image-224" title="Billboard" src="http://www.bbproject.net/wp-content/uploads/2010/02/billboard-160x122.jpg" alt="" width="160" height="122" />Otwieramy stronę internetową, widzimy nagłówek i czekamy&#8230; czekamy&#8230; po chwili pojawia się reklama a za nią interesująca nas treść. Brzmi znajomo?</p>
<p>Zdecydowana większość systemów reklamowych opiera się na załączaniu zewnętrznego kodu JavaScript, który w przypadku wolnego serwera dostawcy reklam, może powodować niepotrzebne spowalnianie ładowania się naszej strony. O ile w sytuacji takich gigantów jak <a href="https://www.google.com/adsense">Google AdSense</a> nie mamy się o co martwić, to przy korzystaniu z usług innych podmiotów czy też systemów pośredniczących (np.: <a href="http://www.openx.org">OpenX</a>), może warto zastanowić się jak pozbyć się tego problemu i nie opóźniać pokazania treści tylko przez reklamę. Zniecierpliwiony użytkownik naszej witryny może ją po prostu opuścić zanim zdąży cokolwiek zobaczyć.</p>
<p><span id="more-220"></span>Przedstawione rozwiązanie problemu jest stricte teoretyczne, gdyż docelowa implementacja zależy od konkretnego przypadku, a osoby które zajmują się tworzeniem stron internetowych na pewno będą wiedziały jak przenieść to na własny grunt.</p>
<p>Załóżmy hipotetyczną budowę naszej witryny w następującej postaci:</p>
<div style="margin: 10px auto; width: 300px;">
<div style="border: 2px solid #ff0000; padding: 10px; margin: 10px 0px; text-align: center;"><span style="color: #ff0000;">nagłówek</span></div>
<div style="border: 2px dotted #696969; padding: 10px; margin: 10px 0px; text-align: center;"><strong><span style="color: #696969;">reklama</span></strong></div>
<div style="border: 2px solid #1e90ff; padding: 10px; margin: 10px 0px; text-align: center;"><span style="color: #1e90ff;">treść</span></div>
</div>
<p>Przykładowy kod takiej witryny mógł by wyglądać w następujący sposób:</p>
<pre class="brush: xml">&lt;div id="header"&gt;&lt;/div&gt;
&lt;div id="advert"&gt;&lt;/div&gt;
&lt;div id="content"&gt;&lt;/div&gt;</pre>
<p>Jeśli nie chcemy aby warstwa reklamowa blokowała pojawienie się treści, wystarczy że przeniesiemy ją na sam koniec. Ktoś powie &#8211; ok, ale w tym wypadku reklama powędruje na dół strony. Musimy zatem zastosować pewną sztuczkę. Mianowicie, zwiększamy <strong>dolny margines</strong> warstwy nagłówka o wartość wysokości sekcji reklamowej, tak aby powstała pusta luka. Z kolei warstwę z reklamą, pozycjonujemy w sposób <strong>absolutny</strong> (<em>position: absolute;</em>) przy pomocy stylów, umieszczając ja w otrzymanej wnęcę.</p>
<pre class="brush: xml">&lt;div id="header" style="margin-bottom: 50px;"&gt;&lt;/div&gt;
&lt;div id="content"&gt;&lt;/div&gt;
&lt;div id="advert" style="position: absolute; top: 200px; height: 50px;"&gt;&lt;/div&gt;</pre>
<p>Tym sposobem, przeglądarka wyświetlając stronę, najpierw pokaże nagłówek, treść a dopiero na samym końcu reklamę &#8211; ale w odpowiednim miejscu. Jeśli ta z jakichś powodów nie będzie w stanie się wyświetlić (padnie serwer reklamy), to nie spowoduje to blokowania treści.</p>
<p>Oczywiście to co znajduje się pod reklamą, np.: stopka strony, nie pokaże się dopóki nie zostanie pobrana reklama, nie mniej, nie jest to tak istotny element w stosunku do treści po którą sięga odwiedzający witrynę.</p>
<p>Rozwiązania tego nie możemy zastosować w sytuacji w której odległość warstwy z reklamą jest zmienna w stosunku do początku strony, gdyż w tym momencie nie jesteśmy w stanie pozycjonować warstwy przy pomocy atrybutu <em>absolute</em>. Metodę tą stosuje z powodzeniem na dwóch swoich stronach i spisuje się znakomicie &#8211; <a href="http://www.cotozaplik.pl">cotozaplik.pl</a> oraz <a href="http://checksum.me">checksum.me</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bbproject.net/2010/03/co-zrobic-gdy-reklama-blokuje-wyswietlanie-strony/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Poprawa szybkości wczytywania grafik przy pomocy stylów</title>
		<link>http://www.bbproject.net/2009/12/poprawa-szybkosci-wczytywania-grafik-przy-pomocy-stylow/</link>
		<comments>http://www.bbproject.net/2009/12/poprawa-szybkosci-wczytywania-grafik-przy-pomocy-stylow/#comments</comments>
		<pubDate>Sun, 06 Dec 2009 09:16:27 +0000</pubDate>
		<dc:creator>M@ster</dc:creator>
				<category><![CDATA[Webmastering]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[html]]></category>
		<category><![CDATA[optymalizacja]]></category>

		<guid isPermaLink="false">http://www.bbproject.net/?p=9</guid>
		<description><![CDATA[Czy zdarza się Wam czy to projektując własną stronę czy też odwiedzając cudzą, mieć do czynienia z dużą ilością drobnych grafik (np.: ikon) które to kolejno wypełniają zawartość strony? Czy nie można przyspieszyć tego procesu skoro każdy z plików to z reguły nie więcej niż 1KB? Oczywiście można. Przyczyną tego stanu jest sposób w jaki [...]]]></description>
			<content:encoded><![CDATA[<p><img class="alignleft size-thumbnail wp-image-44" title="Wirtualna Polska - menu" src="http://www.bbproject.net/wp-content/uploads/2009/11/wp_menu-160x123.png" alt="Wirtualna Polska - menu" width="160" height="123" />Czy zdarza się Wam czy to projektując własną stronę czy też odwiedzając cudzą, mieć do czynienia z dużą ilością drobnych grafik (np.: ikon) które to kolejno wypełniają zawartość strony? Czy nie można przyspieszyć tego procesu skoro każdy z plików to z reguły nie więcej niż 1KB? Oczywiście można.</p>
<p>Przyczyną tego stanu jest sposób w jaki przeglądarka pobiera kolejne zasoby dołączone do odwiedzanej strony. Łącząc wszystkie drobne grafiki w jeden większy plik, a następnie przy pomocy stylów CSS wybierając interesującą nas część, możemy znacznie przyspieszyć ładowanie takiej strony.</p>
<p><span id="more-9"></span></p>
<h4>Jak działa przeglądarka?</h4>
<p>Otwierając dowolną stronę www, uzyskujemy od serwera treść dokumentu HTML, to czy jest on statyczny czy generowany dynamicznie (przez np.: php) nie ma w tej chwili znaczenia, która jest parsowana i wyświetlana przez przeglądarkę. Jeśli ta napotka na swej drodze zewnętrzne zasoby w postaci stylów CSS, skryptów JavaScript czy też grafikę rozpoczyna ich pobieranie.</p>
<h4>W czym tkwi problem?</h4>
<p>Na nieszczęście, z uwagi na fakt iż protokół HTTP jest protokołem bezstanowym, każde pobranie zasobu poprzedzone jest otwarciem gniazda TCP, nawiązaniem połączenia, pobraniem danych oraz zamknięciem połączenia. Stwarza to pewien narzut w postaci danych oraz czasu. Jeśli mamy do czynienia z dużymi plikami, przykładowo zdjęciami, nie jest to tak istotne. Z kolei jeśli naszą stronę ozdabiają różne drobne elementy graficzne, wtedy ów narzut nie tyle przekracza rozmiar zasobu co wprowadza niepotrzebne opóźnienia, gdyż samo nawiązanie sesji TCP trwa dłużej niż pobranie piku.</p>
<h4>Jak temu zaradzić?</h4>
<p>Dobrym rozwiązaniem jest scalenie wszystkich elementów graficznych w jeden plik, np.: w postaci kolumny obrazków. Ktoś może powiedzieć, jaki w tym zysk skoro i tak przeglądarka musi pobrać tą samą ilość danych? Zgadza się, jednakże zyskujemy mnóstwo czasu na narzucie związanym z tworzeniem połączenia i jego kończeniem dla każdego zasobu z osobna. Co to oznacza w praktyce? Znacznie szybsze ładowanie strony. Oczywiście opłacalność zabiegu w dużej mierze zależy od ilości grafiki klasyfikującej się do scalenia.</p>
<h4>A w praktyce?</h4>
<p>Przejdźmy zatem do części praktycznej. O ile samo scalenie obrazków nie powinno stwarzać problemów o tyle ich późniejsze wykorzystanie może rodzić pytania. Jak „wyciąć” grafikę na której nam zależy? Oczywiście stosując odpowiednią klasę stylów kaskadowych. Najprostszym sposobem jest używanie obrazków jako tło którym jest nasz zbiorczy plik graficzny, przesunięty o żądaną ilość pikseli.</p>
<p>Zastosujmy teraz zdobytą wiedzę do stworzenia menu strony składającego się z etykiet tekstowych oraz ikon. Potrzebny nam będzie zestaw stosownych obrazków oraz odpowiednie style zastosowane do menu. Zacznijmy jednak od napisania samego kodu HTML:</p>
<pre class="brush: xml">&lt;ul class="menu"&gt;
  &lt;li class="home"&gt;Strona główna&lt;/li&gt;
  &lt;li class="mail"&gt;Kontakt&lt;/li&gt;
  &lt;li class="download"&gt;Pobierz&lt;/li&gt;
  &lt;li class="tools"&gt;Narzędzia&lt;/li&gt;
&lt;/ul&gt;</pre>
<p>&#8230;kolejno arkusza stylów:</p>
<pre class="brush: css">.menu
{
  list-style: none;
  color: #404040;
  font: bold 16px Arial;
}
.menu li
{
  float: left;
  height: 24px;
  line-height: 24px;
  padding: 0px 30px;
}
.home     { background: url(icons.png) 0px   0px no-repeat; }
.mail     { background: url(icons.png) 0px -24px no-repeat; }
.download { background: url(icons.png) 0px -48px no-repeat; }
.tools    { background: url(icons.png) 0px -72px no-repeat; }</pre>
<p>&#8230;jeszcze dodajmy tylko użyty zestaw ikon:</p>
<p><img class="alignnone size-full wp-image-10" title="Zestaw ikon" src="http://www.bbproject.net/wp-content/uploads/2009/11/icons.png" alt="Zestaw ikon" /></p>
<p>&#8230;i cieszmy oko gotowym menu:</p>
<p><img class="size-full wp-image-11 aligncenter" title="Menu" src="http://www.bbproject.net/wp-content/uploads/2009/11/menu.png" alt="Menu" width="517" height="24" /></p>
<p>Jak widać, cała zabawa polega na odpowiednim przesunięciu tła tak aby trafić w interesujący nas punkt. Każda ikona ma rozmiar 24x24px, zatem musimy wymusić wysokość elementu menu właśnie na 24px, tak aby sąsiednie obrazki nie były widoczne.</p>
<p>Co zrobić w sytuacji w której mamy dużo rysunków o różnych rozmiarach? Można scalać je podobnie, jednakże lepszym wyjściem jest pogrupowanie identycznych pod względem rozmiaru w osobne pliki.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.bbproject.net/2009/12/poprawa-szybkosci-wczytywania-grafik-przy-pomocy-stylow/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

