Kompresowanie plików za pomocą interfejsu Closure Compiler Service API

Kompilator zamknięty został wycofany i zostanie usunięty. Zamiast tego rozważ uruchomienie kompilatora lokalnie.

Omówienie

Komunikaty dotyczące interfejsu API zawierały podstawowe informacje o tym, jak komunikować się z usługą Closure Compiler, ale za pomocą tej usługi można usunąć tylko komentarze z jednego wiersza kodu JavaScript. W tym samouczku pokazujemy, jak używać usługi kompilatora Closure.

W tym samouczku zakładamy, że masz podstawową znajomość JavaScriptu i HTTP. Do przesyłania kodu JavaScript do usługi Closure Compiler używany jest skrypt w Pythonie, ale nie trzeba znać języka Python, żeby postępować zgodnie z przykładem.

  1. Skompresowanie pliku
  2. Zwiększanie kompresji
    1. Jak bardzo kod jest mniejszy?
    2. W jaki sposób usługa kompilatora zamkniętego zmniejszyła program?
  3. Kolejne kroki

Kompresowanie pliku

Przykład podany w komunikacji z interfejsem API przekazał ciąg znaków JavaScript jako parametr wiersza poleceń do skryptu kompilacji. Takie podejście nie sprawdza się jednak w przypadku programu JavaScript o realistycznym rozmiarze, ponieważ ciąg znaków JavaScript szybko staje się niezrozumiały, gdy kod jest dłuższy niż kilka wierszy. W przypadku większych programów możesz użyć parametru żądania code_url, aby określić nazwę pliku JavaScript do przetworzenia. Oprócz js_code możesz też użyć code_url lub zamiennika js_code.

Weźmy na przykład taki program JavaScript:

/**
 * A simple script for adding a list of notes to a page. The list diplays
 * the text of each note under its title.
 */

/**
 * Creates the DOM structure for a note and adds it to the document.
 */
function makeNoteDom(noteTitle, noteContent, noteContainer) {
  // Create DOM structure to represent the note.
  var headerElement = document.createElement('div');
  var headerText = document.createTextNode(noteTitle);
  headerElement.appendChild(headerText);

  var contentElement = document.createElement('div');
  var contentText = document.createTextNode(noteContent);
  contentElement.appendChild(contentText);

  var newNote = document.createElement('div');
  newNote.appendChild(headerElement);
  newNote.appendChild(contentElement);

  // Add the note's DOM structure to the document.
  noteContainer.appendChild(newNote);
}

/**
 * Iterates over a list of note data objects and creates a DOM
 */
function makeNotes(data, noteContainer) {
  for (var i = 0; i < data.length; i++) {
    makeNoteDom(data[i].title, data[i].content, noteContainer);
  }
}

function main() {
  var noteData = [
      {title: 'Note 1', content: 'Content of Note 1'},
      {title: 'Note 2', content: 'Content of Note 2'}];
  var noteListElement = document.getElementById('notes');
  makeNotes(noteData, noteListElement);
}

main();

Ten program możesz łatwiej przesłać do usługi Closure Compiler jako plik, a nie jako jeden duży ciąg. Aby przetworzyć plik za pomocą usługi, wykonaj te czynności:

  1. Zapisz kod JavaScript w pliku.
  2. Udostępnij plik w internecie (np. przesyłając go na serwer WWW).
  3. Wyślij żądanie POST do usługi Closure Compiler, tak jak to zostało opisane w komunikacji z interfejsem API, ale w przypadku parametru js_code zastąp parametr code_url. Wartością code_url musi być adres URL pliku JavaScript utworzonego w kroku 1.

Kod JavaScript tego przykładu można znaleźć w pliku tutorial2.js. Aby przetworzyć ten plik za pomocą interfejsu API usługi Closure Compiler, zmień program Pythona z komunikacji z tym interfejsem API na code_url:

#!/usr/bin/python2.4

import httplib, urllib, sys

# Define the parameters for the POST request and encode them in
# a URL-safe format.

params = urllib.urlencode([
    ('code_url', sys.argv[1]), # <--- This parameter has a new name!
    ('compilation_level', 'WHITESPACE_ONLY'),
    ('output_format', 'text'),
    ('output_info', 'compiled_code'),
  ])

# Always use the following value for the Content-type header.
headers = { "Content-type": "application/x-www-form-urlencoded" }
conn = httplib.HTTPSConnection('closure-compiler.appspot.com')
conn.request('POST', '/compile', params, headers)
response = conn.getresponse()
data = response.read()
print data
conn.close()

Uwaga: aby odtworzyć ten przykład, użytkownicy systemu Windows mogą zainstalować Pythona. Przeczytaj sekcję Najczęstsze pytania na temat Pythona Windows, aby dowiedzieć się, jak zainstalować i używać Pythona w systemie Windows.

Wyślij kod do kompilatora zamkniętych za pomocą tego polecenia:

$ python compile.py https://closure-compiler.appspot.com/closure/compiler/samples/tutorial2.js

Usługa Closure Compiler pobiera plik z witryny https://closure-compiler.appspot.com/closure/compiler/samples/tutorial2.js i zwraca w odpowiedzi skompresowany kod JavaScript.

Aby skompilować wiele plików wyjściowych w jedny plik wyjściowy, uwzględnij wiele parametrów code_url, jak w tym przykładzie:

params = urllib.urlencode([
    # Multiple code_url parameters:
    ('code_url', 'http://yourserver.com/yourJsPart1.js'),
    ('code_url', 'http://yourserver.com/yourJsPart2.js'),
    ('compilation_level', 'WHITESPACE_ONLY'),
    ('output_format', 'text'),
    ('output_info', 'compiled_code'),
  ])

Poprawa kompresji

W przykładach wykorzystano compilation_level WHITESPACE_ONLY, które usuwają tylko komentarze i spacje. Dzięki poziomowi kompresji SIMPLE_OPTIMIZATIONS możesz osiągnąć znacznie wyższe współczynniki kompresji. Aby użyć kompresji SIMPLE_OPTIMIZATIONS, zmień parametr compilation_level na SIMPLE_OPTIMIZATIONS:

params = urllib.urlencode([
    ('code_url', sys.argv[1]),
    ('compilation_level', 'SIMPLE_OPTIMIZATIONS'),  # <--- This parameter has a new value!
    ('output_format', 'text'),
    ('output_info', 'compiled_code'),
  ])

i uruchom skrypt w zwykły sposób:

$ python compile.py https://closure-compiler.appspot.com/closure/compiler/samples/tutorial2.js

Dane wyjściowe powinny wyglądać tak:

var GLOBAL_document=document,$$PROP_appendChild="appendChild";function makeNoteDom(a,b,c){var d=GLOBAL_document.createElement("div");a=GLOBAL_document.createTextNode(a);d[$$PROP_appendChild](a);a=GLOBAL_document.createElement("div");b=GLOBAL_document.createTextNode(b);a[$$PROP_appendChild](b);b=GLOBAL_document.createElement("div");b[$$PROP_appendChild](d);b[$$PROP_appendChild](a);c[$$PROP_appendChild](b)}function makeNotes(a,b){for(var c=0;c<a.length;c++)makeNoteDom(a[c].title,a[c].content,b)}
function main(){var a=[{title:"Note 1",content:"Content of Note 1"},{title:"Note 2",content:"Content of Note 2"}],b=GLOBAL_document.getElementById("notes");makeNotes(a,b)}main();

Ten kod jest trudniejszy do odczytania niż program źródłowy, ale jest mniejszy.

O ile mniejszy jest kod?

Jeśli zmienisz parametr output_info w parametrach żądania z compiled_code na statistics, możemy dokładnie zobaczyć, ile miejsca zaoszczędziliśmy:

Original Size: 1372
Compressed Size: 677
Compilation Time: 0

Nowy kod JavaScript ma mniej niż połowę rozmiar oryginału.

Jak usługa kompilatora sprzątania zmniejszyła program?

W tym przypadku Kompresor zamknięty dokonuje częściowego zmniejszenia rozmiaru przez zmianę nazw lokalnych zmiennych. Na przykład oryginalny plik zawiera ten wiersz kodu:

var headerElement = document.createElement('div');

Kompresor zamknięty zmienia to oświadczenie na:

var d=document.createElement("div");

Kompilator zamknięty zmienia symbol headerElement na d w każdym miejscu funkcji makeNoteDom i dlatego zachowa tę funkcjonalność. Jednak 13 znaków „headerElement” został skrócony do 3 znaków w każdym z tych 3 miejsc. Dzięki temu można zaoszczędzić 36 znaków.

Kompilacja z parametrem SIMPLE_OPTIMIZATIONS zawsze zachowuje funkcje o prawidłowym składni JavaScript, pod warunkiem że kod nie uzyskuje dostępu do zmiennych lokalnych za pomocą nazw ciągów (np. instrukcji eval()).

Dalsze kroki

Teraz gdy znasz już funkcję SIMPLE_OPTIMIZATIONS i podstawy korzystania z niej, następnym krokiem jest poznanie poziomu kompilacji. Ten poziom wymaga wykonania kilku dodatkowych czynności, aby JavaScript mógł działać tak samo przed kompilacją i po nim, ale sprawia, że jest on jeszcze mniejszy. Więcej informacji o ADVANCED_OPTIMIZATIONS znajdziesz w artykule Zaawansowane kompilacje i rozszerzenia.