Mapy źródeł – CSS & JS source maps

Może spotkałeś(-aś) się z plikami .map, na przykład używając bibliotek JavaScript’owych. Ten post tłumaczy, do czego one służą i dlaczego warto ich używać.

Temat: Tworzenie stron internetowych
Dział: Front-end
Poziom: Średniozaawansowany

Krótkie wprowadzenie

Kod w przeglądarce po stronie klienta nie musi być czytelny. Poniższe przykłady są równoznaczne.

p.lead,
header.lead,
header .lead {
  text-align: center;
  font-size: 2rem;
}

#navigation {
  padding: 0 20px 1em 20px;
}

header .lead,header.lead,p.lead{text-align:center;font-size:2rem}#navigation{padding:0 20px 1em}
var typeFilter = function (type, array) {
  var test = function (value) {
    return (value.length)
        ? (value[0].toLowerCase() === type.toLowerCase())
        : false;
  };
  return $filter('filter')(array, test);
};
var f=function(e,r){var t=function(r){return r.length?r[0].toLowerCase()===e.toLowerCase():!1};return $filter("filter")(r,t)};

 

Istnieje wiele sposobów na skompresowanie swojego kodu, ale o praktycznych aspektach za chwilę. Minifikacja* (usuwanie zbędnych znaków) jest bardzo pożyteczną praktyką ze względu na wielkość pliku. Niestety komplikuje to debugowanie.

Debugowanie nieczytelnego kodu CSS

Tutaj zaczyna się magia: DevTool w przeglądarce jest w stanie odtwożyć z której linijki jakiego pliku źródłowego dany fragment pochodzi, jeśli dostarczymy mu mapę. Oznacza to, że możesz mieć wgląd w źródła nawet kiedy strona wczytuje „zmielony” i nieczytelny kod.

* Kalka z angielskiego (minification). Tak brzmi hasło w Wikipedii. Dlatego nie lubię pisać na techniczne tematy po polsku.

Praktyka

Jeśli już korzystasz z jakiegokolwiek narzędzia wymagającego używania konsoli (gulp, Grunt, npm scripts) na pewno poradzisz sobie ze znalezieniem opcji umożliwiających wygenerowanie mapy. W przypadku różnego rodzaju dodatków do edytora/IDE może być różnie. Ja zwykle używam gulp’a, albo wtyczki do edytora Brackets. Opisywanie każdego narzędzia nie ma sensu. Zamiast tego proponuję prosty i darmowy program, z którym każdy powinien sobie poradzić.

Aplikacja Koala

Koala. Ustawienia z prawej umożliwiają wygenerowanie mapy.

Jak to działa?

Mapę do kodu można dołączyć na dwa sposoby:

  1. Za pomocą komentarza na końcu pliku:
    /*# sourceMappingURL=style.css.map */
    //# sourceMappingURL=/katalog/functions.js.map
  2. Poprzez nagłówek HTTP X-SourceMap:
    X-SourceMap: /inny_katalog/script.js.map

Szczerze powiedziawszy, nie spotkałem się jeszcze z zastosowaniem tej drugiej opcji.

Składnia pliku to dość czytelny na pierwszy rzut oka JSON. Przykładowo:

{
  "version": 3,
  "file": "style.css",
  "sources": [
    "style.scss"
  ],
  "mappings": ";AAAA,AAAA,IAAI,CAAC;EACH,…",
  "names": []
}

Najciekawszą częścią jest oczywiście mappings. Dane tam zapisane można przetłumaczyć jako:

wiersz: kolumna->w_źródła:k_źródła, kolumna->w_źródła:k_źródła

Dobrym sposobem na zrozumienie o co chodzi jest zobaczenie wizualizacji.

Algorytm to VLQ zakodowany w Base64. Ciekawostka: format ten został po raz pierwszy zdefiniowany do kodowania muzyki w formacie MIDI.

Techniczne szczegóły

Jeśli dalej Ci mało, to prawdopodobnie masz za dużo wolnego czasu. Odsyłam do oryginalnej dokumentacji. Poza tym polecam poradnik Introduction to JavaScript Source Maps i post How do source maps work?, dzięki którym ogarnąłem ten temat.


Frameworki CSS i Material Design Lite

Od jakiegoś czasu dostaję pytania w sprawie „frejmłorków”. W sieci można znaleźć mnóstwo blogów na ten temat. Pisanie własnego eseju, albo porównanie funkcji wydaje mi się bezcelowe. W tej chwili pewno straciłem połowę publiczności, więc nie chcąc stracić reszty zacznę od podsumowania współczesnych (jak na początek 2016) rozwiązań:

  • Dla początkujących polecam Bootstrap 3. Jest łatwy do opanowania, między innymi dzięki ogromnej popularności i wynikającemu z niej wsparciu społeczności.
  • Aktualnie najnowocześniejszym rozwiązaniem jest Foundation 6, którego zaletami jest świetne działanie na urządzeniach mobilnych i poręczny kod SCSS.
  • W wielu przypadkach okaże się, że nie potrzebujesz bardzo zaawansowanych narzędzi. Istnieje mnóstwo małych i praktycznych frameworków, wśród których popularnością wyróżnia się Skeleton.

Co to jest „framework”?

Z angielskiego chodzi tu o strukturę, „ramę”, od której zaczyna się pracę. Framework CSS powinien zawierać:

  • Reset (normalizację) stylów przeglądarki
  • Układ (layout) ułatwiający pozycjonowanie treści (grid system)
  • Ujednolicenie podstawowych elementów (typografii, formularzy itp.)

W poprzedniej sekcji specjalnie nie nazwałem Bootstrapa ani Foundation frameworkami CSS. Dlaczego? Bo nimi nie są! Można to porównać do nazywania Drupala albo WordPressa frameworkiem PHP. Bardziej adekwatną nazwą jest front-end framework, jako że front-end (fasada – wszystko co serwis wyświetla użytkownikowi) dotyczy także skryptów i struktury strony. Słyszałem też bardzo adekwatną nazwę „UI Toolkit” (zestaw narzędzi dla interfejsu użytkownika).

Google Material Design

Ciągnąc wyjaśnienia dalej, Material Design nie jest ani frameworkiem CSS, ani frameworkiem front-endowym. Czym w takim razie jest? To ciekawy zestaw zasad projektowania, dostępny pod adresem www.google.com/design/spec/material-design/. Cała specyfikacja jest zaskakująco uniwersalna i intuicyjna.

Material Design Lite

Material Design Lite – wybór kolorkówOficjalna implementacja Material Design dostępna jest na getmdl.io. Najbardziej precyzyjny opis z jakim się spotkałem, to „a library of components & templates” – biblioteka komponentów i szablonów. Terminologia bywa myląca, ale nie przejmuj się – Antyweb nazwał MDL uniwersalnym frameworkiem dla webmasterów xD.

W przypadku Bootstrapa i Foundation największą zaletą jest modułowość. Znając podstawy preprocesora SASS można łatwo wybrać potrzebne elementy (na przykład framework CSS) i dostosować wygląd. Material Design Lite nie jest pod tym względem zbyt praktyczny. Nie polecam tworzenia i ręcznego kompilowania własnej wersji. Próbowałem. Realistycznie mamy jedynie możliwość dobrania dwóch głównych kolorów. Większa ingerencja wiąże się raczej z nadpisywaniem kodu CSS, czego nie polecam. Zastanawiałem się nad użyciem MDL do mojego kolejnego projektu, ale się rozmyśliłem. Może innym razem.

Alternatywy

Na szczęście istnieje wiele innych wersji, poza tą oficjalną. Wszystkim, którzy czekali na „Bootstrapa od Google” pewno spodoba się Materialize. Poza tym znalazłem motywy/nakładki na wcześniej wspominane popularne frameworki front-endowe, jednak przed ich użyciem stanowczo polecam przeglądnięcie oryginalnych wytycznych.

Podsumowanie

wybór narzędzia


Optymalizacja wczytywania strony

Poza zawartością i wyglądem witryny lub aplikacji powinniśmy dbać także o wygodę korzystania z niej. Pierwszymi rzeczami z którymi (świadomie, lub «oby» nie) styka się użytkownik jest pobieranie, renderowanie i wyświetlanie naszej treści przez przeglądarkę. Mamy wtedy świetną okazję, żeby już w pierwszych sekundach zdenerwować naszego klienta.

Co za dużo, to niezdrowo

… doskonałość osiąga się nie wtedy, kiedy nie można nic już dodać, ale kiedy nie można nic już zabrać.   Antoine de Saint-Exupéry, Ziemia, planeta ludzi

Można by jeszcze dodać, że „Najważniejsze jest…” (neee. Nie lubię tego cytatu. I tej książki.). Skupmy się na konkretach: ilości i rozmiar plików. Zaczynając od podstaw: ważne by na serwerze włączona była kompresja gzip. Mając to z głowy, zastanówmy się ile zbędnych bajerów, głównie skryptów, wpakowaliśmy. Okazuje się, że „możesz nie potrzebować jQuery”. Przypomnę jeszcze, że instalowanie losowych wtyczek do systemu zarządzania treścią to prosta droga do katastrofy.

Grafika

Obrazki mają zwykle znacznie większy rozmiar od tekstów, arkuszy stylów i skryptów. Wczytywanie ich w odpowiedni sposób jest bardzo ważne dla optymalizacji ładowania strony. Pierwszym i podstawowym krokiem jest kompresja. Ze stratną kompresją JPEG lepiej nie przesadzać, ale póki artefakty nie zaczynają być widoczne, zwiększenie o kilka procent nie zaszkodzi. Warto pamiętać, że grafiki PNG można bezstratnie skompresować nawet o kilkadziesiąt procent. Polecam w tym celu stronę tinypng.com. Dodatkowym bardzo przydatnym trikiem jest przygotowanie miejsca o wielkości grafiki i wypełnienie go uśrednionym kolorem. Tak robi na przykład Pinterest.

Wektory na ratunek

Wszystkie nowoczesne przeglądarki (i Internet Exploder Explorer od wersji 9) wspierają format SVG. Trzeba trochę z tym uważać, bo nie wszystkie w równym stopniu. Tak czy inaczej stworzone w ten sposób grafiki ważą znacznie mniej. Dodatkowo istnieje możliwość osadzenia ich bezpośrednio w kodzie, dzięki czemu zmniejszamy ilość odwołań do serwera. Wadą tego rozwiązania jest wczytywanie tej samej treści przy każdym odświeżeniu strony. Rozwiązać to można na przykład za pomocą opóźnionego ładowania i Kukiz Cookies. Przy pierwszym ładowaniu serwujemy wersję osadzoną w kodzie, wczytujemy plik w tle po załadowaniu innych elementów strony i ustawiamy ciasteczko, dzięki któremu przy kolejnym wczytaniu odniesiemy się do załadowanego pliku zamiast ponownie umieszczać grafikę w kodzie.

It’s all about that bass base

Jest jeszcze jeden sposób na osadzania grafik dowolnego typu w kodzie HTML lub CSS. Data URI z kodowaniem Base64. Znacznie ułatwiają to prekompilatory (SASS, LESS). Z powodu opisanego powyżej proponuję stosowanie tego typu rozwiązania raczej w kodzie CSS. Metoda nie jest bez wad. Po więcej szczegółów odsyłam od Chrisa Coyiera na css-tricks.com/data-uris/.

Ładowanie sekwencyjne (progresywne)

Przez ustawienie elementów w odpowiedniej kolejności w kodzie i użycie zdarzeń document.ready i window.load możemy nadać priorytet części zawartości. Osobiście używam takiej listy priorytetów:

  1. HTML – treść, a przynajmniej widoczna jej część, powinna być pobierana w pierwszym zapytaniu.
  2. Podstawowy CSS – wielkość fontu i szerokość kolumn, tło większych elementów.
  3. Font – tak wysoko na mojej liście z dwóch powodów:
    1. Przeglądarki w większości dają nam aktualnie 3 sekundy na dostarczenie przed wyświetleniem zamiennika.
    2. O ile nie używamy przesadnej ilości krojów, mamy do czynienia z sensownie niewielkimi plikami.
  4. Ważne skrypty, np. otwieranie menu.
  5. Reszta stylu – główny plik CSS zawierający zwykle framework.
  6. Grafika

Jest kilka cyfr, o których warto pamiętać:

  • 300ms na pojawienie się pierwszych elementów strony.
  • 3s na (w miarę) kompletne załadowanie.
  • 10s jako granica po przekroczeniu której użytkownik traci zainteresowanie, a czasem cierpliwość.

Przy czym nie każdy ma turbo internet. Pod tym względem warto brać przykład z Facebooka (Wtorki z 2G). DevTool w Chrome ma opcję ograniczania transferu (network throttling). Oto co goście z Google mają do powiedzenia w temacie:

Miałem zamiar dodać jeszcze coś o optymalizacji pod urządzenia mobilne, ale to już temat na kolejny wpis.

Studium przypadku

Przy połączeniu 3G przed optymalizacją (po lewej) mija ponad 2 sekundy do pojawienia się czegokolwiek. Efekty w tym przypadku są mało widoczne, bo i projekt jest niewielki.