Kısmi nemlendirme durumu (Next ve Preact ile)

İlkbaharda, ana şirketimiz Axel Springer için farklı haber medyası web sitelerinin korunmasından sorumluyuz. En yeni çıkan yayınlarımızdan welt.de, Almanya'daki en hızlı haber medya sitesidir; En çok aranan hedeflerimizden biri sürekli olarak mümkün olan en iyi performansı elde etmektir ve bunun nedeni basittir: daha iyi performans genellikle daha iyi bir kullanıcı deneyimi ve dolayısıyla daha yüksek bir kullanıcı tutma anlamına gelir.

tl; Dr.

Bir Infographic ile kısa bir özeti için "Recap" aşağı kaydırın. Özetle bunun için anahtar noktalar:
  • Performans web için çok önemlidir
  • Yüksek performans elde etmek için müşteriye mümkün olduğunca az göndermek istiyoruz
  • bunu müşteriye göndermek ve hidratlamak istediğimiz bileşenleri seçerek yapabiliriz
  • Sayfanın geri kalanını statik olarak bıraktık ve çoklu renderleme köklerine sahibiz
  • Bütün bunlar tek bir kod tabanı ile çalışır
  • Aşağıda, yukarıda belirtilen adımların nasıl uygulandığına dair uzun bir makale bulunmaktadır. Ayrıca burada bu uygulamanın bir WIP deposuna bir link bulacaksınız:
  • https://github.com/spring-media/next-super-performance

Web’deki performans

Addy Osmani'yi takip ederseniz, tatbikatı zaten biliyorsunuzdur, performansın web'deki nedeni ve etkileri hakkında çok şey yazar. Başlamak için Addy’nin “2018’de JavaScript'in Maliyeti” başlıklı makalesini önerebilirim. Bu makaleden öğrenebileceğiniz çok önemli iki şey:

  • JavaScript'in maliyeti yalnızca paketinizi yüklemek için geçen zaman değildir
  • JavaScript'inizin ayrıştırılması ve yürütülmesi zamanı çok önemlidir

Elbette, yükleme stratejileri, kritik bir oluşturma yolu, performans bütçeleri ve benzeri dahil, performanstan çok daha fazlası var. Tüm bunlar, müşterinize gönderirken neyin en iyisini optimize edeceğiniz konusunda döner. Kısmi hidrasyon ile odaklanmak istediğimiz, gönderdiklerinizi nasıl optimize edeceğiniz değil, ne kadar gönderdiğinizdir.

Bunun önemli bir yönü, sunucu tarafında görüntü oluşturma (SSR) olacaktır; çünkü sunucuda yapmamız gereken, istemcide yapılması gerekmeyen birçok şey vardır. Aslında bu, bu makalenin özüdür; Sunucuda yapılabilecekler sunucuda yapılmalıdır, ancak müşteriye yalnızca istemci tarafında yapılması gerekenler gönderilmelidir. Ek olarak, web performansı hakkında bildiğiniz her şeyi hala uygulayabilirsiniz, ancak yönetmeniz gereken daha az faktör var, bu makalenin ilerleyen kısımlarında ayrıntılı olarak açıklanacaktır.

SSR ve hidrasyon

Performanslı bir web sitesi oluşturma hedefimizi gerçekleştirmek için Next'in değiştirilmiş bir versiyonunu kullanacağız. Sonraki, birçok gelişmiş performans geliştirme özelliği ile birlikte gelir; en önemlisi, Next, sunucu tarafı oluşturma işlemini (SSR) kutudan çıkarır. Bu, Next uygulamasının React ve şu sırayla yazılmış olan uygulamanızı alacağı anlamına gelir:

  1. Sunucuda bir HTML dizesi olarak oluştur
  2. İşlenen HTML dizesini kullanıcılarınıza kaynak kodu olarak gönderin
  3. React kodunu kullanıcılara JavaScript olarak gönder
  4. Ve sonra nihayet React kodunuzu kullanarak HTML'nizi "hidratlayın"

Bu durumda “hidrate” etmek, Next'in React kodunu HTML'inizin üzerinde yayınlayacağı ve ardından React'e şöyle bir şey söyleyeceği anlamına gelir:

Hey React, boş bir DOM düğümünde renderlemenizi söylesem, tam olarak oluşturacağınız şeyle tam olarak eşleşen bazı HTML'ler, lütfen her şeyi yeniden oluşturma senin günün

Tepki cevap verecektir

Tamam, sadece HTML’ye baktım ve göründüğümle tam olarak uyuşuyor. Serin. DOM’nize yalnızca bazı etkinlik işleyicileri ekleyeceğim ve sayfanız şimdi ilk başta hepsini kendim yaptığım gibi tek bir sayfa uygulaması gibi davranıyor.

Bir web sitesini bu şekilde yüklemenin yararları basittir: Kullanıcılarınız, web sitenizi yüklediklerinde (boş bir sayfa yerine) tamamen görüntülenen bir sayfa görecek ve etkileşimli hale gelecektir. Web siteniz de büyük bir performans iyileştirmesinden faydalanacaktır çünkü tarayıcının herhangi bir yeniden boyama işlemi yapmasına gerek yoktur (sayfanızı React ile yeniden oluşturma).

Çok fazla yükü

Web uygulamaları oluşturmak veya başka bir deyişle, JavaScript tarafından tam olarak kontrol edilmesi gereken ve tıkladığınız her yerde etkileşimli olması gereken web siteleri oluşturmak istediğinizde bu yaklaşım harikadır. Üretimdeki bu yaklaşımın örnekleri, Facebook, Twitter ve web tabanlı e-posta istemcileri gibi web sitelerini içerir.

Ancak çoğu web sitesi böyle değildir, çoğu web sitesi oldukça statiktir ve ayrıca bazı etkileşimli öğeler içerir.

Artık, uygulama kodunuzu tüm kullanıcılara sayfanızda herhangi bir yerde bulunan her başlık veya metin paragrafı için React bileşenleri dahil olmak üzere göndermeniz yeterlidir. Sonuç, yüklenmesi, ayrıştırılması ve yürütülmesi gereken gereksiz yere dev bir pakettir. Bu düşük performansta sonuçlanır, özellikle mobil kullanıcılar için sayfanız yavaş olacaktır (ve hiçbir sebep yoktur!).

Ve bu berbat.

Öyleyse ne yapabiliriz? Dışarıda pek çok strateji ve ürün var. En öne çıkanlardan biri, yoğun bir şekilde performans optimizasyonuna odaklanan statik bir site üreticisi olan Gatsby'dir (şimdiye kadar duyduğuma eminim). Gatsby ile ilgili sorun, her gün güncellenen ve milyonlarca makaleye ev sahipliği yapan bir CMS'ye bağlı sitelere sahip olduğunuzda ve milyonlarca makaleyi barındıran, gerçekten çalışmayan tüm sayfalarınızı ve alt sayfalarınızı derleme zamanında oluşturmak zorunda olmasıdır. haber medyası siteleri. Bu yüzden Next'i kullanıyoruz ve ihtiyaçlarımızı karşılayacak şekilde değiştiriyoruz.

Kısmi hidrasyon girin

Yukarıda belirtilen problemleri çözmek için kısmi nemlendirme dediğimiz bir şey bulduk.

Bu konuyu ele aldıysanız, muhtemelen aşamalı hidrasyon veya tembel hidrasyon gibi terimlerle karşılaşmış olacaksınız. Hepsi özel olarak aynı şeyi ifade etmiyorlar ama hepsi birbiriyle ilişkili ve aynı alana ait.

Kısmi hidrasyon sürümümüzün arkasındaki temel fikir şudur: SSR yapmak ve ardından tüm başvurunuzu müşterinize göndermek yerine, uygulamanızın JavaScript’inin yalnızca belirli bölümlerinin hidratlanması için müşterinize yalnızca JavaScript’in çalışmasını gerektiren kısımlarını hidratlamak için gönderilir. . Böyle bir yöntemi kullanarak bir web sitesi oluşturmak isteseydiniz, statik web sitenizde birden fazla render köküne sahip birden fazla küçük React ‘apps’ olurdu.

İşleri bu şekilde yapmak, web sitenize büyük bir performans artışı sağlamalıdır, çünkü gönderiminiz sonunda düz HTML, CSS ve sayfanız için gereken en az JavaScript miktarı yeterli olacaktır. Unutulmaması gereken bir nokta, performans ölçerken yalnızca yükleme zamanını değil aynı zamanda ayrıştırma ve yürütme zamanını da etkilemelisiniz.

Ayrıca, kod bölme, TCP yavaş başlatma işlemine ve kritik oluşturma yolunuza özen gösterme gibi tüm bunlara uygun performans stratejileri uygulamayı da seçebilirsiniz.

Bizim uygulama

Uygulamamız 2 paketten oluşmaktadır:

  • Havuz görevlisi-vaaz adı verilen kısmi hidrasyon için vaizlik kütüphanesi
  • Next.js eklentisi bir sonraki süper performans olarak adlandırılır

Son kitaplık, havuz görevlisi-vaazını kullanan Next.js için yalnızca bir eklentidir, bu nedenle havuz görevlisi-vaazına yoğunlaşalım. Gelecekteki bir aşamada bir sonraki süper performans üzerine bir takip yazısı yazabilirim.

havuz görevlisi-preact

Bir başlık, gövde, kenar çubuğu ve 2 reaktif eleman içeren düzen

Bu mizanpajın resmini çizin ve gri kutuların tamamen statik olabilen öğeler olduğunu varsayalım ve mor olanların etkileşimli olmasını istersiniz. Örneğin, büyük olan bir Twitter yayını ve küçük olan küçük bir oylama aracı olabilir. Bu yüzden etkileşimli hale getirmek için bu öğelere JavaScript uygulamamız gerekiyor ve gerisini statik öğeler olarak bırakmak istiyoruz.

Bunun için havuz görevlisi-vaiz kullanarak yapılan örnek bir uygulama şöyle görünebilir:

Satır 3–8, görüntülemek istediğimiz tüm bileşenlerdir, bu bileşenler sunucuda oluşturulur ve daha sonra herhangi bir JavaScript olmadan istemciye HTML ve CSS olarak gönderilir.

Satır 10 ve 11, nemlendirme için TwitterFeed ve Poll bileşenlerini işaretlediğimiz ve karşılığında yeni bir bileşen aldığımız yer. Satır 18 ve 19 onları kullandığımız yer.

Satır 22 çok önemlidir. Bu, hidrasyon verilerini (sahne ve bileşen adları) sayfaya enjekte eden bir bileşendir.

Ama açıklamama izin ver. Tepki ile normal bir nemlendirme yaptığımızda, kodunuz şuna benzer:

Kısmi nemlendirme yaptığımızda çözmemiz gereken 2 sorun var.

  1. ReactDOM.hydrate, hidrasyon için başlangıç ​​noktası olarak kullandığı düğüm olan DOM'daki bir kök düğüm üzerinde çalışır. Bu kök düğümü, uygulamanızın bileşenlerine ve durumuna uygun olan, sunucu tarafından oluşturulan bir DOM ağacı içermelidir. Yakala: Açıkça, bir kök düğümü görevi görmesi için bir DOM düğümünü adlandırmanız gerekir. Bu örnekte, bu basittir, bu düğüme bir kimlik verebilir, document.getElementbyId öğesini kullanabilir ve ardından bu düğümü ReactDOM.hydrate içine atabilir ve “bitirdiniz!
    Diğer taraftan kısmi hidrasyon, statik sayfanızda hidratlamanız gereken birden fazla DOM öğesinin olacağı anlamına gelir. Bunları geliştirici için sıkıcı bir iş olacak açık bir şekilde adlandırmak istemeyeceksiniz.
  2. HydrateTwitterFeed veya HydratedPoll'un kendilerine aktarılması gereken malzemelere ihtiyacı olursa ne olur? Diyelim, gibi bir şey. Eğer ReactDOM.hydrate (, rootElementOnThePage) çalıştırmak istiyorsak, luke_schmuke 'yi nereden alacağız? Statik bir sayfa bunu nasıl bilebilir? Bir şekilde onları depolayıp müşteriye göndermemiz gerekiyor.

Çözüm

Bu problemin üstesinden gelme şeklimiz, withhidrasyonun uygulanmasından anlaşılabilir:

Şuna daha yakından bakalım: withydration yüksek mertebeden bileşen tekniğini kullanarak çalışır, daha yüksek mertebeden bileşen orijinal bileşeni orijinal tadilatsız destekleriyle birlikte döndürür ancak hidrasyon işareti olarak adlandırılan bir