Kom ihåg när vi var tvungna att spendera mycket tid på att optimera projektets tillgångar (bilder, CSS, etc ...)? Tja idag har användarna en mycket snabbare internetuppkoppling och det verkar som om vi har råd att använda större bilder eller större flashfiler med mycket video och bilder inuti. Men med utvecklingen av mobilutveckling återkommer vi igen i samma situation. Det är oerhört viktigt att skapa väl optimerade webbplatser, så att vi har snabbare applikationer, som hämtar mindre innehåll och svarar omedelbart.
Ofta använder vi samma bilder för olika delar av våra webbplatser. Till exempel, i en webbutik, har alla produkter en översiktsbild. Låt oss säga att vi har tre sidor där vi måste visa bilderna - en sida för att lista produkterna, en annan sida för produktens detaljer och en tredje sida som bara visar bilden i sin ursprungliga storlek.
Så vi behöver tre olika bildstorlekar och om vi använder samma fil för alla tre olika ställen, kommer webbläsaren ladda ner fullstorleksbilden även för listningssidan, där vi faktiskt bara behöver en 200x200 bild. Om den ursprungliga filen är cirka 1 MB och vi har tio produkter per sida, så skulle användaren ladda ner 10 MB. Det är inte en mycket bra idé. Om du kan, försök generera olika bilder för de olika delarna av din webbplats, så sparar du många KB-filer för dina användare. Det är en bra idé att tänka på den aktuella skärmupplösningen. Om någon till exempel öppnar din webbplats på sin iPhone, behöver du inte tjäna den gigantiska header-bilden, som du brukar använda. Genom att använda CSS-mediafrågor kan du skicka en bild med en mindre storlek:
@media bara skärm och (min enhet bredd: 320px) och (max enhet bredd: 480px) .header background-image: url (... /images/background_400x200.jpg);
Att skicka en bild med bara rätt mått är inte alltid tillräckligt. Vissa filformat kan komprimeras mycket utan att förlora sin kvalitet. Det finns många program som kan hjälpa dig. Till exempel, Photoshop ger en fin funktion som heter Spara för webb och enheter
:
Det finns många alternativ i den här dialogrutan, men en av de viktigaste är Kvalitet
. Om du ställer in det på ungefär 80% kan du minska filstorleken avsevärt.
Självklart kan du använda kod för att komprimera filerna, men jag föredrar personligen Photoshop och jag använder det när det är möjligt. Här är ett enkelt exempel skrivet i PHP:
funktion compressImage ($ source, $ destination, $ quality) $ info = getimagesize ($ source); switch ($ info ['mime']) fall "image / jpeg": $ image = imagecreatefromjpeg ($ source); imagejpeg ($ image, $ destination, $ quality); ha sönder; fall "image / gif": $ image = imagecreatefromgif ($ source); imagegif ($ bild, $ destination, $ kvalitet); ha sönder; fall "image / png": $ image = imagecreatefrompng ($ source); imagepng ($ image, $ destination, $ quality); ha sönder; compressImage ('source.png', 'destination.png', 85);
En av de saker du kan göra för att öka prestanda för din ansökan är att minska antalet förfrågningar till servern. Så innebär varje ny bild en ny förfrågan. Det är en bra idé att kombinera dina bilder till en. Den resulterande bilden heter a sprite
och med att ändra bakgrund-positionen
CSS-stil kan du bara visa den del av bilden du behöver. Twitter Bootstrap använder till exempel sprites för sina interna ikoner:
Därefter kan du i CSS göra något så här för att visa vilken del av sprite du vill ha:
.icon-edit background-image: url ("... /img/glyphicons-halfl-white.png"); Bakgrundsposition: -96px -72px;
Webbläsarens cachemekanism är din vän. Ja, ibland under utveckling kan det leda till några mycket rolig
situationer, men det hjälper verkligen att förbättra webbplatsens prestanda. Varje webbläsare cachar innehåll som bilder, JavaScript eller CSS. Det finns flera sätt att styra cachen och jag föreslår att du kolla in den här stora artikeln för en detaljerad granskning. I allmänhet kan du styra processen genom att ställa in rubriker, som så:
$ expire = 60 * 60 * 24 * 1; // sekunder, minuter, timmar, dagar header ("Cache-Control: maxage =". $ expire); header ("Expires:" .gmdate ('D, d MYH: I: s ', tid () + $ utgår).' GMT '); rubrik ('Senast ändrad:' .gmdate ('D, d M Y H: i: s'). 'GMT');
HTML5 går framåt varje dag. Det finns en trevlig funktion som heter förhämtning
vilket berättar för webbläsaren att du behöver lite resurs inom den närmaste framtiden och det bör laddas ned nu, i förväg. Till exempel:
För några år sedan var jag tvungen att utveckla en enkel webbsida, som var bara en HTML-fil. Självklart var det flera bilder, som jag var tvungen att inkludera. Data URI-system hjälpte mig att lösa problemet. Tanken är att konvertera dina bilder till en base64 kodad sträng och placera den i src
attribut av img
märka. Till exempel:
Genom att använda detta tillvägagångssätt är din bild faktiskt i HTML och du sparar en HTTP-begäran. Självklart, om du har en stor bild kommer strängen att vara riktigt lång. Här är ett enkelt PHP-skript som konverterar bilder till base64-strängar:
$ picture = fread ($ fp, file size ($ file)); fclose ($ fp); // base64 kodar binär data, bryt den sedan // i bitar enligt RFC 2045 semantik $ base64 = base64_encode ($ bild); $ tag = ''; $ css = 'url (data: image / jpg; base64,' .str_replace ("\ n", "", $ base64). '); ';
Du kan finna det här användbart i vissa fall, men kom ihåg att det inte fungerar bra i IE.
Jag tycker om att skriva CSS är som att skriva kod. Du måste fortfarande organisera dina stilar, för att definiera olika block och förhållandet mellan dem. Det är därför jag tycker att CSS-hanteringen är väldigt viktig. Varje del av ansökan ska ha sina egna stilar och de ska vara snygga separerade. Att hålla allt i olika filer ger en bra organisation, men också med sina egna problem.
Vi vet alla att användningen av @importera
uttalande är inte en mycket bra idé. Det beror på att alla nya @importera
innebär en ny begäran till servern. Och om du till exempel har 20 olika .css
filer betyder det att webbläsaren kommer att göra 20 förfrågningar. Och webbläsaren gör inte / visar sidan innan du laddar ned alla stilar. Om några av dina .css
filer saknas eller är mycket stora, får du en stor fördröjning innan du ser något på skärmen.
CSS preprocessorer löser alla problem ovan. Du delar fortfarande dina stilar i olika filer, men i slutet sammanställer förprocessorn allt till en enda .css
fil. De erbjuder faktiskt ett gäng coola funktioner som variabler, kapslade block, mixins och arv. Koden ser fortfarande ut som CSS, men den är välformaterad / strukturerad. Det finns få populära förprocessorer som är värda att kontrollera - Sass, LESS, och Stylus. Här är ett enkelt exempel skrivet i MINDER:
.position (@top: 0, @left: 0) position: absolute; topp: @top; vänster: @left; text-align: left; typsnittstorlek: 24px; .header .position (20px, 30px); .tips .position (10px, -20px); .logo .position (10px, 20px);
kommer att producera
.header position: absolute; topp: 20px; vänster: 30px; text-align: left; typsnittstorlek: 24px; .header.tips position: absolute; topp: 10px; vänster: -20px; text-align: left; typsnittstorlek: 24px; .header .logo position: absolute; topp: 10px; vänster: 20px; text-align: left; typsnittstorlek: 24px;
Eller, till exempel om du har styling för en knapp och vill producera precis samma knapp men med en annan färg för texten, kan du göra det här:
.knapp border: solid 1px # 000; vaddering: 10px; bakgrund: # 9f0; färg: # 0029FF; .aktiv knapp . knapp (); färg: #FFF;
Normalt tänker de flesta utvecklare inte på effektiv CSS. Effektiviteten hos CSS återspeglar sidans rendering och om dina stilar är ineffektiva kommer din ansökan att göras långsamt av webbläsare. Ett intressant faktum är att webbläsare analyserar CSS-selektorerna från höger till vänster. Vilket innebär att följande kod:
kropp ul li a färg: # F000; text-dekoration: ingen;
... är inte effektivt alls. Det beror på att motorn kommer att få alla taggar och kommer att behöva utvärdera var och en av moderelementen för att slutligen samla den nödvändiga stilen. Du bör också veta att i effektivitetssyfte är selektorerna sorterade i följande ordning: ID, klass, tag och universal. Det betyder att ett element med en
id
set kommer att bli gjorda snabbare än ett element med bara en taggväljare. Det är naturligtvis ingen mening att lägga till ids på alla element i DOM-trädet, men du bör definitivt kolla din kod och förbättra den där det är möjligt. Om du till exempel har något liknande här:
ul #navigation li background: # ff0232;
Du borde ta bort ul
del, för att du bara har en #navigering
element på sidan. Eller i följande väljare:
body .content p font-size: 20px;
Det är uppenbart att .innehåll
elementet är ett barn av kropp
märka. Alla element är faktiskt barn av detta element.
Här är två användbara länkar om det här ämnet: developers.google.com och css-tricks.com
Som vi nämnde ovan är det bra att ha så liten kod som möjligt, eftersom webbläsaren inte gör sidan innan du laddar ner CSS. Här är några tips för att minska filstorleken.
Kombinera liknande stilar:
.rubrik font-size: 24px; .content font-size: 24px;
... omvandlas till:
.header, .content font-size: 24px;
Använd shorthands. Istället för:
.rubrik bakgrundsfärg: # 999999; bakgrundsbild: url (... /images/header.jpg); Bakgrundsställning: Överst till höger;
Skriv det på det här sättet:
.rubrik bakgrund: # 999 url (... /images/header.jpg) till höger;
Minifiera din CSS-kod. Du kan göra detta genom att använda ett verktyg som i allmänhet tar bort alla mellanslag och nya rader. Till exempel CSSOptimiser eller Minifycss. Det är vanligt att använda sådana instrument på serverns sida, dvs något som skrivs på baksidans språk. Normalt minskar dessa komponenter din kod och tjänar den till användaren.
MärkaDet är bra att inkludera din .css
filer i huvud
taggen, så kommer webbläsaren att ladda ner den först.
Samma som med din CSS - det är bra att minska antalet begäranden som ska skickas till servern. I de flesta fall upphör inte laddningen av JavaScript-filerna att återge sidan, men det kommer att göra vissa delar av sidan icke-funktionell.
Det finns en massa bibliotek som gör JavaScript-minifiering. Det är något som kommer att minska filens storlek, men tänk på att i en utvecklingsmiljö är det bra att hålla koden ren. De flesta av dessa verktyg ändrar namnet på dina variabler och omvandlar allt till en ensträngsträng, vilket gör debuggingprocessen nästan omöjlig.
JavaScript har inte en mekanism för hantering av moduler. Så, alla dessa saker är uppfunna för att lösa detta problem. De tillhandahåller ett API som du kan använda för att definiera och använda moduler. Till exempel, här är ett exempel taget från http://requirejs.org/:
Mitt provprojekt Mitt provprojekt
Insidan av main.js
, du kan använda fordra()
att ladda alla andra skript du behöver:
kräva (["hjälpar / util"], funktion (util) // Den här funktionen heter när scripts / hjälper / util.js laddas. // Om använd.js-samtal definierar (), blir den här funktionen inte avbruten tills // utils beroenden har laddats, och utilitetsargumentet håller // modulvärdet för "hjälpar / util".);
Om vi pratar om kodorganisation kan vi inte hoppa över delen om namnområden. Nativt finns det ingen sådan funktion i JavaScript, men du kan fortfarande uppnå samma sak med en liten kod. Om du till exempel vill bygga din egen MVC-ram har du förmodligen följande klasser:
var modell = funktion () ...; var view = funktion () ...; var controller = funktion () ...;
Om du lämnar saker som de är i ovanstående kod, blir de offentliga och det finns en större chans att skapa konflikter med andra bibliotek i ditt projekt. Så att gruppera dem i ett oberoende objekt (namespace) gör ramverket skyddad:
var MyAwesomeFramework = modell: funktion () ..., visa: funktion () ..., controller: funktion () ...
Det är inte nödvändigt att återuppfinna hjulet. JavasScript blev väldigt populär och det finns många bra metoder där ute. Designmönster är återanvändbara lösningar för vanliga problem i programmeringen. Efter några av dem hjälper du dig att bygga en bra applikation. Men om jag försöker täcka dem alla här, skulle jag behöva skriva en bok, så här är bara några av dem:
Använd det här mönstret för att skapa en förekomst av en viss objekttyp. Här är ett exempel:
var Klass = funktion (param1, param2) this.var1 = param1; this.var2 = param2; Class.prototype = metod: funktion () alert (this.var1 + "/" + this.var2); ;
Eller så kan du prova det här:
funktionsklass (param1, param2) this.var1 = param1; this.var2 = param2; this.method = function () alert (param1 + "/" + param2); ; ; var instance = ny klass ("värde1", "värde2");
Modulmönstret ger oss möjligheten att skapa privata och offentliga metoder. Till exempel, i koden nedan, variabeln _index
och metoden privateMethod
är privata. ökning
och getIndex
är offentliga.
var-modul = (funktion () var _index = 0; var privatMethod = funktion () return _index * 10; returnera inkrement: funktion () _index + = 1;, getIndex: funktion () return _index; ;) ();
Varhelst du ser prenumeration eller försändelse av händelser kommer du troligtvis att se det här mönstret. Det finns observatörer som är intresserade av något som är relaterat till ett visst objekt. När åtgärden inträffar meddelar objektet observatörerna. Exemplet nedan visar hur vi kan lägga till en observatör på användare
objekt:
var Users = list: [], lyssnare: , lägg till: funktion (namn) this.list.push (namn: namn); this.dispatch ( "user-added"); , på: funktion (händelsenamn, lyssnare) if (! this.listeners [eventName]) this.listeners [eventName] = []; this.listeners [eventname] .push (lyssnare); , avsändning: funktion (händelsenamn) om (this.listeners [eventName]) for (var i = 0; iFunktionskedjemönster
Detta mönster är ett bra sätt att organisera det offentliga gränssnittet för din modul. Det sparar tid och förbättrar läsbarheten:
var User = profil: , namn: funktion (värde) this.profile.name = value; returnera detta; , jobb: funktion (värde) this.profile.job = value; returnera detta; , getProfile: function () returnera this.profile; ; var profil = Användarnamn ("Krasimir Tsonev"). jobb ("webbutvecklare"). getProfile (); console.log (profil);Jag rekommenderar starkt att du kolla denna bok av Addy Osmani. Det är en av de bästa resurserna som du kan hitta om designmönster i JavaScript.
Tillgångar-Pack
Nu när vi närmar oss slutet av den här artikeln vill jag dela några tankar om CSS och JavaScript-kodhantering på servern. Det är en mycket vanlig teknik för att lägga till sammanslagning, minifiering och sammanställning i programmets logik. Ofta finns det någon form av cachemekanism, men alla saker händer under körtiden. Så du har förmodligen en kodlogik som hanterar begäran om
.js
eller.css
filer och serverar rätt innehåll. Bakom denna process är sammanställningen, minifiering eller vad du än använder för att förpacka dina tillgångar.I mina senaste projekt använde jag ett verktyg som heter
tillgångar-pack
. Det är verkligen användbart och jag kommer att förklara i detalj vad exakt det gör, men den mer intressanta delen är hur jag använde den. Detta bibliotek är endast avsett att användas i utvecklingsläge, det är inte något som stannar i din kodbas och det är inte något som du ska installera på din produktionsserver.Tanken är att endast använda förpackaren när du arbetar på tillgångarna (CSS, JS). Den tittar faktiskt på ändringar i specifika kataloger och sammanställer / förpackar koden i en enda fil. Genom att använda detta tillvägagångssätt behöver du inte tänka på minifiering eller sammanställning. Allt du behöver göra är att skicka den sammanställda statiska filen till användaren. Detta ökar prestandan i din ansökan, eftersom den bara tjänar statiska filer och gör det självklart enklare. Du behöver inte ställa in något på din server eller genomföra onödig logik.
Så här kan du installera och använda
tillgångar-pack
.Installation
Det här verktyget är en Nodejs-modul, så du borde ha Node redan installerad. Om du inte gör det, gå till nodejs.org/download och ta tag i paketet för ditt operativsystem. Efter det:
npm installera -g assetspackAnvändande
Modulen arbetar med JSON-konfiguration. När den används via kommandoraden bör du placera dina inställningar i en
.json
fil.Via kommandoraden
Skapa en
assets.json
fil och kör följande kommando i samma katalog:assetspackOm din konfigurationsfil använder ett annat namn eller finns i en annan katalog, använd:
assetspack --config [sökväg till json fil]I kod
var AssetsPack = kräver ("assetspack"); var config = [typ: "css", titta på: ["css / src"], output: "test / packed / styles.css", minifiera: true, exclude: ["custom.css"]]; var pack = nytt AssetsPack (config, function () console.log ("AssetsPack ser");); pack.onPack (funktion () console.log ("AssetsPack gjorde jobbet"););Konfiguration
Konfigurationen ska vara en giltig JSON-fil / -objekt. Det är bara en rad objekt:
[(asset object), (asset object), (asset object), ...]Asset Object
Den grundläggande strukturen för tillgångsobjektet är som så:
typ: (filtyp / sträng, kan vara css, js eller mindre till exempel), titta på: (katalog eller kataloger för att titta på / sträng eller array av strängar /), pack: (katalog eller kataloger för packning / sträng eller array av strängar /.), utgång: (sökväg till utgångsfil / sträng /), minifiera: / boolean /, utesluta: (rad filnamn)De
packa
egendom är inte obligatorisk. Om du saknar det, är dess värde lika medKolla på
.minify
som standard är false.Här är några exempel:
Packning CSS
typ: "css", titta på: ["test / data / css", "test / data / css2"], pack: ["test / data / css", "test / data / css2"], utgång: test / packed / styles.css ", avgränsa: true, exclude: [" header.css "]Förpackning av JavaScript
typ: "js", titta på: "test / data / js", pack: ["test / data / js"], output: "test / packed / scripts.js", minifiera: true, exclude: .js "]Förpackning
.mindre
filerFörpackningen av
.mindre
filer är lite annorlunda. Depacka
egendom är obligatoriskt och det är i grunden din ingångspunkt. Du borde importera alla andra.mindre
filer där. Deutesluta
egendom är inte tillgänglig här.typ: "mindre", titta på: ["test / data / mindre"], pack: "test / data / mindre / index.less", utgång: "test / packed / styles-less.css"Om du hittar några problem, kolla
tester / förpackning-less.spec.js
av förvaret i GitHub.Packar andra filformat
tillgångar-pack
fungerar med alla filformat. Till exempel kan vi kombinera HTML-mallar i en enda fil genom att göra något så här:typ: "html", titta på: ["test / data / tpl"], output: "test / packed / template.html", utesluter: ["admin.html"]Den enda sak som du borde veta här är att det inte finns någon minifiering.
Slutsats
Som främsta webbutvecklare borde vi försöka leverera bästa möjliga prestanda för våra användare. Tipsen ovan är inte tänkt att täcka alla aspekter av tillgångsorganisation och prestanda, men de är de jag har behandlat personligen under mitt dagliga arbete. Vänligen gärna dela några av dina tips nedan, i kommentarerna.