Gelişmiş Derleme

Genel bakış

Kapatma Derleyici'yi compilation_level ADVANCED_OPTIMIZATIONS ile kullanmak, SIMPLE_OPTIMIZATIONS veya WHITESPACE_ONLY ile derlemeden daha iyi sıkıştırma oranları sunar. ADVANCED_OPTIMIZATIONS ile derleme, kodu dönüştürme ve simgeleri yeniden adlandırma yöntemlerinde daha agresif davranarak ekstra sıkıştırma sağlıyor. Bununla birlikte, daha agresif bir yaklaşım, çıkış kodunun giriş koduyla aynı şekilde çalışmasını sağlamak için ADVANCED_OPTIMIZATIONS kullanırken daha dikkatli olmanız gerektiği anlamına gelir.

Bu eğiticide ADVANCED_OPTIMIZATIONS derleme düzeyinin işlevi ve kodunuzun ADVANCED_OPTIMIZATIONS ile derlemeden sonra çalışmasını sağlamak için neler yapabileceğiniz gösterilmektedir. Bu işlev ayrıca derleyici tarafından işlenen kodun dışındaki kodda tanımlanan ext kavramını da tanıtır.

Bu eğiticiyi okumadan önce JavaScript'i Closure Compiler araçlarından biriyle derleme işlemine (derleyici hizmet kullanıcı arayüzü, derleyici hizmeti API veya derleyici uygulaması) aşina olmanız gerekir.

Terminolojiyle ilgili bir not: --compilation_level komut satırı işareti, yaygın olarak kullanılan kısaltmalar ADVANCED ve SIMPLE'yi desteklerken daha kesin olan ADVANCED_OPTIMIZATIONS ve SIMPLE_OPTIMIZATIONS'i de destekler. Bu doküman daha uzun biçim kullanıyor ancak adlar komut satırında birbirinin yerine kullanılabilir.

  1. Daha İyi Sıkıştırma
  2. ADVANCED_OPTIMIZATIONS nasıl etkinleştirilir?
  3. ADVANCED_OPTIMIZATIONS Kullanılırken Dikkat Edilmesi Gerekenler
    1. Saklamak istediğiniz Kodu Kaldırma
    2. Tutarsız Mülk Adları
    3. İki Bölümün Ayrı Olarak Derlenmesi
    4. Derlenmiş ve Derlenmemiş Kod Arasındaki Bozuk Referanslar

Daha İyi Sıkıştırma

Varsayılan SIMPLE_OPTIMIZATIONS derleme seviyesi olan Closure Compiler, yerel değişkenleri yeniden adlandırarak JavaScript'i küçültüyor. Bununla birlikte, yerel değişkenler dışında kısaltılabilen simgeler vardır. Ayrıca simgeleri yeniden adlandırma dışında da küçültebilir. ADVANCED_OPTIMIZATIONS ile derleme, tüm kod parçalama olanaklarından çok yararlanır.

Aşağıdaki kod için SIMPLE_OPTIMIZATIONS ve ADVANCED_OPTIMIZATIONS sonuçlarını karşılaştırın:

function unusedFunction(note) {
  alert(note['text']);
}

function displayNoteTitle(note) {
  alert(note['title']);
}

var flowerNote = {};
flowerNote['title'] = "Flowers";
displayNoteTitle(flowerNote);

SIMPLE_OPTIMIZATIONS ile derlemede kodun kısaltması:

function unusedFunction(a){alert(a.text)}function displayNoteTitle(a){alert(a.title)}var flowerNote={};flowerNote.title="Flowers";displayNoteTitle(flowerNote);

ADVANCED_OPTIMIZATIONS ile derlemede kodun tamamı kısaltılır:

alert("Flowers");

Bu komut dosyalarının her ikisi de "Flowers" yazan bir uyarı üretir ancak ikinci komut dosyası çok daha küçüktür.

ADVANCED_OPTIMIZATIONS düzeyi, değişken adlarının basit bir şekilde kısaltmasının ötesine geçer. Bunlardan bazıları:

  • daha agresif bir yeniden adlandırma:

    SIMPLE_OPTIMIZATIONS ile derleme, komut dosyasında yalnızca bir işleve özel olan değişkenler olduğundan, displayNoteTitle() ve unusedFunction() işlevlerinin note parametrelerini yalnızca yeniden adlandırır. ADVANCED_OPTIMIZATIONS, flowerNote global değişkenini de yeniden adlandırır.

  • ölü kodu kaldırma:

    ADVANCED_OPTIMIZATIONS derlemesi, kodda hiçbir zaman çağrılmadığı için unusedFunction() işlevini tamamen kaldırır.

  • işlevi satır içine alma:

    ADVANCED_OPTIMIZATIONS ile derleme, displayNoteTitle() çağrısını işlevin gövdesini oluşturan alert() ile değiştirir. Bir işlev çağrısının, işlevin gövdesiyle değiştirilmesi, "satır içi" olarak bilinir. İşlev daha uzun veya karmaşıksa satır içine almak, kodun davranışını değiştirebilir. Ancak, Kapatma Derleme Aracı'nın bu durumda satır içinin güvenli olduğunu ve alan tasarrufu sağladığını belirler. ADVANCED_OPTIMIZATIONS ile derleme ayrıca, güvenli bir şekilde yapabildiğini belirlerken sabit değerleri ve bazı değişkenleri de satır içine alır.

Bu liste, ADVANCED_OPTIMIZATIONS derlemesinin gerçekleştirebileceği boyut azaltma dönüşümlerine yalnızca bir örnektir.

ADVANCED_OPTIMIZATIONS nasıl etkinleştirilir?

Closure Compiler hizmeti kullanıcı arayüzü, service API'si ve uygulaması, compilation_level öğesini ADVANCED_OPTIMIZATIONS olarak ayarlamak için farklı yöntemlere sahiptir.

Kapatma Derleyici Hizmeti kullanıcı arayüzünde ADVANCED_OPTIMIZATIONS nasıl etkinleştirilir?

Closure Compiler hizmeti kullanıcı arayüzünde ADVANCED_OPTIMIZATIONS özelliğini etkinleştirmek için "Gelişmiş" radyo düğmesini tıklayın.

Closure Compiler service API'de ADVANCED_OPTIMIZATIONS nasıl etkinleştirilir?

Closure Compiler service API için ADVANCED_OPTIMIZATIONS öğesini etkinleştirmek amacıyla aşağıdaki python programında olduğu gibi ADVANCED_OPTIMIZATIONS değerine sahip, compilation_level adlı bir istek parametresi ekleyin:

#!/usr/bin/python2.4

import httplib, urllib, sys

params = urllib.urlencode([
    ('code_url', sys.argv[1]),
    ('compilation_level', 'ADVANCED_OPTIMIZATIONS'),
    ('output_format', 'text'),
    ('output_info', 'compiled_code'),
  ])

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()

Closure Compiler uygulamasında ADVANCED_OPTIMIZATIONS nasıl etkinleştirilir?

Closure Compiler uygulaması için ADVANCED_OPTIMIZATIONS'i etkinleştirmek üzere aşağıdaki komutta olduğu gibi --compilation_level ADVANCED_OPTIMIZATIONS komut satırı işaretini ekleyin:

java -jar compiler.jar --compilation_level ADVANCED_OPTIMIZATIONS --js hello.js

ADVANCED_OPTIMIZATIONS Kullanılırken Dikkat Edilmesi Gerekenler

ADVANCED_OPTIMIZATIONS ile ilgili bazı yaygın istenmeyen durumlar ve bunlardan kaçınmak için uygulayabileceğiniz adımlar aşağıda açıklanmıştır.

Saklamak İstediğiniz Kodun Kaldırılması

Aşağıdaki işlevi yalnızca ADVANCED_OPTIMIZATIONS ile derlerseniz Closure Compiler boş çıkış üretir:

function displayNoteTitle(note) {
  alert(note['myTitle']);
}

Bu işlev, derleyiciye ilettiğiniz JavaScript'te hiçbir zaman çağrılmadığı için Closure Compiler bu kodun gerekli olmadığını varsayar.

Çoğu durumda bu davranış tam olarak istediğiniz şeydir. Örneğin, kodunuzu büyük bir kitaplıkla birlikte derlerseniz Closure Compiler, söz konusu kitaplıktaki hangi işlevleri kullandığınızı belirleyebilir ve kullanmadığınız işlevleri kaldırabilir.

Ancak, Closure Compiler'ın saklamak istediğiniz işlevleri kaldırdığını görürseniz bunu önlemenin iki yolu vardır:

  • İşlev çağrılarınızı Closure Compiler tarafından işlenen koda taşıyın.
  • Göstermek istediğiniz işlevlerin çıkışlarını ekleyin.

Sonraki bölümlerde, her bir seçeneği daha ayrıntılı olarak ele alacağız.

Çözüm: İşlev Aramalarınızı Kapatma Derleyici ile İşlenen Koda Taşıyın

Kodunuzun yalnızca bir bölümünü Closure Compiler ile derlerseniz istenmeyen kod kaldırma işlemleriyle karşılaşabilirsiniz. Örneğin, yalnızca işlev tanımlarını içeren bir kitaplık dosyanız ve kitaplığı içeren ve bu işlevleri çağıran kodu içeren bir HTML dosyanız olabilir. Bu durumda, kitaplık dosyasını ADVANCED_OPTIMIZATIONS ile derlerseniz Closure Compiler tüm kitaplık işlevlerinizi kaldırır.

Bu sorunun en basit çözümü, işlevlerinizi programınızın bu işlevleri çağıran kısmıyla birlikte derlemektir. Örneğin, Closure Compiler aşağıdaki programı derlerken displayNoteTitle() öğesini kaldırmaz:

function displayNoteTitle(note) {
  alert(note['myTitle']);
}
displayNoteTitle({'myTitle': 'Flowers'});

Bu durumda displayNoteTitle() işlevi, Closure Compiler işlevinin çağrıldığını gördüğü için kaldırılmaz.

Başka bir deyişle, programınızın giriş noktasını Closure Compiler'a ilettiğiniz koda dahil ederek istenmeyen kod kaldırma işlemlerini önleyebilirsiniz. Bir programın giriş noktası, kodun çalıştırılmaya başladığı yerdir. Örneğin, önceki bölümdeki çiçek notu programında son üç satır, JavaScript tarayıcıya yüklenir yüklenmez yürütülür. Bu programın giriş noktasıdır. Saklamanız gereken kodu belirlemek için Closure Compiler bu giriş noktasından başlar ve programın kontrol akışını oradan takip eder.

Çözüm: Göstermek istediğiniz İşlevler için istisnaları ekleyin

Bu çözümle ilgili daha fazla bilgiye aşağıda ve harcama ve dışa aktarma sayfalarında yer almaktadır.

Tutarsız Mülk Adları

Kapatıcı Derlemesi derlemesi, hiçbir zaman dize derlemenizi değiştirmez, kullandığınız derleme değişmez. Yani ADVANCED_OPTIMIZATIONS ile yapılan bir derleme, kodunuzun dizeye erişip erişmediğine bağlı olarak özellikleri farklı şekilde ele alır. Bir mülke verilen referansları nokta sözlü referanslarla birlikte kullanırsanız Closure Compiler bu mülke atıflarını belirtir ancak diğerlerini adlandırmaz. Bunun sonucunda kodunuz muhtemelen düzgün çalışmaz.

Örneğin, aşağıdaki kodu ele alalım:

function displayNoteTitle(note) {
  alert(note['myTitle']);
}
var flowerNote = {};
flowerNote.myTitle = 'Flowers';

alert(flowerNote.myTitle);
displayNoteTitle(flowerNote);

Bu kaynak koddaki son iki ifade tam olarak aynı şeyi yapar. Bununla birlikte, kodu ADVANCED_OPTIMIZATIONS ile sıkıştırdığınızda şunları elde edersiniz:

var a={};a.a="Flowers";alert(a.a);alert(a.myTitle);

Sıkıştırılmış koddaki son ifade bir hata oluşturur. myTitle özelliğine doğrudan referans, a olarak yeniden adlandırıldı ancak displayNoteTitle işlevinde myTitle için alıntılanan referans yeniden adlandırılmadı. Sonuç olarak son ifade, artık mevcut olmayan bir myTitle özelliğine başvuruda bulunuyor.

Çözüm: Mülk Adlarınızda Tutarlı Olun

Bu çözüm oldukça basittir. Herhangi bir tür veya nesne için yalnızca nokta söz dizimi veya tırnak içine alınmış dizeler kullanın. Söz dizimini, özellikle aynı mülke referans vererek karıştırmayın.

Ayrıca, daha iyi kontroller ve optimizasyonlar sağladığı için mümkün olduğunda nokta söz dizimi kullanmayı tercih edin. Tırnak içine alınmış dize özelliği erişimi, yalnızca Kod Kapatma Derleyici'nin yeniden adlandırılmasını istemediğinizde (örneğin, adın kodu çözülmüş JSON gibi) harici bir kaynaktan geldiğinde kullanın.

İki Bölümün Ayrı Numaralı Derlemesi

Uygulamanızı farklı kod parçalarına bölerseniz parçaları ayrı olarak derlemek isteyebilirsiniz. Bununla birlikte, iki kod parçası hiç etkileşimde bulunmazsa bu durum zorluk yaratabilir. Başarılı olmasanız bile iki Kapatma Derleyici çalıştırmasının sonucu uyumlu olmaz.

Örneğin, bir uygulamanın iki bölüme ayrıldığını varsayalım: verileri alan bölüm ve verileri görüntüleyen bölüm.

Verileri almak için kod şudur:

function getData() {
  // In an actual project, this data would be retrieved from the server.
  return {title: 'Flower Care', text: 'Flowers need water.'};
}

Verilerin görüntülenmesiyle ilgili kod şudur:

var displayElement = document.getElementById('display');
function displayData(parent, data) {
  var textElement = document.createTextNode(data.text);
  parent.appendChild(textElement);
}
displayData(displayElement, getData());

Bu iki kod parçasını ayrı olarak derlemeye çalışırsanız çeşitli sorunlarla karşılaşırsınız. Öncelikle, Kapatma Derleyici getData() işlevini kaldırmak istediğiniz Kaldırmak istediğiniz kodu kaldırma bölümünde açıklanan nedenlerle kaldırır. İkinci olarak, Kapatma Derleyici, verileri gösteren kodu işlerken önemli bir hata oluşturur.

input:6: ERROR - variable getData is undefined
displayData(displayElement, getData());

Derleyici, verileri gösteren kodu derlerken getData() işlevine erişemediğinden, getData özelliğini tanımlanmamış olarak işler.

Çözüm: Bir Sayfa İçin Tüm Kodu Birlikte Derleyin

Derlemenin doğru olmasını sağlamak için bir sayfanın tüm kodunu tek bir derlemede derleyin. Closure Compiler, giriş olarak birden fazla JavaScript dosyasını ve JavaScript dizesini kabul edebilir. Böylece kitaplık kodunu ve diğer kodu tek bir derleme isteğinde birlikte aktarabilirsiniz.

Not: Derlenen ve derlenmemiş kodu karıştırmanız gerekiyorsa bu yaklaşım işe yaramaz. Bu durumu ele almaya ilişkin ipuçları için Derlenmiş ve Derlenmemiş Kod arasındaki Bozuk Referanslar bölümüne bakın.

Derlenmiş Kodlar ile Derlenmemiş Kod Arasındaki Bozuk Referanslar

ADVANCED_OPTIMIZATIONS içindeki simgenin yeniden adlandırılması, Closure Compiler tarafından işlenen kod ile diğer kodlar arasındaki iletişimi bozar. Derleme, kaynak kodunuzda tanımlanan işlevleri yeniden adlandırır. Fonksiyonlarınızı çağıran harici kodlar, derleme işleminden sonra bozulur. Çünkü eski işlev adını ifade eder. Benzer şekilde, harici olarak tanımlanmış simgelere derlenen kodlarla ilgili referanslar Closure Compiler tarafından değiştirilebilir.

"derlenmemiş kod"un eval() işlevine dize olarak aktarılan tüm kodları içerdiğini unutmayın. Closure Compiler, koddaki dize değişmez değerlerini hiçbir zaman değiştirmez. Bu yüzden, Kapalı Derleyici eval() ifadelerine aktarılan dizeleri değiştirmez.

Bu sorunların birbirine bağlı ancak farklı sorunlar olduğunu unutmayın: Dıştan derlenmiş iletişimi sürdürme ve dıştan derlenen iletişimi sürdürme. Bu farklı sorunların ortak bir çözümü vardır, ancak her iki tarafta da nüanslar vardır. Closure Compiler'dan en iyi şekilde yararlanmak için hangi destek kaydına sahip olduğunuzu anlamanız gerekir.

Devam etmeden önce depolama ve dışa aktarma hakkında bilgi edinin.

Derlenen Koddan Harici Koda Çağırma Çözümü: Harici Numaralarla Derleme

Sayfanıza başka bir komut dosyası tarafından sağlanan kodu kullanıyorsanız Closure Compiler'ın, referanslarınızı söz konusu harici kitaplıkta tanımlanan simgelere göre yeniden adlandırmadığından emin olmanız gerekir. Bunun için, harici kitaplığın dışlarını içeren bir dosyayı derlemenize ekleyin. Bu işlem, giyim destekçisine hangi adları kontrol etmediğinizi bildirir ve bu nedenle değiştirilemez. Kodunuz, harici dosyada kullanılan adları kullanmalıdır.

Bunun yaygın örnekleri, OpenSocial API'si ve Google Haritalar API'si gibi API'lerdir. Örneğin, kodunuz OpenSocial işlevini opensocial.newDataRequest() çağırıyorsa uygun uçlar olmadan Closure Compiler bu çağrıyı a.b() öğesine dönüştürür.

Harici Koddan Derlenen Koda Çağırma Çözümü: Harici Numaraları Uygulama

Kitaplık olarak yeniden kullandığınız JavaScript kodunuz varsa derlenmemiş kodun kitaplıktaki işlevleri çağırmasına izin vermeden yalnızca kitaplığı küçültmek için Closure Compiler'ı kullanmak isteyebilirsiniz.

Bu durumda çözüm, kitaplığınızdaki herkese açık API'yı tanımlayan bir dizi hariç tutma işlemi uygulamaktır. Kodunuz, bu seçimlerde belirtilen simgeler için tanımlar sağlar. Yani, ders dışı sınıflarınızdan bahsedilen tüm sınıf veya işlevler. Ayrıca, sınıflarınızın dışarıdan beyan edilen arayüzler uygulaması da gerekebilir.

Bu seçimler yalnızca kendiniz için değil, diğer kullanıcılar için de faydalıdır. Kitaplığınız kendi bakış açılarından harici bir komut dosyasını temsil ettiğinden, kitaplığınızın tüketicileri kodlarını derlerken bu kitapları da dahil etmelidir. Harici kişileri siz ve tüketicileriniz arasındaki sözleşme olarak düşünebilirsiniz, her ikinizin de bir kopyası olmalıdır.

Bu amaçla, kodunuzu derlerken derlemeleri de derlemeye dahil ettiğinizden emin olun. Harici kullanımları genellikle "başka bir yerden gelme" olarak kabul ettiğimizden bu durum olağan dışı görünebilir, ancak Dış Şekilde Derleme Tahtası'na hangi simgeleri açıkladığınızı söylemeniz gerekir, böylece bu simgeler yeniden adlandırılmaz.

Burada dikkat edilmesi gereken önemli bir nokta, harici simgeleri tanımlayan kodla ilgili "yinelenen tanım" teşhisini alabileceğinizdir. Kapanış Derleme Aracı dıştaki sembollerin dış kütüphaneler tarafından sağlandığını varsayar ve şu anda bilerek bir tanım sağladığınızı anlayamıyordur. Bu teşhisler engelleme açısından güvenlidir. Baskıyı API'nizi gerçekten karşıladığınızın bir onayı olarak düşünebilirsiniz.

Ayrıca, Kapanış Derleme Aracı tanımlarınızın harici tanımların türleriyle eşleşip eşleşmediğini kontrol edebilir. Böylece, tanımlarınızın doğru olduğunu onaylayabilirsiniz.