Web Performance Made Easy - Google I/O 2018 sürümü

Google IO 2018'de, web performansını iyileştirmeyi kolaylaştıran araçlar, kitaplıklar ve optimizasyon tekniklerinin bir özetini sunduk. Bu makalede, Oodles Tiyatrosu uygulamasını kullanarak bu senaryoları açıklıyoruz. Ayrıca tahmine dayalı yükleme ile ilgili deneysel çalışmalarımızdan ve yeni Guess.js girişiminden bahsediyoruz.

Addy Osmani
Addy Osmani
Ewa Gasperowicz

Geçtiğimiz yıl, web'i nasıl daha hızlı ve daha etkili hale getirebileceğimizi bulmaya çalıştık. Bu sayede, bu makalede sizinle paylaşmak istediğimiz yeni araçlara, yaklaşımlara ve kitaplıklara yer verdik. İlk bölümde, Oodles Theater uygulamasını geliştirirken pratikte kullandığımız bazı optimizasyon tekniklerini göstereceğiz. İkinci bölümde, tahmine dayalı yükleme denemelerimizden ve yeni Guess.js girişiminden bahsedeceğiz.

Performans ihtiyacı

İnternet her yıl daha ağır ve ağır hale geliyor. Web'in durumunu kontrol ettiğimizde, büyük kısmı JavaScript ve resimler olmak üzere, mobil ağırlıkta yaklaşık 1,5 MB boyutundaki bir ortanca sayfanın bulunduğunu görebiliriz.

Web sitelerinin boyutunun büyümesi ve ağ gecikmesi, CPU sınırlamaları, oluşturma engelleme kalıpları veya gereksiz üçüncü taraf kodları gibi diğer faktörlerle birlikte karmaşık performans bulmacasının ortaya çıkmasına katkıda bulunmaktadır.

Çoğu kullanıcı hızı, ihtiyaçlarının kullanıcı deneyimi hiyerarşisinin en üstünde yer alır. Bu çok da şaşırtıcı bir şey değil, çünkü bir sayfanın yüklenmesi bitene kadar gerçekten pek bir şey yapmanız mümkün değil. Sayfadan değer çıkaramaz, sayfanın estetiğine hayran kalmazsınız.

Kullanıcı deneyimi hiyerarşisi piramidi
Şekil 1. Kullanıcılar için hız ne kadar önemli? (Speed Matters, 3. Cilt)

Performansın kullanıcılar için önemli olduğunu biliyoruz ancak optimizasyona nereden başlanacağını keşfetmede sır gibi düşünülebilir. Neyse ki bu süreçte size yardımcı olabilecek araçlar var.

Lighthouse - performans iş akışı temeli

Lighthouse, web sitenizi denetlemenize olanak tanıyan ve web sitenizi nasıl daha iyi hale getirebileceğinize ilişkin ipuçları veren Chrome Geliştirici Araçları'nın bir parçasıdır.

Kısa süre önce, günlük geliştirme iş akışında gerçekten yararlı olan yeni performans denetimlerini kullanıma sunduk.

Yeni Lighthouse denetimleri
Şekil 2. Yeni Lighthouse denetimleri

Şimdi pratik bir örnek üzerinden bunlardan nasıl yararlanabileceğinizi inceleyelim: Oodles Theater uygulaması. Bu, küçük bir demo web uygulamasıdır. Burada en sevdiğimiz etkileşimli Google Doodle'larımızdan bazılarını deneyebilir, hatta bir iki oyun oynayabilirsiniz.

Uygulamayı geliştirirken mümkün olduğunca yüksek performans göstermesini istedik. Optimizasyonun başlangıç noktası bir Lighthouse raporuydu.

Oodles uygulaması için Lighthouse raporu
Şekil 3. Oodles uygulaması için Lighthouse raporu

Lighthouse raporunda görüldüğü gibi uygulamamızın ilk performansı oldukça kötüydü. 3G ağda, kullanıcının ilk anlamlı boyama veya uygulamanın etkileşimli hale gelmesi için 15 saniye beklemesi gerekiyordu. Lighthouse, sitemizle ilgili bir ton sorunu öne çıkardı ve 23 olan genel performans puanı tam olarak bunu yansıtıyordu.

Sayfa yaklaşık 3,4 MB ağırlığındaydı.Çok fazla yağ azaltmamız gerekiyordu.

Böylece ilk performans görevimizi başlattık: genel deneyimi etkilemeden kolayca kaldırabileceğimiz şeyler bulma.

Performans optimizasyonu fırsatları

Gereksiz kaynakları kaldırın

Güvenle kaldırılabilecek bazı bariz şeyler vardır: boşluklar ve yorumlar.

Sadeleştirmeden elde edilen kazançlar
Şekil 4. JavaScript ve CSS'yi küçültüp sıkıştırın

Lighthouse, bu fırsatı Daraltılmamış CSS ve JavaScript denetiminde öne çıkarır. Derleme işlemimiz için web paketi kullanıyorduk, dolayısıyla küçültmek için Uglify JS eklentisini kullandık.

Küçültme sık yapılan bir iştir. Bu nedenle, kullandığınız derleme süreci ne olursa olsun, kullanıma hazır bir çözüm bulabilirsiniz.

Bu alandaki faydalı bir başka denetim de Metin sıkıştırmayı etkinleştirme'dir. Sıkıştırılmamış dosyalar göndermek için bir neden yoktur ve bugünlerde CDN'lerin çoğu bunu desteklemektedir.

Kodumuzu barındırmak için Firebase Hosting kullanıyorduk. Firebase ise varsayılan olarak gzip işlemi etkinleştirir. Bu nedenle kodumuzu makul bir CDN'de barındırma özelliği sayesinde bunu ücretsiz olarak aldık.

Gzip oldukça popüler bir sıkıştırma yöntemi olsa da Zopfli ve Brotli gibi diğer mekanizmalar da ilgi görüyor. Brotli, çoğu tarayıcıda destekten yararlanır ve öğelerinizi sunucuya göndermeden önce ön sıkıştırmak için ikili program kullanabilirsiniz.

Verimli önbellek politikaları kullanın

Bir sonraki adımımız ise kaynakları gereksiz yere iki kez göndermediğimizden emin olmaktı.

Lighthouse'daki Verimsiz önbellek politikası denetimi, tam olarak bunu başarmak için önbelleğe alma stratejilerimizi optimize edebileceğimizi fark etmemize yardımcı oldu. Sunucumuzda bir max-age son kullanma tarihi başlığı ayarlayarak, kullanıcının tekrarlanan bir ziyarette daha önce indirdiği kaynakları yeniden kullanabilmesini sağladık.

İdeal olarak mümkün olduğunca fazla kaynağı mümkün olan en uzun süre boyunca güvenli bir şekilde önbelleğe almayı hedeflemeniz ve güncellenen kaynakların verimli bir şekilde yeniden doğrulanması için doğrulama jetonları sağlamanız gerekir.

Kullanılmayan kodları kaldırın

Şimdiye kadar gereksiz indirmenin belirgin kısımlarını kaldırdık, peki daha az bariz olan kısımlarına ne olacak? Örneğin, kullanılmayan kod.

Geliştirici Araçları'ndaki kod kapsamı
Şekil 5. Kod kapsamını kontrol edin

Bazen gerçekten gerekli olmayan uygulama kodunu ekleriz. Bu durum özellikle uygulamanız üzerinde daha uzun süre çalışıyorsanız, ekibiniz veya bağımlılıklarınız değişirse ve bazen artık bir kitaplık geride kalırsa ortaya çıkar. Bizim başına da tam olarak böyle olmuştur.

Başlangıçta, uygulamamızın hızlı prototipini oluşturmak için Materyal Bileşenleri kitaplığını kullanıyorduk. Zamanla daha özel bir görünüm ve tarza geçiş yaptık ve bu kitaplığı tamamen unuttuk. Neyse ki, kod kapsamı kontrolü, kodu paketimizde yeniden keşfetmemize yardımcı oldu.

Geliştirici Araçları'nda, hem çalışma zamanı hem de uygulamanızın yükleme süresi için kod kapsamı istatistiklerinizi kontrol edebilirsiniz. Alttaki ekran görüntüsünde iki büyük kırmızı şeridi görebilirsiniz. CSS'mizin %95'inden fazlası kullanılmıyordu ve çok fazla JavaScript de kullanıyorduk.

Lighthouse, bu sorunu kullanılmayan CSS kuralları denetiminde de tespit etti. 400 kb'ın üzerinde potansiyel tasarruf sağladığını gösterdi. Kodumuza geri döndük ve kitaplığın hem JavaScript hem de CSS bölümünü kaldırdık.

MVC adaptörünü bırakırsak stillerimiz 10 KB'a düşer
Şekil 6. MVC adaptörünü bırakırsak stillerimiz 10 KB'a düşer!

Böylece CSS paketimiz 20 kat azaldı. Bu da iki satırlık kısa bir kayıt için oldukça uygun.

Tabii ki bu sayede performans puanımız yükseldi ve Etkileşime Hazır Olma Süresi çok daha iyiye gitti.

Ancak bu tür değişiklikler söz konusu olduğunda, yalnızca metriklerinizi ve puanlarınızı kontrol etmeniz yeterli olmaz. Gerçek kodu kaldırmak hiçbir zaman riskli değildir. Bu nedenle, olası gerilemelere karşı her zaman dikkat etmelisiniz.

Kodumuz %95 oranında kullanılmamış ve hâlâ bir yerlerde% 5 bulunmaktadır. Görünüşe göre bileşenlerimizden biri hâlâ bu kitaplıktaki stilleri (doodle kaydırıcısındaki küçük okları) kullanıyordu. Ancak çok küçük olduğu için, gidip bu stilleri manuel olarak düğmelere geri ekleyebildik.

Eksik kitaplık nedeniyle düğmeler bozuktu
Şekil 7. Bileşenlerden biri, kaldırılan kitaplığı kullanmaya devam ediyor

Bu nedenle, kodu kaldırırsanız olası görsel gerilemelere karşı korumanıza yardımcı olacak uygun bir test iş akışınız olduğundan emin olmanız yeterlidir.

Çok büyük ağ yüklerinden kaçının

Büyük kaynakların web sayfası yüklemelerini yavaşlatabileceğinin farkındayız. Bu çözümler, kullanıcılarımıza maliyete yol açabiliyor ve veri planları üzerinde büyük etki yaratabiliyor. Bu yüzden bu konuda dikkatli olmak çok önemli.

Lighthouse, Devasa ağ yükü denetimini kullanarak bazı ağ yüklerimizle ilgili bir sorun yaşadığımızı tespit etti.

Çok büyük ağ yüklerini tespit edin
Şekil 8. Çok büyük ağ yüklerini algılayın

Burada, elimizde 3 MB'tan fazla kodun gönderildiğini gördük. Özellikle mobil cihazlar için bu değer oldukça büyük.

Bu listenin en üstünde, Lighthouse 2 MB sıkıştırılmamış kod içeren bir JavaScript tedarikçi paketimiz olduğunu vurguladı. Bu, webpack tarafından da vurgulanan bir sorundur.

Ne demişler? En hızlı istek, gerçekleşmemiş olandır.

İdeal olarak kullanıcılarınıza sunduğunuz her bir öğenin değerini ölçmeniz, bu öğelerin performansını ölçmeniz ve ilk deneyimde ürünün gerçekten indirilmeye değip değmeyeceğine karar vermeniz gerekir. Çünkü bu öğeler bazen ertelenebilir, geç yüklenebilir veya boştayken işlenebilir.

Örneğimizde, çok sayıda JavaScript paketiyle uğraştığımız için JavaScript topluluğunda zengin bir JavaScript paketi denetim aracı kümesi bulunduğundan şanslıydık.

JavaScript paketi denetimi
Şekil 9. JavaScript paketi denetimi

Webpack paket analiz aracı ile işe başladık. Bu analiz bize, 1,6 MB'lık ayrıştırılmış JavaScript'ten oluşan unicode adlı bir bağımlılığı ekledik. Bu, oldukça fazla.

Daha sonra düzenleyicimize gitti ve Görsel kod için Maliyet İçe Aktarma Eklentisi'ni kullanarak içe aktardığımız her modülün maliyetini görselleştirebildik. Böylece hangi bileşenin bu modüle referans veren kodu içerdiğini keşfedebildik.

Daha sonra, BundlePhobia adlı başka bir araca geçtik. Bu, herhangi bir AİOY paketinin adını girmenize ve küçültülmüş ve gzip'lenmiş boyutunun tahmini olarak ne olduğunu görmenize olanak tanıyan bir araçtır. Yalnızca 2, 2 kb ağırlığındaki slug modülü için güzel bir alternatif bulduk ve bunu değiştirdik.

Bunun performansımız üzerinde büyük etkisi oldu. Bu değişiklik ile JavaScript paketimizin boyutunu küçültmeye yönelik diğer fırsatları keşfetmeyle birlikte 2, 1 MB kod tasarrufu yaptık.

Bu paketlerin gzip veya küçültülmüş boyutunu hesaba kattığınızda genel olarak% 65 iyileşme gördük. Bunu da bir süreç olarak yapmaya değer olduğunu gördük.

Bu nedenle, genel olarak sitelerinizde ve uygulamalarınızda gereksiz indirmeleri kaldırmaya çalışın. Öğelerinizin envanterini oluşturup bunların performans üzerindeki etkisini ölçün çok büyük bir fark yaratabilir. Bu nedenle öğelerinizi düzenli olarak kontrol ettiğinizden emin olun.

Kod bölmeyle daha düşük JavaScript başlatma süresi

Büyük ağ yüklerinin uygulamamız üzerinde büyük bir etkisi olabilir, ancak gerçekten büyük etki yaratabilecek bir şey daha var, o da JavaScript.

JavaScript, en pahalı öğenizdir. Mobil cihazlarda büyük JavaScript grupları gönderiyorsanız kullanıcılarınızın kullanıcı arayüzü bileşenlerinizle ne kadar kısa sürede etkileşimde bulunacağı konusunda gecikme yaşanabilir. Yani kullanıcılar, kullanıcı arayüzünde anlamlı bir şey olmadan da dokunabiliyor. JavaScript'in neden bu kadar yüksek maliyetli olduğunu anlamak bizim için önemli.

Tarayıcı JavaScript'i bu şekilde işler.

JavaScript işleme
Şekil 10. JavaScript işleme

Her şeyden önce bu komut dosyasını indirmemiz gerekir. Ardından, bu kodu ayrıştırması ve derlemesi ve yürütmesi gereken bir JavaScript motorumuz vardır.

Şimdi bu aşamalar masaüstü veya dizüstü bilgisayar gibi ileri teknoloji cihazlarda, hatta ileri teknoloji telefonlarda çok fazla zaman almayan bir şey. Ancak ortalama bir cep telefonunda bu işlem 5 ila on kat daha uzun sürebilir. Etkileşimi geciktiren şey budur. Bu nedenle bu sınırı azaltmaya çalışmamız önemlidir.

Uygulamanızdaki bu sorunları keşfetmenize yardımcı olmak için Lighthouse'a yeni bir JavaScript başlatma süresi denetimi ekledik.

JavaScript önyükleme süresi
Şekil 11. JavaScript başlatma süresi denetimi

Oodle uygulaması örneğinde ise JavaScript'in açılması için 1, 8 saniye süremiz olduğunu belirtti. Tüm rotalarımızı ve bileşenlerimizi statik olarak tek bir monolitik JavaScript paketine aktarıyorduk.

Bu sorunu çözmek için kullanabileceğiniz tekniklerden biri, kod bölmedir.

Kod bölme işlemi pizza gibidir

Kod bölme yöntemi, kullanıcılarınıza tam bir pizza parçası kadar JavaScript değeri vermek yerine, ihtiyaç duyduğu sürece her seferinde sadece bir dilim verseniz nasıl olur?

Kod bölme işlemi, rota düzeyinde veya bileşen düzeyinde uygulanabilir. React ve React Loadable, Vue.js, Angular, Polymer, Preact ve diğer birçok kitaplıkla uyumlu şekilde çalışır.

Uygulamamıza kod bölmeyi dahil ettik. İhtiyaç duyduğumuzda kodu eşzamansız olarak geç yükleyebilmemize olanak tanımak için statik içe aktarma yerine dinamik içe aktarmaya geçiş yaptık.

Dinamik içe aktarmalarla kod bölme
Şekil 13. Dinamik içe aktarma işlemleriyle kod bölme

Bunun etkisi hem paketlerimizin boyutunu küçültüyordu hem de JavaScript önyükleme süremizi kısaltmamıza neden oluyordu. Süresi 0, 78 saniyeye inerek uygulamayı% 56 daha hızlı hale getirdi.

Genel olarak, JavaScript yoğun bir deneyim oluşturuyorsanız yalnızca kullanıcıya gereken kodu gönderdiğinizden emin olun.

Kod bölme gibi kavramları kullanın, ağaç sallama gibi fikirleri keşfedin ve web paketi kullanıyorsanız kitaplığınızın boyutunu nasıl küçültebileceğinizle ilgili birkaç fikir edinmek için webpack-libs-optimizations deposuna göz atın.

Resimleri optimize edin

Resim yükleme performansıyla ilgili şaka

Oodle uygulamasında çok fazla resim kullanıyoruz. Ne yazık ki Lighthouse, bu konuda bize göre çok daha az istekliydi. Aslına bakarsanız, resimlerle ilgili üç denetim de başarısızlıkla sonuçlandı.

Resimlerimizi optimize etmeyi unuttuk, doğru boyutlandırmıyorduk. Ayrıca, diğer resim biçimlerini kullanarak da bazı kazanç elde edebildik.

Görüntü denetimleri
Şekil 14. Lighthouse görüntü denetimleri

Resimlerimizi optimize etmeye başladık.

Tek seferlik optimizasyon turu için ImageOptim veya XNConvert gibi görsel araçları kullanabilirsiniz.

Daha otomatik bir yaklaşım, derleme işleminize imagemin gibi kitaplıklarla bir resim optimizasyonu adımı eklemektir.

Böylece gelecekte ekleyeceğiniz resimlerin otomatik olarak optimize edilmesini sağlayabilirsiniz. Akamai gibi bazı CDN'ler veya Cloudinary, Fastly veya Uploadcare gibi üçüncü taraf çözümler size kapsamlı resim optimizasyonu çözümleri sunar. Böylece görsellerinizi bu hizmetlerde de barındırabilirsiniz.

Maliyet veya gecikme sorunları nedeniyle bunu yapmak istemiyorsanız Thumbor veya Imageflow gibi projeler kendi kendine barındırılan alternatifler sunar.

Optimizasyondan önce ve sonra
Şekil 15. Optimizasyondan önce ve sonra

Arka plan PNG'miz, web paketinde büyük ve haklı olarak işaretlendi. Görüntü alanına uygun şekilde boyutlandırdıktan ve ImageOptim ile çalıştırdıktan sonra, 100 KB gibi bir boyuta indik.

Bu işlemi sitemizdeki birden fazla resim için tekrarlamak, toplam sayfa ağırlığını önemli ölçüde düşürmemizi sağladı.

Animasyonlu içerik için doğru biçimi kullanın

GIF'ler çok pahalı olabilir. Şaşırtıcı bir şekilde, GIF biçimi hiçbir zaman animasyon platformu olarak tasarlanmamıştır. Bu nedenle, daha uygun bir video biçimine geçmek, dosya boyutu açısından büyük tasarruflar sağlar.

Oodle uygulamasında ana sayfada giriş sekansı olarak GIF kullanıyorduk. Lighthouse'a göre, daha verimli bir video biçimine geçerek 7 MB'tan fazla tasarruf edebiliriz. Klibimiz yaklaşık 7,3 MB ağırlığı, makul bir web sitesi için çok fazla olduğundan, bunun yerine iki kaynak dosyası içeren bir video öğesine dönüştürdük: mp4 ve daha geniş tarayıcı desteği için WebM.

Animasyonlu GIF'leri videoyla değiştirme
Şekil 16. Animasyonlu GIF'leri video ile değiştirin

Animasyonlu GIF dosyasını mp4 dosyasına dönüştürmek için FFmpeg aracını kullandık. WebM biçimi daha da fazla tasarruf imkanı sunar. ImageOptim API sayesinde böyle bir dönüştürme işlemi gerçekleştirebilirsiniz.

ffmpeg -i animation.gif -b:v 0 -crf 40 -vf scale=600:-1 video.mp4

Bu dönüşüm sayesinde toplam ağırlığımızın% 80'inden fazla tasarruf etmeyi başardık. Bu da bizi yaklaşık 1 MB'a indirdi.

Yine de 1 MB, özellikle kısıtlı bir bant genişliğine sahip kullanıcılar için kabloyu aşağı iten büyük bir kaynaktır. Neyse ki Effective Type API'yi kullanarak bant genişliğinin yavaş olduğunu fark edip çok daha küçük bir JPEG sunabiliyoruz.

Bu arayüz, kullanıcının kullandığı ağ türünü tahmin etmek için etkili gidiş dönüş süresi ve indirme değerlerini kullanır. Bu işlev yalnızca yavaş 2G, 2G, 3G veya 4G şeklinde bir dize döndürür. Dolayısıyla, bu değere bağlı olarak, kullanıcı 4G'nin altında bir bağlantı kullanıyorsa video öğesini resimle değiştirebiliriz.

if (navigator.connection.effectiveType) { ... }

Bu site, deneyimden biraz uzaklaşıyor ama en azından site yavaş bir bağlantıda kullanılabiliyor.

Ekran dışı resimleri geç yükleme

Kullanıcılar bunları sayfada hemen göremeseler de bantlar, kaydırma çubukları veya çok uzun sayfalar genellikle resim yükler.

Lighthouse, bu davranışı ekran dışı görüntüler denetiminde işaretler. Bu davranışı Geliştirici Araçları'nın ağ panelinde de görebilirsiniz. Sayfada çok az resim varken gelen çok sayıda resim görüyorsanız bu durum, bunları geç yüklemeyi düşünebileceğiniz anlamına gelir.

Geç yükleme henüz tarayıcıda yerel olarak desteklenmediğinden bu özelliği eklemek için JavaScript kullanmamız gerekir. Oodle cover'larımıza geç yükleme davranışı eklemek için Lazysizes kitaplığını kullandık.

<!-- Import library -->
import lazysizes from 'lazysizes'  <!-- or -->
<script src="lazysizes.min.js"></script>

<!-- Use it -->

<img data-src="image.jpg" class="lazyload"/>
<img class="lazyload"
    data-sizes="auto"
    data-src="image2.jpg"
    data-srcset="image1.jpg 300w,
    image2.jpg 600w,
    image3.jpg 900w"/>

Geç boyutlar, yalnızca öğenin görünürlük değişikliklerini izlemekle kalmayıp aynı zamanda optimum kullanıcı deneyimi için görünüme yakın öğeleri proaktif olarak önceden getirdiğinden akıllıdır. Ayrıca, isteğe bağlı bir IntersectionObserver entegrasyonu da sunar. Böylece, görünürlüğü son derece verimli bir şekilde ölçebilirsiniz.

Bu değişikliğin ardından resimlerimiz isteğe bağlı olarak getirilmektedir. Bu konuyu daha ayrıntılı incelemek istiyorsanız çok kullanışlı ve kapsamlı bir kaynak olan images.guide'a göz atabilirsiniz.

Tarayıcının kritik kaynakları erkenden sunmasına yardımcı olun

Kablodan tarayıcıya gönderilen her bayt aynı derecede öneme sahip değildir ve tarayıcı bunu bilir. Birçok tarayıcı, ilk önce ne getirmesi gerektiğine karar vermek için buluşsal yöntemlere sahiptir. Bu nedenle bazen resimlerden veya komut dosyalarından önce CSS getirir.

Bize, sayfanın yazarları olarak bizim için gerçekten önemli olan şeyleri tarayıcıya bildirmemiz yararlı olabilir. Neyse ki son birkaç yıldır tarayıcı tedarikçileri bu konuda bize yardımcı olacak link rel=preconnect, preload veya prefetch gibi kaynak ipuçları gibi çeşitli özellikler ekliyor.

Web platformuna getirilen bu özellikler, tarayıcının doğru şeyi doğru zamanda getirmesine yardımcı olur ve komut dosyası yerine komut dosyası kullanılarak yapılan bazı özel yükleme, mantık tabanlı yaklaşımlardan biraz daha verimli olabilir.

Lighthouse'un bu özelliklerden bazılarını etkili bir şekilde kullanma konusunda bize nasıl rehberlik ettiğini görelim.

Lighthouse'un bize söylemesi gereken ilk şey, herhangi bir başlangıç noktasına çok sayıda maliyetli gidiş-dönüşten kaçınmak.

Varış noktalarına birden fazla ve maliyetli gidiş gelişten kaçının
Şekil 17. Herhangi bir kalkış noktasına birden fazla ve maliyetli gidiş dönüş yapmaktan kaçının

Oodle uygulaması söz konusu olduğunda, aslında Google Fonts'u yoğun bir şekilde kullanıyoruz. Sayfanıza bir Google Yazı Tipi stil sayfası bıraktığınızda, en fazla iki alt alan bağlanır. Lighthouse, bu bağlantıyı ısıtabilirsek ilk bağlantı süremizde 300 milisaniyeye kadar tasarruf edebileceğimizi söylüyor.

Bağlantı yeniden bağlama özelliğinden yararlanarak bu bağlantı gecikmesini etkili bir şekilde maskeleyebiliriz.

Özellikle yazı tipi yüzümüzün CSS'sinin googleapis.com'da, yazı tipi kaynaklarımızın ise Gstatic'de barındırıldığı Google Fonts gibi bir şeyde bu durum çok büyük bir etki yaratabilir. Dolayısıyla, bu optimizasyonu uyguladık ve birkaç yüz milisaniye kısalttık.

Lighthouse'un önerisi, önemli isteklerin önceden yüklenmesidir.

Önemli istekleri önceden yükleyin
Şekil 18. Önemli istekleri önceden yükleyin

<link rel=preload> gerçekten güçlü bir araçtır. Tarayıcıya, mevcut gezinmenin parçası olarak bir kaynağın gerekli olduğunu bildirir ve tarayıcının bu kaynağı en kısa sürede getirmesini sağlamaya çalışır.

Şimdi Lighthouse, iki web yazı tipi yüklediğimiz için gidip önemli web yazı tipi kaynaklarımızı önceden yüklememiz gerektiğini söylüyor.

Bir web yazı tipinde önceden yükleme şu şekilde görünür: rel=preload belirtildiğinde, yazı tipi türünü as ile geçirirsiniz ve ardından yüklemeye çalıştığınız yazı tipinin türünü (ör. woff2) belirtirsiniz.

Bunun sayfanız üzerinde çok büyük bir etkisi olabilir.

Kaynakları önceden yüklemenin etkisi
Şekil 19. Kaynakları önceden yüklemenin etkisi

Normalde, bağlantı rel önyüklemesini kullanmadan, web yazı tipleri sayfanız için kritik öneme sahipse tarayıcının yapması gereken, öncelikle HTML'nizi getirmesi, CSS'nizi ayrıştırması ve çok daha ileri bir noktaya giderek en sonunda web yazı tiplerinizi getirmektir.

Bağlantı rel önyüklemesini kullanarak, tarayıcı HTML'nizi ayrıştırır almaz bu web yazı tiplerini almaya çok daha erken başlayabilir. Uygulamamız durumunda bu, web yazı tiplerimizi kullanarak metin oluşturmamız için harcadığımız zamandan bir saniye tasarruf etmemizi sağladı.

Google Fonts'u kullanarak yazı tiplerini önceden yüklemeyi denerseniz işte bu kadar kolay değildir.

Stil sayfalarımızdaki yazı tipi yüzlerinde belirttiğimiz Google Yazı Tipi URL'leri, yazı tipleri ekibinin oldukça düzenli olarak güncellediği bir şeydi. Bu URL'lerin süresi dolabilir veya düzenli aralıklarla güncellenebilir. Bu nedenle, yazı tipi yükleme deneyiminiz üzerinde tam kontrol sahibi olmak istiyorsanız web yazı tiplerinizi kendi kendinize barındırmanız önerilir. Bu, bağlantıları rel'in önceden yüklenmesi gibi öğelere erişmenizi sağladığı için harika olabilir.

Örneğimizde, Google Web Yazı Tipleri Yardımcısı'nın bu web yazı tiplerinden bazılarını çevrimdışı yapmamıza ve yerel olarak oluşturmamıza yardımcı olması açısından çok kullanışlı olduğunu gördük. Bu aracı kontrol edin.

Kritik kaynaklarınızın bir parçası olarak web yazı tiplerini veya JavaScript'i kullanıyor olabilirsiniz. Her durumda, tarayıcının kritik kaynaklarınızı en kısa sürede sağlamasına yardımcı olmaya çalışın.

Deneysel: Öncelikli İpuçları

Bugün sizinle paylaşmak istediğimiz özel bir şey var. Kaynak ipuçları ve önceden yükleme gibi özelliklere ek olarak, öncelikli ipuçları adını verdiğimiz yepyeni bir deneysel tarayıcı özelliği üzerinde çalışıyoruz.

Başlangıçta görünür olan içeriğin önceliğini ayarlayın
Şekil 20. Öncelik ipuçları

Bu, tarayıcıya bir kaynağın ne kadar önemli olduğunu gösteren yeni bir özelliktir. Düşük, yüksek veya otomatik değerlerine sahip yeni bir özelliği (önem) gösterir.

Böylece, anlaşmazlığı azaltmak için kritik olmayan stiller ve görüntüler gibi daha az önemli kaynakların veya getirme API çağrılarının öncelik düzeyini düşürüyoruz. Kahraman resimlerimiz gibi daha önemli öğelerin önceliğini de artırabiliriz.

Oodle uygulamamızda bu durum, optimizasyon uygulayabileceğimiz pratik bir yer sağladı.

Başlangıçta görünür olan içeriğin önceliğini ayarlayın
Şekil 21. Başlangıçta görünen içeriğin önceliğini ayarlayın

Resimlerimize geç yükleme özelliğini eklemeden önce, tüm doodle'larımızı içeren bir resim atlı karıncası aldık ve tarayıcı tüm resimleri daha başta yüksek öncelikli olarak bantın en başında alıyordu. Ne yazık ki kullanıcı için en önemli olanlar bandın ortasındaki resimlerdi. Dolayısıyla, bu arka plan resimlerinin önemini çok düşük, ön plan resimlerinin önemini çok yüksek ve bunun yavaş 3G üzerinde iki saniyelik bir etkisi olduğunu ve bu resimleri ne kadar hızlı getirip oluşturabildiğimizi belirledik. Olumlu bir deneyim oldu.

Bu özelliği birkaç hafta içinde Canary'de de kullanıma sunmayı umuyoruz, lütfen sık sık kontrol edin.

Web yazı tipi yükleme stratejisine sahip olun

Tipografi, iyi bir tasarımın temelini oluşturur. Web yazı tipleri kullanıyorsanız ideal olarak metninizin oluşturulmasını engellemek istemezsiniz ve görünmez metin göstermek de kesinlikle istemezsiniz.

Web yazı tipleri yüklenirken görünmez metin olmaması denetimi ile bunu şimdi Lighthouse'da vurguluyoruz.

Web Yazı Tipleri yüklenirken görünmez metinden kaçının
Şekil 22. Web yazı tipleri yüklenirken görünmez metin kullanma

Web yazı tiplerinizi bir yazı tipi yüz bloğu kullanarak yüklerseniz, söz konusu web yazı tipinin getirilmesi uzun sürerse tarayıcının ne yapacağına karar vermesine izin vermiş olursunuz. Bazı tarayıcılar bir sistem yazı tipine geri dönmeden önce bunun için üç saniyeye kadar bekler ve sonunda bunu indirdikten sonra yazı tipine değiştirirler.

Bu görünmez metinden kaçınmaya çalışıyoruz. Dolayısıyla bu örnekte, web yazı tipi çok uzun sürseydi bu haftanın klasik doodle'larını göremeyecektik. Neyse ki font-display adlı yeni özellik sayesinde bu süreç üzerinde çok daha fazla kontrole sahip olursunuz.

    @font-face {
      font-family: 'Montserrat';
      font-style: normal;
      font-display: swap;
      font-weight: 400;
      src: local('Montserrat Regular'), local('Montserrat-Regular'),
          /* Chrome 26+, Opera 23+, Firefox 39+ */
          url('montserrat-v12-latin-regular.woff2') format('woff2'),
            /* Chrome 6+, Firefox 3.6+, IE 9+, Safari 5.1+ */
          url('montserrat-v12-latin-regular.woff') format('woff');
    }

Yazı tipi görüntüleme, web yazı tiplerinin nasıl oluşturulacağına veya değiştirileceği süreye bağlı olarak nasıl yedekleneceğine karar vermenize yardımcı olur.

Bu örnekte, yazı tipi görüntüleme değişimini kullanıyoruz. Değiştirme işlemi, yazı tipi yüzüne sıfır saniyelik bir blok süresi ve sonsuz bir değiştirme süresi verir. Bu, yazı tipinin yüklenmesi zaman alıyorsa tarayıcının metninizi yedek yazı tipiyle hemen çizeceği anlamına gelir. Yazı tipi kullanılabilir olduğunda resmi de değiştiriyor.

Uygulamamız söz konusu olduğunda, bunun mükemmel olmasının nedeni, çok erken anlamlı metinleri göstermemize ve hazır olduğunda web yazı tipine geçmemize olanak vermesi.

Yazı tipi görüntüleme sonucu
Şekil 23. Yazı tipi görüntüleme sonucu

Genel olarak, web yazı tiplerini kullanıyorsanız, web'in büyük bir yüzdesinde olduğu gibi, iyi bir web yazı tipi yükleme stratejisi vardır.

Yazı tipleri için yükleme deneyiminizi optimize etmek amacıyla kullanabileceğiniz pek çok web platformu özelliği vardır. Aynı zamanda Zach Leatherman'ın Web Font Recipes deposuna da göz atabilirsiniz. Çünkü bu havuz oldukça faydalıdır.

Oluşturmayı engelleyen komut dosyalarını azaltın

Uygulamamızın, en azından biraz daha erken bir temel kullanıcı deneyimini sağlamak için indirme zincirinde daha erken kullanıma sunabileceğimiz başka bölümleri de var.

Lighthouse zaman çizelgesi şeridinde, tüm kaynaklar yüklenirken kullanıcının bu ilk birkaç saniyede gerçekten hiçbir içerik göremediğini görebilirsiniz.

Oluşturmayı engelleyen stil sayfaları fırsatını azaltma
Şekil 24. Oluşturmayı engelleyen stil sayfaları fırsatını azaltın

Harici stil sayfalarını indirmek ve işlemek, oluşturma sürecimizin herhangi bir ilerleme kaydetmesini engellemektedir.

Stillerden bazılarını biraz daha erken sunarak kritik oluşturma yolumuzu optimize etmeyi deneyebiliriz.

Bu ilk oluşturma işleminden sorumlu stilleri alır ve bunları HTML'mizde satır içi yaparsak, tarayıcı bunları harici stil sayfalarının gelmesini beklemeden doğrudan oluşturabilir.

Örneğimizde, bir derleme adımı sırasında kritik içeriğimizi index.html'de satır içi yapmak için Kritik adlı bir AİOY modülü kullandık.

Bizim için zorlu işlerin çoğunu bu modül üstlenmiş olsa da, bunun farklı rotalarda sorunsuz çalışmasını sağlamak hâlâ biraz zordu.

Dikkatli olmazsanız veya sitenizin yapısı çok karmaşıksa en başından uygulama kabuğu mimarisi için planlamadıysanız bu tür bir kalıp kullanmak çok zor olabilir.

Bu nedenle, performansla ilgili hususları erkenden değerlendirmek önemlidir. En baştan performans odaklı tasarım yapmazsanız daha sonra bunu yaparken sorunlarla karşılaşma olasılığınız yüksektir.

Nihayetinde riskin karşılığını aldık. Uygulama sayesinde içerik çok daha erkenden yayınlanmaya başlandı ve ilk anlamlı boyama süremiz önemli ölçüde iyileşti.

Sonuç

Bu, sitemize uyguladığımız performans optimizasyonlarından oluşan uzun bir listeydi. Sonuca bir göz atalım. Uygulamamız, optimizasyondan önce ve sonra, 3G ağ üzerindeki orta ölçekli bir mobil cihazda bu şekilde yüklendi.

Lighthouse performans puanı 23'ten 91'e yükseldi. Hız açısından oldukça iyi bir ilerleme. Tüm değişiklikler, Lighthouse raporunu sürekli kontrol edip takip etmemiz sayesinde oldu. Tüm iyileştirmeleri teknik olarak nasıl uyguladığımıza göz atmak isterseniz depomuza, özellikle de oraya ulaşan PR'lere göz atabilirsiniz.

Tahmini performans - veriye dayalı kullanıcı deneyimleri

Makine öğreniminin, birçok alanda gelecek için heyecan verici bir fırsat olduğuna inanıyoruz. Gelecekte daha fazla deneme yapılmasını tetikleyeceğini düşündüğümüz fikirlerden biri, gerçek verilerin oluşturduğumuz kullanıcı deneyimlerinde gerçekten yol gösterebileceğidir.

Günümüzde, kullanıcının ne isteyebileceği veya neye ihtiyaç duyabileceği ve dolayısıyla nelerin önceden getirilmeye, önceden yüklenmeye veya önbelleğe alınmaya değer olacağına dair rastgele birçok karar alıyoruz. Doğru olduğunu tahmin edersek az sayıda kaynağa öncelik verebiliriz, ancak bunu web sitesinin tamamına yaymak gerçekten zordur.

Aslında günümüzde optimizasyonlarımızı daha iyi hale getirecek verilere sahibiz. Google Analytics Reporting API'yi kullanarak sitemizdeki URL'ler için sonraki üst sayfaya ve çıkış yüzdelerine göz atabilir ve bu sayede hangi kaynaklara öncelik vermemiz gerektiğine dair sonuçlara ulaşabiliriz.

Bunu iyi bir olasılık modeliyle birleştirirsek içeriği agresif bir şekilde aşırı önceden getirerek kullanıcımızın verilerini boşa harcamaktan kaçınırız. Bu tür modelleri uygulamak için Google Analytics verilerinden ve makine öğrenimini ve Markov zincirleri veya nöral ağ gibi modelleri kullanabiliriz.

Web Uygulamaları için Veriye Dayalı Paketleme
Şekil 25. Web Uygulamaları için Veriye Dayalı Paketleştirme

Bu denemeleri kolaylaştırmak için, Guess.js adını verdiğimiz yeni bir girişimi duyurmaktan mutluluk duyuyoruz.

Guess.js
Şekil 26. Guess.js

Guess.js, web için veriye dayalı kullanıcı deneyimlerine odaklanan bir projedir. Bu yeniliğin, web performansını artırmak ve bunun da ötesine geçmek için verileri kullanma konusundaki keşiflere ilham vereceğini umuyoruz. Bugün bunların hepsi açık kaynaklı ve GitHub'da kullanıma hazır. Bu geliştirme; Minko Gechev, Gatsby'den Kyle Matthews, Katie Hempenius ve daha pek çok kişinin açık kaynak topluluğunun iş birliğiyle oluşturuldu.

Guess.js'yi inceleyin ve görüşlerinizi bizimle paylaşın.

Özet

Puanlar ve metrikler Web'in hızını artırmaya yardımcı olur, ancak bunlar hedeflerin kendisi değil, yalnızca araçlardır.

Hareket halindeyken hepimiz yavaş sayfa yüklemeleri yaşadık, ancak artık kullanıcılarımıza gerçekten hızlı yüklenen daha keyifli deneyimler sunma fırsatına sahibiz.

Performansı iyileştirmek bir yolculuktur. Çok sayıda küçük değişiklik büyük kazanımlar getirebilir. Doğru optimizasyon araçlarını kullanarak ve Lighthouse raporlarını takip ederek kullanıcılarınıza daha iyi ve daha kapsayıcı bir deneyim sunabilirsiniz.

Özel teşekkürler: Ward Peeters, Minko Gechev, Kyle Mathews, Katie Hempenius, Dom Farolino, Yoav Weiss, Susie Lu, Yusuke Utsunomiya, Tom Ankers, Deniz Feneri ve Google Doodle'ları.