SlideShare una empresa de Scribd logo
1 de 25
Descargar para leer sin conexión
Kompresja stron internetowych
Patryk Jar
Tech 3 Camp, 18 czerwca 2013 r.
O mnie
• Patryk Jar
• Webdeveloper
• Nor-sta (nor-sta.eu)
• yarpo.pl
2
3
Agenda
• Lepszy kod w przeglądarce
• Mniej żądań HTTP
• Mniej danych
• Narzędzia
• Ile możemy zyskać w praktyce?
• Podsumowanie
4
Lepszy kod CSS
• Unikaj @import, CSS expressions
• Szybsze selektory:
a#id → #id
body div → body > div
→ div
5Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
Lepszy kod HTML
• Przeskalowane grafiki
• Zwalczaj „divitis”
• Pliki wystarczy ładować raz
– Ile razy ładujesz jQuery?
• Unikaj błędów 404, 500 itp.
– Nie zostawiaj pustych <img src="" />
6Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
JS i CSS
<html>
<head>
<meta charset="utf-8" />
<title>Example.com</title>
<link rel="stylesheet" type="text/css" href="x.css"/>
<link rel="stylesheet" type="text/css" href="y.css"/>
</head>
<body>
<!-- tu cały kod HTML strony -->
<script src="a.js"></script>
<script src="b.js"></script>
</body>
</html>
7Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
Zamiast document.write
document.write('<script src="script.js"></sc'+'ript>');
function loadJS(fileUrl) {
var e = document.createElement("script");
e.async = true;
e.src = fileUrl;
document.body.appendChild(e);
}
8Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
Mniej żądań HTTP
• Content Delivery Network
– Google
– Microsoft
– Wiele, wiele innych
<script src="//ajax.googleapis.com/ajax/
libs/jquery/1.10.1/jquery.min.js"></script>
9Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
Scalanie plików CSS
+ + =
10Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
CSS Sprite
• Zamiast wielu osobnych plików (6 kB)
• Jeden (4kB)
img {
background: url(sprite.png);
width: 18px; height: 18px;
}
#myIcon { background-position: -40px 0; }
<img src="blank.png" id="myIcon" />
11Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
CSS Sprite - zysk
Pojedyncze grafiki CSS Sprite
Liczba żądań HTTP 11 2
Rozmiar danych 6kB 4kB
Czas ~500ms ~150ms
12Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
Grafika jako base64
<img src="blank.png" />
<img src="data:image/png;base64,
iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCA
YAAAAfFcSJAAAAC0lEQVQIW2P8DwQACgAD
/il4QJ8AAAAASUVORK5CYII=" />
13Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
Moduły JavaScript
• Moduły JS (np. AMD, CommonJS)
– Wielokrotnie wywoływany moduł = 1 żądanie
– Ładowanie większej liczby plików równolegle
– Scalenie do jednego pliku
14Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
Zapakuj lepiej dane
15Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
JavaScript przed kompresją
define("dijit/Toolbar", ["require", "dojo/_base/declare", "dojo/has", "dojo/keys",
"dojo/ready", "./_Widget", "./_KeyNavContainer", "./_TemplatedMixin"],
function(require, declare, has, keys, ready, _Widget, _KeyNavContainer, _TemplatedMixin){
return declare("dijit.Toolbar", [_Widget, _TemplatedMixin, _KeyNavContainer], {
/* tu jeszcze 10 linii kodu */
templateString: '<div class="dijit" role="toolbar" tabIndex="${tabIndex}" data-dojo-
attach-point="containerNode"></div>',
baseClass: "dijitToolbar",
postCreate: function() {
this.inherited(arguments);
this.connectKeyNavHandlers(
this.isLeftToRight() ? [keys.LEFT_ARROW] : [keys.RIGHT_ARROW],
this.isLeftToRight() ? [keys.RIGHT_ARROW] : [keys.LEFT_ARROW]
);
}
});
});
16Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
JavaScript po kompresji
define("dijit/Toolbar",["require","dojo/_base/declare","dojo/has","dojo/keys","dojo/ready","./_
Widget","./_KeyNavContainer","./_TemplatedMixin"],function(_1,_2,_3,_4,_5,_6,_7,_8){
if(_3("dijit-legacy-requires")){ _5(0,function(){ var _9=["dijit/ToolbarSeparator"];
_1(_9); }); }
return _2("dijit.Toolbar",[_6,_8,_7],{templateString:"<div class="dijit" role="toolbar"
tabIndex="${tabIndex}" data-dojo-attach-point="containerNode"></div>",
baseClass:"dijitToolbar",postCreate:function(){ this.inherited(arguments);
this.connectKeyNavHandlers(this.isLeftToRight()?[_4.LEFT_ARROW]:[_4.RIGHT_ARROW],this.isLef
tToRight()?[_4.RIGHT_ARROW]:[_4.LEFT_ARROW]); }}); });
17Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
Kompresja JavaScript
Moduł Bez kompresji Skompresowany Zysk
dojo/request/iframe 12kB 7kB 41%
dojo/selector/acme 49kB 13kB 73%
dojo/colors 7kB 5kB 29%
dojo/cookie 3kB 2kB 33%
dijit/MenuItem 7kB 3kB 57%
dijit/Dialog 22kB 9kB 60%
dijit/place 14kB 4kB 71%
tct/widgets/NodeBrowser 11kB 5kB 54%
18Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
GZIP
19Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
Ciasteczka
• Wysyłane w nagłówku żądania HTTP
• Inna domena na pliki statyczne
• HTML 5: sessionStorage, localStorage
20Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
Narzędzia
• Diagnoza
– YSlow
– Google PageSpeed Insights
• Kompresja JavaScript
– Shrinksafe
– JSmin
– Closure Compiler
• Kompresja CSS
– YUI Compressor
• CSS Sprite
– Dowolny edytor, wiele narzędzi online
21Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
Ile Nor-sta zyskała na kompresji?
22Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
Prototyp TCT 5.0 Oficjalne wydanie TCT 5.0
Liczba żądań HTTP 250 30
Rozmiar pobranych plików* ~1,2 MB ~300 kB
ready 90 sekund 7 sekund
* - dane przesłane po sieci, w oficjalnym wydaniu były poddane kompresji GZIP
23
Dziękuję za uwagę
• Jar.Patryk@gmail.com
• yarpo.pl
24Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
Pytania?
25Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie

Más contenido relacionado

Similar a Kompresja stron internetowych, Tech 3 Camp, Patryk yarpo Jar

Word up warszawa 2015
Word up warszawa 2015Word up warszawa 2015
Word up warszawa 2015Tomasz Dziuda
 
Jak Twoja strona moze wygenerować niespodziewane koszta? WordUp Kraków
Jak Twoja strona moze wygenerować niespodziewane koszta? WordUp KrakówJak Twoja strona moze wygenerować niespodziewane koszta? WordUp Kraków
Jak Twoja strona moze wygenerować niespodziewane koszta? WordUp KrakówTomasz Dziuda
 
Bezpieczenstwo Portali Spolecznosciowych W Ujeciu Robakow Web 20 Pingwinaria2009
Bezpieczenstwo Portali Spolecznosciowych W Ujeciu Robakow Web 20 Pingwinaria2009Bezpieczenstwo Portali Spolecznosciowych W Ujeciu Robakow Web 20 Pingwinaria2009
Bezpieczenstwo Portali Spolecznosciowych W Ujeciu Robakow Web 20 Pingwinaria2009Logicaltrust pl
 
The story of GOG.com Cache - PHPers 2014 ( PL )
 The story of GOG.com Cache - PHPers 2014 ( PL ) The story of GOG.com Cache - PHPers 2014 ( PL )
The story of GOG.com Cache - PHPers 2014 ( PL )GOG.com dev team
 
Drobne błędy w portalach WWW -- prawdziwe studium przypadku
Drobne błędy w portalach WWW -- prawdziwe studium przypadkuDrobne błędy w portalach WWW -- prawdziwe studium przypadku
Drobne błędy w portalach WWW -- prawdziwe studium przypadkumsobiegraj
 
Dive into HTML5 - Marcin Zajkowski @ SNT, Microsoft
Dive into HTML5 - Marcin Zajkowski @ SNT, MicrosoftDive into HTML5 - Marcin Zajkowski @ SNT, Microsoft
Dive into HTML5 - Marcin Zajkowski @ SNT, MicrosoftMarcin Zajkowski
 
Za darmo nie umarło - WordCamp Wrocław
Za darmo nie umarło - WordCamp WrocławZa darmo nie umarło - WordCamp Wrocław
Za darmo nie umarło - WordCamp WrocławTomasz Dziuda
 
Responsive Web Design - kto mało pyta, nie błądzi
Responsive Web Design - kto mało pyta, nie błądziResponsive Web Design - kto mało pyta, nie błądzi
Responsive Web Design - kto mało pyta, nie błądziJakub Wiśniewski
 
4Developers 2015: Frameworki jee vs cross-site scripting (xss) - Piotr Bucki
4Developers 2015: Frameworki jee vs cross-site scripting (xss) - Piotr Bucki4Developers 2015: Frameworki jee vs cross-site scripting (xss) - Piotr Bucki
4Developers 2015: Frameworki jee vs cross-site scripting (xss) - Piotr BuckiPROIDEA
 
Zabezpiecz swoją stronę w Joomla!
Zabezpiecz swoją stronę w Joomla!Zabezpiecz swoją stronę w Joomla!
Zabezpiecz swoją stronę w Joomla!Wojciech Klocek
 
Gaca-Tworek Barbara: JavaScript SEO w praktyce: Webinar Senuto
Gaca-Tworek Barbara: JavaScript SEO w praktyce: Webinar SenutoGaca-Tworek Barbara: JavaScript SEO w praktyce: Webinar Senuto
Gaca-Tworek Barbara: JavaScript SEO w praktyce: Webinar SenutoBarbaraGacaTworek
 
W3 Total Cache - skuteczne przyśpieszanie WordPressa
W3 Total Cache - skuteczne przyśpieszanie WordPressaW3 Total Cache - skuteczne przyśpieszanie WordPressa
W3 Total Cache - skuteczne przyśpieszanie WordPressaBartosz Romanowski
 
The story of GOG.com Cache - 4developers 2014 ( PL )
The story of GOG.com Cache - 4developers 2014 ( PL )The story of GOG.com Cache - 4developers 2014 ( PL )
The story of GOG.com Cache - 4developers 2014 ( PL )GOG.com dev team
 
Jak ładujemy skrypty JS i jakie ma to znaczenie?
Jak ładujemy skrypty JS i jakie ma to znaczenie?Jak ładujemy skrypty JS i jakie ma to znaczenie?
Jak ładujemy skrypty JS i jakie ma to znaczenie?BarbaraGacaTworek
 
Optymalizacja Serwisów WWW
Optymalizacja Serwisów WWWOptymalizacja Serwisów WWW
Optymalizacja Serwisów WWWPaweł Harajda
 

Similar a Kompresja stron internetowych, Tech 3 Camp, Patryk yarpo Jar (20)

Word up warszawa 2015
Word up warszawa 2015Word up warszawa 2015
Word up warszawa 2015
 
Jak Twoja strona moze wygenerować niespodziewane koszta? WordUp Kraków
Jak Twoja strona moze wygenerować niespodziewane koszta? WordUp KrakówJak Twoja strona moze wygenerować niespodziewane koszta? WordUp Kraków
Jak Twoja strona moze wygenerować niespodziewane koszta? WordUp Kraków
 
Anatomy of RTB auction
Anatomy of RTB auctionAnatomy of RTB auction
Anatomy of RTB auction
 
Iron Python I Dlr
Iron Python I DlrIron Python I Dlr
Iron Python I Dlr
 
Bezpieczenstwo Portali Spolecznosciowych W Ujeciu Robakow Web 20 Pingwinaria2009
Bezpieczenstwo Portali Spolecznosciowych W Ujeciu Robakow Web 20 Pingwinaria2009Bezpieczenstwo Portali Spolecznosciowych W Ujeciu Robakow Web 20 Pingwinaria2009
Bezpieczenstwo Portali Spolecznosciowych W Ujeciu Robakow Web 20 Pingwinaria2009
 
The story of GOG.com Cache - PHPers 2014 ( PL )
 The story of GOG.com Cache - PHPers 2014 ( PL ) The story of GOG.com Cache - PHPers 2014 ( PL )
The story of GOG.com Cache - PHPers 2014 ( PL )
 
Drobne błędy w portalach WWW -- prawdziwe studium przypadku
Drobne błędy w portalach WWW -- prawdziwe studium przypadkuDrobne błędy w portalach WWW -- prawdziwe studium przypadku
Drobne błędy w portalach WWW -- prawdziwe studium przypadku
 
Dive into HTML5 - Marcin Zajkowski @ SNT, Microsoft
Dive into HTML5 - Marcin Zajkowski @ SNT, MicrosoftDive into HTML5 - Marcin Zajkowski @ SNT, Microsoft
Dive into HTML5 - Marcin Zajkowski @ SNT, Microsoft
 
Za darmo nie umarło - WordCamp Wrocław
Za darmo nie umarło - WordCamp WrocławZa darmo nie umarło - WordCamp Wrocław
Za darmo nie umarło - WordCamp Wrocław
 
Responsive Web Design - kto mało pyta, nie błądzi
Responsive Web Design - kto mało pyta, nie błądziResponsive Web Design - kto mało pyta, nie błądzi
Responsive Web Design - kto mało pyta, nie błądzi
 
Jaki hosting pod wordpressa
Jaki hosting pod wordpressaJaki hosting pod wordpressa
Jaki hosting pod wordpressa
 
4Developers 2015: Frameworki jee vs cross-site scripting (xss) - Piotr Bucki
4Developers 2015: Frameworki jee vs cross-site scripting (xss) - Piotr Bucki4Developers 2015: Frameworki jee vs cross-site scripting (xss) - Piotr Bucki
4Developers 2015: Frameworki jee vs cross-site scripting (xss) - Piotr Bucki
 
Zabezpiecz swoją stronę w Joomla!
Zabezpiecz swoją stronę w Joomla!Zabezpiecz swoją stronę w Joomla!
Zabezpiecz swoją stronę w Joomla!
 
Gaca-Tworek Barbara: JavaScript SEO w praktyce: Webinar Senuto
Gaca-Tworek Barbara: JavaScript SEO w praktyce: Webinar SenutoGaca-Tworek Barbara: JavaScript SEO w praktyce: Webinar Senuto
Gaca-Tworek Barbara: JavaScript SEO w praktyce: Webinar Senuto
 
W3 Total Cache - skuteczne przyśpieszanie WordPressa
W3 Total Cache - skuteczne przyśpieszanie WordPressaW3 Total Cache - skuteczne przyśpieszanie WordPressa
W3 Total Cache - skuteczne przyśpieszanie WordPressa
 
The story of GOG.com Cache - 4developers 2014 ( PL )
The story of GOG.com Cache - 4developers 2014 ( PL )The story of GOG.com Cache - 4developers 2014 ( PL )
The story of GOG.com Cache - 4developers 2014 ( PL )
 
Jak ładujemy skrypty JS i jakie ma to znaczenie?
Jak ładujemy skrypty JS i jakie ma to znaczenie?Jak ładujemy skrypty JS i jakie ma to znaczenie?
Jak ładujemy skrypty JS i jakie ma to znaczenie?
 
W 3 sekundy do setki
W 3 sekundy do setkiW 3 sekundy do setki
W 3 sekundy do setki
 
Wydajny frontend 2023
Wydajny frontend 2023Wydajny frontend 2023
Wydajny frontend 2023
 
Optymalizacja Serwisów WWW
Optymalizacja Serwisów WWWOptymalizacja Serwisów WWW
Optymalizacja Serwisów WWW
 

Kompresja stron internetowych, Tech 3 Camp, Patryk yarpo Jar

  • 1. Kompresja stron internetowych Patryk Jar Tech 3 Camp, 18 czerwca 2013 r.
  • 2. O mnie • Patryk Jar • Webdeveloper • Nor-sta (nor-sta.eu) • yarpo.pl 2
  • 3. 3
  • 4. Agenda • Lepszy kod w przeglądarce • Mniej żądań HTTP • Mniej danych • Narzędzia • Ile możemy zyskać w praktyce? • Podsumowanie 4
  • 5. Lepszy kod CSS • Unikaj @import, CSS expressions • Szybsze selektory: a#id → #id body div → body > div → div 5Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
  • 6. Lepszy kod HTML • Przeskalowane grafiki • Zwalczaj „divitis” • Pliki wystarczy ładować raz – Ile razy ładujesz jQuery? • Unikaj błędów 404, 500 itp. – Nie zostawiaj pustych <img src="" /> 6Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
  • 7. JS i CSS <html> <head> <meta charset="utf-8" /> <title>Example.com</title> <link rel="stylesheet" type="text/css" href="x.css"/> <link rel="stylesheet" type="text/css" href="y.css"/> </head> <body> <!-- tu cały kod HTML strony --> <script src="a.js"></script> <script src="b.js"></script> </body> </html> 7Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
  • 8. Zamiast document.write document.write('<script src="script.js"></sc'+'ript>'); function loadJS(fileUrl) { var e = document.createElement("script"); e.async = true; e.src = fileUrl; document.body.appendChild(e); } 8Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
  • 9. Mniej żądań HTTP • Content Delivery Network – Google – Microsoft – Wiele, wiele innych <script src="//ajax.googleapis.com/ajax/ libs/jquery/1.10.1/jquery.min.js"></script> 9Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
  • 10. Scalanie plików CSS + + = 10Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
  • 11. CSS Sprite • Zamiast wielu osobnych plików (6 kB) • Jeden (4kB) img { background: url(sprite.png); width: 18px; height: 18px; } #myIcon { background-position: -40px 0; } <img src="blank.png" id="myIcon" /> 11Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
  • 12. CSS Sprite - zysk Pojedyncze grafiki CSS Sprite Liczba żądań HTTP 11 2 Rozmiar danych 6kB 4kB Czas ~500ms ~150ms 12Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
  • 13. Grafika jako base64 <img src="blank.png" /> <img src="data:image/png;base64, iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCA YAAAAfFcSJAAAAC0lEQVQIW2P8DwQACgAD /il4QJ8AAAAASUVORK5CYII=" /> 13Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
  • 14. Moduły JavaScript • Moduły JS (np. AMD, CommonJS) – Wielokrotnie wywoływany moduł = 1 żądanie – Ładowanie większej liczby plików równolegle – Scalenie do jednego pliku 14Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
  • 15. Zapakuj lepiej dane 15Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
  • 16. JavaScript przed kompresją define("dijit/Toolbar", ["require", "dojo/_base/declare", "dojo/has", "dojo/keys", "dojo/ready", "./_Widget", "./_KeyNavContainer", "./_TemplatedMixin"], function(require, declare, has, keys, ready, _Widget, _KeyNavContainer, _TemplatedMixin){ return declare("dijit.Toolbar", [_Widget, _TemplatedMixin, _KeyNavContainer], { /* tu jeszcze 10 linii kodu */ templateString: '<div class="dijit" role="toolbar" tabIndex="${tabIndex}" data-dojo- attach-point="containerNode"></div>', baseClass: "dijitToolbar", postCreate: function() { this.inherited(arguments); this.connectKeyNavHandlers( this.isLeftToRight() ? [keys.LEFT_ARROW] : [keys.RIGHT_ARROW], this.isLeftToRight() ? [keys.RIGHT_ARROW] : [keys.LEFT_ARROW] ); } }); }); 16Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
  • 17. JavaScript po kompresji define("dijit/Toolbar",["require","dojo/_base/declare","dojo/has","dojo/keys","dojo/ready","./_ Widget","./_KeyNavContainer","./_TemplatedMixin"],function(_1,_2,_3,_4,_5,_6,_7,_8){ if(_3("dijit-legacy-requires")){ _5(0,function(){ var _9=["dijit/ToolbarSeparator"]; _1(_9); }); } return _2("dijit.Toolbar",[_6,_8,_7],{templateString:"<div class="dijit" role="toolbar" tabIndex="${tabIndex}" data-dojo-attach-point="containerNode"></div>", baseClass:"dijitToolbar",postCreate:function(){ this.inherited(arguments); this.connectKeyNavHandlers(this.isLeftToRight()?[_4.LEFT_ARROW]:[_4.RIGHT_ARROW],this.isLef tToRight()?[_4.RIGHT_ARROW]:[_4.LEFT_ARROW]); }}); }); 17Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
  • 18. Kompresja JavaScript Moduł Bez kompresji Skompresowany Zysk dojo/request/iframe 12kB 7kB 41% dojo/selector/acme 49kB 13kB 73% dojo/colors 7kB 5kB 29% dojo/cookie 3kB 2kB 33% dijit/MenuItem 7kB 3kB 57% dijit/Dialog 22kB 9kB 60% dijit/place 14kB 4kB 71% tct/widgets/NodeBrowser 11kB 5kB 54% 18Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
  • 19. GZIP 19Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
  • 20. Ciasteczka • Wysyłane w nagłówku żądania HTTP • Inna domena na pliki statyczne • HTML 5: sessionStorage, localStorage 20Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
  • 21. Narzędzia • Diagnoza – YSlow – Google PageSpeed Insights • Kompresja JavaScript – Shrinksafe – JSmin – Closure Compiler • Kompresja CSS – YUI Compressor • CSS Sprite – Dowolny edytor, wiele narzędzi online 21Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
  • 22. Ile Nor-sta zyskała na kompresji? 22Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie Prototyp TCT 5.0 Oficjalne wydanie TCT 5.0 Liczba żądań HTTP 250 30 Rozmiar pobranych plików* ~1,2 MB ~300 kB ready 90 sekund 7 sekund * - dane przesłane po sieci, w oficjalnym wydaniu były poddane kompresji GZIP
  • 23. 23
  • 24. Dziękuję za uwagę • Jar.Patryk@gmail.com • yarpo.pl 24Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie
  • 25. Pytania? 25Lepszy kod / Mniej żądań / Mniej danych / Zysk / Podsumowanie