Uygulama Kabuğu Mimarisi ile Web Uygulamalarını Anında Yükleme

Addy Osmani
Addy Osmani
Matt Gaunt

Uygulama kabuğu, kullanıcı arayüzünü çalıştıran basit HTML, CSS ve JavaScript kodlarıdır. Uygulama kabuğu şu özelliklere sahip olmalıdır:

  • hızlı yüklenir
  • önbelleğe alınmalıdır
  • İçeriği dinamik olarak görüntüleme

Güvenilir ve iyi bir performansın sırrı, uygulama kabuğudur. Uygulamanızın kabuğunu, yerel bir uygulama geliştirirken uygulama mağazasında yayınlayacağınız bir kod paketi gibi düşünün. Başlangıç için gereken yük bu kadar olabilir, ancak tüm hikaye anlatmayabilir. Kullanıcı arayüzünüzü yerel tutar ve içeriği bir API aracılığıyla dinamik olarak çeker.

Uygulama Kabuğunda HTML, JS ve CSS kabuğu ile HTML İçeriğinin Ayrımı

Arka plan

Alex Russell'ın Progresif Web Uygulamaları makalesinde çevrimdışı destek, push bildirimleri ve ana ekrana eklenme özelliği ile eksiksiz, daha yerel uygulamalara benzer bir deneyim sunmak için bir web uygulamasının kullanım ve kullanıcı izni üzerinden nasıl kademeli şekilde değişebileceği açıklanıyor. Bu, büyük ölçüde Service Worker'ın işlevselliği ile performans avantajları ve önbelleğe alma özelliklerine bağlıdır. Bu, hıza odaklanmanızı ve web uygulamalarınızda yerel uygulamalarda görmeye alışık olduğunuz anlık yükleme olanağını ve düzenli güncellemeleri almanızı sağlar.

Bu özelliklerden tam olarak yararlanmak için web siteleri konusunda yeni bir düşünme şekline ihtiyacımız var: uygulama kabuğu mimarisi.

Şimdi Service Worker artırılmış uygulama kabuğu mimarisi kullanarak uygulamanızı nasıl yapılandıracağınızı ayrıntılı olarak inceleyelim. Hem istemci hem de sunucu tarafı oluşturmayı inceleyeceğiz ve hemen deneyebileceğiniz bir uçtan uca örneği paylaşacağız.

Bu noktayı vurgulamak için aşağıdaki örnekte bu mimariyi kullanan bir uygulamanın ilk yüklemesi gösterilmektedir. Ekranın alt kısmındaki "Uygulama çevrimdışı kullanıma hazır" durum mesajına dikkat edin. Daha sonra kabuk için bir güncelleme kullanıma sunulursa kullanıcıyı yeni sürüm için yenilemesi konusunda bilgilendirebiliriz.

Uygulama kabuğu için Geliştirici Araçları'nda çalışan hizmet çalışanının resmi

Service Worker'lar nedir?

Service Worker, web sayfanızdan ayrı olarak arka planda çalışan bir komut dosyasıdır. Sunduğu sayfalardan yapılan ağ istekleri ve sunucunuzdan bildirimleri aktarma dahil olmak üzere etkinliklere yanıt verir. Bir hizmet çalışanının ömrü kasıtlı olarak kısadır. Bir etkinlik aldığında uyanır ve yalnızca işlemesi gerektiği sürece çalışır.

Normal tarama bağlamındaki JavaScript'e kıyasla Service Worker'lar, sınırlı sayıda API'ye sahiptir. Bu, web'de çalışanlar için standarttır. Hizmet çalışanı DOM'ye erişemez ancak Cache API gibi öğelere erişebilir ve Fetch API'yi kullanarak ağ isteğinde bulunabilir. IndexedDB API ve postMessage(), veri kalıcılığı ve hizmet çalışanı ile kontrol ettiği sayfalar arasında mesajlaşma için de kullanılabilir. Sunucunuzdan gönderilen aktarma etkinlikleri, kullanıcı etkileşimini artırmak için Bildirim API'sini çağırabilir.

Service Worker, bir sayfadan yapılan ağ isteklerine müdahale edebilir (ve bu işlem, hizmet çalışanı için bir getirme etkinliğini tetikler) ağdan alınan, yerel önbellekten alınan veya programla oluşturulan bir yanıt döndürebilir. Bu da tarayıcıda programlanabilir bir proxy’dir. İşin düzgün tarafı, yanıtın nereden geldiğine bakılmaksızın, web sayfasına hiç hizmet çalışanı dahil olmamış gibi görünmesidir.

Service Worker'lar hakkında ayrıntılı bilgi için Hizmet Çalışanlarına Giriş başlıklı makaleyi okuyun.

Performans avantajları

Service Worker'lar çevrimdışı önbelleğe alma için güçlüdür ancak aynı zamanda sitenizin veya web uygulamanızın tekrar ziyaret edilmesi için anında yükleme biçiminde önemli performans kazanımları da sunar. Uygulama kabuğunu önbelleğe alarak çevrimdışı çalışmasını sağlayabilir ve içeriğini JavaScript kullanarak doldurabilirsiniz.

Yinelenen ziyaretlerde bu, içeriğiniz sonuçta oradan gelse bile ağ olmadan ekranda anlamlı pikseller elde etmenize olanak tanır. Bu yöntemi, araç çubuklarını ve kartları anında gösterip geri kalanını kademeli şekilde yüklemek gibi düşünebilirsiniz.

Bu mimariyi gerçek cihazlarda test etmek için WebPageTest.org adresinde uygulama kabuğu örneğimizi çalıştırdık ve sonuçları aşağıda görebilirsiniz.

1. Test: Chrome Dev'i kullanarak Nexus 5 ile Kablo üzerinden test etme

Uygulamanın ilk görünümü ağdan tüm kaynakları getirmelidir ve 1,2 saniye içinde anlamlı bir boyama sağlamaz. Servis çalışanı önbelleğe alma özelliği sayesinde yinelenen ziyaretimiz anlamlı bir boyama elde eder ve yükleme işlemini 0, 5 saniye içinde tamamen bitirir.

Kablo Bağlantısı için Web Sayfası Test Boyama Diyagramı

2. Test: Chrome Dev'i kullanarak Nexus 5 ile 3G'de test etme

Örneğimizi biraz daha yavaş bir 3G bağlantısıyla da test edebiliriz. Bu kez ilk anlamlı boyamamız için ilk ziyarette 2,5 saniye sürüyor. Sayfanın tamamen yüklenmesi 7,1 saniye sürer. Hizmet çalışanı önbelleğe alma sayesinde yinelenen ziyaretimiz anlamlı bir boyama gerçekleştirir ve yüklemeyi 0, 8 saniyede tamamen bitirir.

3G Bağlantı için Web Sayfası Testi Boya Diyagramı

Diğer görüntülemeler benzer bir hikaye anlatır. Uygulama kabuğunda ilk anlamlı boyamayı gerçekleştirmek için gereken 3 saniyeyi karşılaştırın:

Web Page Test'ten ilk görünüm için boyama zaman çizelgesi

aynı sayfa hizmet çalışanı önbelleğimizden yüklendiğinde geçen 0,9 saniye kadar. Son kullanıcılarımız için 2 saniyeden fazla zaman kazanılıyor.

Web Sayfası Testi'nden yinelenen görüntüleme için boyama zaman çizelgesi

Uygulama kabuğu mimarisi kullanan kendi uygulamalarınız için de benzer ve güvenilir performans kazanımları elde edilebilir.

Service Worker için uygulamaları yapılandırma şeklimizi yeniden ele almamız gerekir mi?

Service Worker'lar, uygulama mimarisinde bazı ince değişiklikler yapar. Uygulamanızın tamamını bir HTML dizesine sığdırmak yerine AJAX stili işlem yapmak daha yararlı olabilir. Burada, her zaman önbelleğe alınan ve ağ olmadan da başlatılabilen bir kabuğa ve düzenli olarak yenilenip ayrı olarak yönetilen içeriğe sahip olursunuz.

Bu bölünmenin etkisi büyüktür. İlk ziyaretinizde sunucuda içerik oluşturabilir ve Service Worker'ı istemciye yükleyebilirsiniz. Sonraki ziyaretlerde yalnızca veri istemeniz gerekir.

Kademeli geliştirme ne olacak?

Service Worker şu anda tüm tarayıcılar tarafından desteklenmese de uygulama içeriği kabuğu mimarisi, herkesin içeriğe erişebilmesi için progresif geliştirme kullanır. Örnek projemizi ele alalım.

Aşağıda Chrome, Firefox Gecelik ve Safari'de oluşturulan tam sürümü görebilirsiniz. En solda, içeriğin bir hizmet çalışanı olmadan sunucuda oluşturulduğu Safari sürümünü görebilirsiniz. Sağ tarafta, Service Worker tarafından desteklenen Chrome ve Firefox Gecelik sürümlerini görüyoruz.

Safari, Chrome ve Firefox'ta yüklenen Uygulama Kabuğu'nun resmi

Bu mimariyi kullanmak ne zaman mantıklıdır?

Uygulama kabuğu mimarisi, dinamik uygulamalar ve siteler için en mantıklı seçenektir. Siteniz küçük ve statikse muhtemelen uygulama kabuğuna ihtiyacınız yoktur ve bir Service Worker oninstall adımında sitenin tamamını önbelleğe alabilirsiniz. Projeniz için en mantıklı yaklaşımı kullanın. Halihazırda uygulama mantığını içerikten ayırmayı teşvik eden birkaç JavaScript çerçevesi, bu kalıbı daha kolay bir şekilde uygulayabilmenizi sağlar.

Henüz bu kalıbı kullanan herhangi bir üretim uygulaması var mı?

Genel uygulamanızın kullanıcı arayüzünde yalnızca birkaç değişiklik yaparak uygulama kabuğu mimarisini oluşturmak mümkündür. Bu mimari, Google'ın I/O 2015 Progresif Web Uygulaması ve Google'ın Gelen Kutusu gibi büyük ölçekli sitelerde iyi sonuç vermiştir.

Google Gelen Kutusu yükleniyor resmi. Service Worker kullanarak Gelen Kutusu'nu gösterir.

Performans açısından önemli bir başarı sağlayan çevrimdışı uygulama kabukları, Jake Archibald'ın çevrimdışı Wikipedia uygulaması ve Flipkart Lite'ın progresif web uygulamasında da iyi gösterilmiştir.

Jake Archibald'ın Wikipedia Demosu'nun ekran görüntüleri.

Mimariyi açıklama

İlk yükleme deneyimi sırasında hedefiniz, kullanıcının ekranına mümkün olan en kısa sürede anlamlı içerik getirmektir.

İlk yükleme ve diğer sayfaları yükleme

Uygulama Kabuğu ile İlk Yükleme Şeması

Uygulama kabuğu mimarisi genel olarak şunları sağlar:

  • İlk yüke öncelik verin ancak hizmet çalışanının uygulama kabuğunu önbelleğe almasına izin verin. Böylece tekrarlanan ziyaretler kabuğun ağdan yeniden alınmasını gerektirmez.

  • Diğer her şeyi geç yükleme veya arka planda yükleme. İyi bir seçenek, dinamik içerik için okuma önbelleğe alma işlevini kullanmaktır.

  • Örneğin, statik içeriğinizi yöneten Service Worker'ı güvenilir bir şekilde önbelleğe almak ve güncellemek için sw-precache gibi hizmet çalışanı araçları kullanın. (Daha sonra sw-precache hakkında daha fazla bilgi edinebilirsiniz.)

Bunu başarmak için:

  • Sunucu, istemcinin oluşturabileceği HTML içeriği gönderir ve hizmet çalışanı desteği olmayan tarayıcıları hesaba katmak için uzak gelecekte HTTP önbellek geçerlilik sonu üst bilgilerini kullanır. Uygulama yaşam döngüsünün ilerleyen aşamalarında hem "sürüm oluşturma"yı hem de kolay güncellemeleri etkinleştirmek için karmaları kullanarak dosya adları sunar.

  • Sayfalar, uygulama kabuğunun hızlı bir ilk boyamasını sağlamak için <head> dokümanındaki <style> etiketinde satır içi CSS stillerini içerir. Her sayfa, mevcut görünüm için gerekli olan JavaScript'i eşzamansız olarak yükler. CSS eşzamansız olarak yüklenemeyeceğinden, ayrıştırıcı odaklı ve eşzamanlı yerine eşzamansız olduğu için JavaScript'i kullanarak stiller isteyebiliriz. Hızlı önbellek isabeti alıp stillerin yanlışlıkla kritik oluşturma yoluna dahil edilmesine neden olabilecek durumlardan kaçınmak için requestAnimationFrame()'ten yararlanabiliriz. requestAnimationFrame(), stiller yüklenmeden önce ilk kareyi boyanmaya zorlar. Diğer bir seçenek de Filament Group'un loadCSS gibi projeleri, JavaScript kullanarak eşzamansız olarak CSS istemek için kullanmaktır.

  • Service Worker, uygulama kabuğunun önbelleğe alınmış bir girişini saklar. Böylece, ağda bir güncelleme bulunmadığı sürece, sonraki ziyaretlerde kabuk tamamen Service Worker önbelleğinden yüklenebilir.

İçerik için Uygulama Kabuğu

Pratik bir uygulama

Uygulama kabuğu mimarisi, istemci için vanilla ES2015 JavaScript ve sunucu için Express.js kullanarak tam olarak çalışan bir örnek hazırladık. Elbette, istemci veya sunucu bölümleri (ör.PHP, Ruby, Python) için kendi yığınınızı kullanmanızı engelleyen hiçbir şey yoktur.

Hizmet çalışanının yaşam döngüsü

Uygulama kabuğu projemiz için aşağıdaki hizmet çalışanı yaşam döngüsünü sunan sw-precache kullanırız:

Etkinlik İşlem
Yükle Uygulama kabuğunu ve diğer tek sayfalık uygulama kaynaklarını önbelleğe alın.
Etkinleştir Eski önbellekleri temizleyin.
Getirme URL'ler için tek sayfalık web uygulaması sunun ve öğeler ile önceden tanımlanmış kısmi öğeler için önbelleği kullanın. Diğer istekler için ağı kullanın.

Sunucu bitleri

Bu mimaride, bir sunucu tarafı bileşeni (bizim örneğimizde Express'te yazılmıştır), içeriği ve sunuyu ayrı olarak işleyebilmelidir. İçerik, sayfanın statik bir şekilde oluşturulmasıyla sonuçlanan bir HTML düzenine eklenebilir veya ayrı olarak sunulup dinamik olarak yüklenebilir.

Sunucu tarafı kurulumunuzun demo uygulamamız için kullandığımızdan önemli ölçüde farklı olabileceği doğaldır. Çoğu sunucu kurulumunda bu web uygulaması modeline ulaşılabilir, ancak bazı yeniden mimari yapılması gerekir. Aşağıdaki modelin oldukça iyi çalıştığını tespit ettik:

Uygulama Kabuğu Mimarisi Şeması
  • Uç noktalar, uygulamanızın üç bölümü için tanımlanır: Kullanıcıya yönelik URL'ler (dizin/joker karakter), uygulama kabuğu (hizmet çalışanı) ve HTML kısmileriniz.

  • Her uç noktanın, gidonun parçalarını ve görünümlerini çekebilen gidiş çubuğu düzenini çeken bir denetleyici vardır. Basitçe açıklamak gerekirse kısmiler, son sayfaya kopyalanan HTML parçaları olan görünümlerdir. Not: Daha gelişmiş veri senkronizasyonu yapan JavaScript çerçevelerinin bir Uygulama Kabuğu mimarisine taşınması genellikle çok daha kolaydır. Kısmi düzenlemeler yerine veri bağlama ve senkronizasyon özelliklerini kullanma eğilimindedirler.

  • İlk olarak kullanıcıya içerik barındıran statik bir sayfa sunulur. Bu sayfa, destekleniyorsa uygulama kabuğunu ve bağlı olduğu her şeyi (CSS, JS vb.) önbelleğe alan bir hizmet çalışanı kaydeder.

  • Bu durumda uygulama kabuğu, belirli bir URL'nin içeriğinde JavaScript ile XHR yapmak üzere tek sayfalık bir web uygulaması gibi çalışır. XHR çağrıları, içeriği görüntülemek için gereken küçük HTML, CSS ve JS parçasını döndüren /partials* uç noktasına yapılır. Not: Buna yaklaşmanın birçok yolu vardır ve XHR, bunlardan yalnızca biridir. Bazı uygulamalar ilk oluşturma için verilerini satır içine alır (belki JSON kullanarak) ve bu nedenle, düzleştirilmiş HTML anlamında "statik" olmazlar.

  • Hizmet çalışanı desteği olmayan tarayıcılara her zaman yedek deneyim sunulmalıdır. Demomuzda temel statik sunucu tarafı oluşturma yöntemine başvururuz ancak bu, birçok seçenekten yalnızca biridir. Service Worker özelliği, önbelleğe alınan uygulama kabuğunu kullanarak Tek Sayfalık Uygulama stili uygulamanızın performansını artırmak için yeni fırsatlar sunar.

Dosya sürümü oluşturma

Karşılaştığımız sorulardan biri de dosya sürümü oluşturma ve güncelleme işlemlerinin nasıl yapılacağıdır. Bu, uygulamaya özeldir ve seçenekler şunlardır:

  • Ağ önceliklendirin, aksi takdirde önbelleğe alınan sürümü kullanın.

  • Yalnızca ağ bağlantısı vardır ve çevrimdışıysa başarısız olur.

  • Eski sürümü önbelleğe alın ve daha sonra güncelleyin.

Uygulama kabuğunun kendisinde, hizmet çalışanı kurulumunuzda önbellek öncelikli yaklaşım benimsenmelidir. Uygulama kabuğunu önbelleğe almıyorsanız mimariyi doğru bir şekilde benimsememişsiniz demektir.

Aletler

Uygulamanızın kabuğunu önbelleğe alma veya yaygın önbelleğe alma kalıplarının kurulumunu kolaylaştıran birkaç farklı Service Worker yardımcı kitaplığı sunuyoruz.

Web Fundamentals&#39;taki Service Worker Library Sitesinin ekran görüntüsü

Uygulama kabuğunuz için sw-precache kullanın

Uygulama kabuğunu önbelleğe almak için sw-precache kullanıldığında dosya düzeltmeleri, yükleme/etkinleştirme soruları ve uygulama kabuğuna ilişkin getirme senaryosuyla ilgili endişeleri giderebilirsiniz. sw-precache'i uygulamanızın derleme işlemine bırakın ve statik kaynaklarınızı almak için yapılandırılabilir joker karakterler kullanın. Hizmet çalışanı komut dosyanızı manuel olarak oluşturmak yerine sw-precache'in önbellek öncelikli getirme işleyicisi kullanarak önbelleğinizi güvenli ve verimli bir şekilde yöneten bir komut dosyası oluşturmasına izin verin.

Uygulamanıza yapılan ilk ziyaretlerde, gerekli kaynakların tamamı önbelleğe alınır. Bu, uygulama mağazasından yerel uygulama yükleme deneyimine benzer. Kullanıcılar uygulamanıza geri döndüğünde yalnızca güncellenen kaynaklar indirilir. Demomuzda, "Uygulama güncellemeleri. Yeni sürüme geçmek için yenileyin." Bu düzen, kullanıcılara en yeni sürüm için yenileme yapabileceklerini bildirmenin kolay bir yoludur.

Çalışma zamanı önbelleğe alma için sw-toolbox kullanma

Kaynağa bağlı olarak farklı stratejilerle çalışma zamanı önbelleğe alma işlemi için sw-toolbox öğesini kullanın:

  • Resimler için cacheFirst ve N maxEntries değerinde özel geçerlilik bitiş tarihine sahip özel bir adlandırılmış önbellek.

  • İstenen içeriğin güncelliğine bağlı olarak networkFirst veya API istekleri için en hızlı. En hızlısı iyi olabilir ancak sık sık güncellenen belirli bir API feed'i varsa networkFirst'ü kullanın.

Sonuç

Uygulama kabuğu mimarileri, çeşitli avantajlar sunar ancak yalnızca bazı uygulama sınıfları için anlamlıdır. Model hâlâ yeni olduğundan, bu mimarinin gösterdiği çabayı ve genel performans avantajlarını değerlendirmek faydalı olacaktır.

Denemelerimizde, iki uygulama katmanı oluşturma işini en aza indirmek için istemci ile sunucu arasındaki şablon paylaşımından yararlandık. Bu sayede kademeli geliştirme, temel bir özellik olmaya devam eder.

Uygulamanızda Service Worker'ları kullanmayı zaten düşünüyorsanız mimariye göz atın ve kendi projeleriniz için uygun olup olmadığını değerlendirin.

İncelemecilerimizle teşekkür ederiz: Jeff Posnick, Paul Lewis, Alex Russell, Seth Thompson, Rob Dodson, Taylor Savage ve Joe Medley.