Image for Grunt.js – sposoby optymalizacji plików JavaScript w web aplikacjach

Grunt.js – sposoby optymalizacji plików JavaScript w web aplikacjach

Czas czytania:

Automatyzacja naszej pracy pomaga realizować projekty szybciej i sprawia, że programowanie staje się jeszcze bardziej przyjemne. W pracy Front-End Developer’a jest wiele czynności, które można poddać takiemu zabiegowi (np. łączenie i minimalizacja plików js oraz css, kompilacja plików pre-procesorów CSS, optymalizacja grafiki, generowanie Sprite CSS, Sprite SVG i wiele, wiele innych). Z pomocą w tej kwestii przychodzi Grunt.js.

Instalacja

  1. Node.js
    Do działania Grunt.js wymagany jest serwer Node.js. Należy go prostu pobrać i zainstalować z tej strony.
  2. Grunt-CLI (Grunt’s Command Line Iterface)Otwieramy systemowy terminal (dla Windows powinien być uruchomiony z uprawnieniami administratora, natomiast dla systemów UNIX’owych przed poniższą komendą należy dodać  „sudo”) i wpisujemy:
    npm install -g grunt-cli

    W celu sprawdzenia poprawności instalacji można wpisać polecenie:

    grunt --version

    W tym momencie mamy przygotowane środowisko do obsługi Grunt.js. Jest to procedura jednorazowa.

Konfiguracja projektu

W katalogu z projektem, w którym chcemy używać Grunt.js należy utworzyć plik package.json oraz Grunfile.js. Poniżej przedstawiona jest przykładowa struktura plików oraz konfiguracja Grunt.js w celu łączenia oraz minimalizowania plików js w projekcie. W sekcji „Materiały dodatkowe” zamieszczam linki do artykułów szerzej omawiających konfigurację w.w. plików.

struktura plików

root 
|-- Gruntfile.js 
|-- index.html 
|-- js |   
|-- lib |   
|   |-- lib-1.js |   
|   |-- lib-2.js |   
|   |-- lib-3.js |   
|   |-- lib-4.js |   
|   |-- lib-5.js |   
|   `-- lib-6.js |   
|-- main.js |   
|-- modules |   
|   |-- module-1.js 
|   |   `-- module-2.js 
`-- package.json

Powyższa struktura plików oprócz plików Gruntfile.js oraz package.json zawiera także plik index.html oraz pliki js, które są poddawane optymalizacji.

package.json

{  
"name": "Test",  
"version": "0.1.0",  
"author": "Artur",  
"private": true,  
"devDependencies": {    
"grunt": "^0.4.5",    
"grunt-contrib-concat": "^0.5.0",    
"grunt-contrib-uglify": "^0.5.1",    
"grunt-contrib-watch": "~0.6.1"  
} 
}

„devDependencies” zawiera deklarację Grunt.js oraz listę pluginów do instalacji:

Mając gotowy plik package.json można przystąpić do instalacji wszystkich zależności w nim zadeklarowanych. W tym celu należy w wierszu poleceń, będąc w katalogu zawierającym omawiany plik, wykonać komendę:

npm install

Gruntfile.js

module.exports = function(grunt){  'use strict';  grunt.initConfig({   pkg: grunt.file.readJSON('package.json'),   // Concat   concat: {    scripts: {     src: [      'js/lib/lib-1.js',      'js/lib/lib-2.js',      'js/lib/lib-3.js',      'js/lib/lib-4.js',      'js/lib/lib-5.js',      'js/lib/lib-6.js',      'js/main.js'     ],     dest: 'js/minified/scripts.js',    }   },   // Uglify   uglify: {    options: {     preserveComments: 'some'    },    scripts: {     files: {      'js/minified/scripts.min.js': ['js/minified/scripts.js']     }    },    modules: {     expand: true, // Enable dynamic expansion.     cwd: 'js/modules', // Src matches are relative to this path.     src: ['**/*.js'], // Actual pattern(s) to match.     dest: 'js/minified', // Destination path prefix.     ext: '.min.js', // Dest filepaths will have this extension.     extDot: 'first' // Extensions in filenames begin after the first dot    }   },   // Watch   watch: {    js: {     files: ['js/*.js', 'js/modules/*.js'],     tasks: ['concat', 'uglify']    }   } }); grunt.loadNpmTasks('grunt-contrib-concat'); grunt.loadNpmTasks('grunt-contrib-uglify'); grunt.loadNpmTasks('grunt-contrib-watch'); grunt.registerTask('default', ['concat', 'uglify', 'watch']); };

W pliku Grunfile.js zawarta jest cała konfiguracja działania poszczególnych pluginów:

  1. Concat (grunt-contrib-concat) Pliki:  lib-1.js, lib-2.js,  lib-3.js, lib-4.js, lib-5.js, lib-6.js, main.js. łączone są w jeden wynikowy plik scripts.js. W tym przypadku ważna jest ich kolejność deklaracji, żeby pliki pluginów były przed plikami je wywołującymi.  Dzięki zabiegowi łączenia, z 7 zapytań do serwera otrzymujemy tylko zapytanie o 1 plik, zyskując na czasie ładowania strony.
  2. Uglify (grunt-contrib-uglify) Task „concat” jest podzielony na dwa pod zadania: – „scripts” Zawartość utworzonego przez poprzedni plugin pliku scripts.js zostaje skompresowana i zapisana do pliku scripts.min.js. Dzięki temu otrzymujemy plik o mniejszym rozmiarze, a zatem również zyskujemy na czasie ładowania strony. – „modules” W bardzo rozbudowanych projektach warto odseparować js dedykowany wyłącznie dla danej części aplikacji, żeby niepotrzebnie nie zwiększały znacznie rozmiaru pliku, w którym i tak nie zostanie wykorzystany. Pliki z katalogu „modules” są automatycznie minimalizowane i zamieniane na plik z końcówką „.min.js”.
    Opcja:

     

    preserveComments: 'some'

    nakazuje podczas kompresji zachowanie komentarzy zaczynających się od lub zawierających w swojej treści dyrektywy @preserve @license @cc_on.Dzięki temu nie zostają usunięte informacje o autorze i licencji pluginów. Więcej opcji znajduje się na stronie pluginu.

  3. Watch (grunt-contrib-watch)Jeżeli zostanie wykonana jakakolwiek zmiana w plikach js w wybranych lokalizacjach, zostanie uruchomiony task „concat”, a następnie „uglify”. Dzięki temu nie trzeba za każdym razem uruchamiać ręcznie grunt’a.

Gdy plik jest gotowy, całość uruchamiana jest za pomocą komendy:

grunt

Wynikowa struktura plików wygląda następująco:

root 
|-- Gruntfile.js 
|-- index.html 
|-- js 
|   |-- lib 
|   |   |-- lib-1.js 
|   |   |-- lib-2.js 
|   |   |-- lib-3.js 
|   |   |-- lib-4.js 
|   |   |-- lib-5.js 
|   |   `-- lib-6.js 
|   |-- main.js 
|   |-- minified 
|   |   |-- module-1.min.js 
|   |   |-- module-2.min.js 
|   |   |-- scripts.js 
|   |   `-- scripts.min.js 
|   |-- modules 
|   |   |-- module-1.js 
|   |   `-- module-2.js 
|-- node_modules 
|   |-- grunt 
|   |-- grunt-contrib-concat 
|   |-- grunt-contrib-uglify 
|   `-- grunt-contrib-watch 
`-- package.json

Dodany został katalog node_modules z zainstalowanym Grunt.js i pluginami oraz katalog minified ze zoptymalizowanymi plikami js.

Wyniki optymalizacji

Przed

grunt-js-before

Czas ładowania strony: 251ms.

Po

grunt-js-after

Czas ładowania strony: 135ms.

Podsumowanie

Optymalizacja plików javascript ma bardzo duży wpływ na szybkość ładowania strony. Już przy połączeniu 7 plików w 1 i kompresji, czas ładowania strony zmniejszył się praktycznie dwukrotnie. Manualna optymalizacja jest bardziej uciążliwa, szczególnie przy pracy w zespole przy dużym projekcie. Jednakże z pomocą przychodzi Grunt.js, dzięki któremu wszystko przebiega szybko, sprawnie i automatycznie.

Materiały dodatkowe

Grunt.js
Grunt.js – Getting started
grunt-contrib-concat
grunt-contrib-uglify
grunt-contrib-watch

Zainteresował Cię ten artykuł?

Oferujemy profesjonalne wsparcie programistów w technologii Web.
Może Cię również zainteresować:
Clutch Recognizes GOGOmedia as a 2022 Development Leader in Poland

GOGOmedia is a multidisciplinary team with vast experience in the digital technology space. We deliver… Read More

Zatrzymać użytkownika na stronie — 4 praktyczne sposoby

Tworząc stronę, zadaliście się sobie mnóstwo trudu. Macie dobre teksty, poprawne UX i atrakcyjny design,… Read More