Bu gönderi, Chromium katkıda bulunanı Ahmed Elwasefi'nin Google Summer of Code aracılığıyla nasıl katkıda bulunan olduğunu ve tespit edip düzelttiği erişilebilirlik performansı sorunlarını paylaşmasıdır.
Kahire'deki Alman Üniversitesi'nde bilgisayar mühendisliği son sınıf öğrencisiyken açık kaynak projelerine katkıda bulunma fırsatlarını keşfetmeye karar verdim. Chromium'un yeni başlayanlara yönelik sorunları listesini keşfetmeye başladım ve özellikle erişilebilirlik konusuna ilgi duymaya başladım. Rehberlik arayışım Aaron Leventhal ile tanışmama yol açtı. Uzmanlığı ve yardım etmeye istekliliği, bir proje için onunla birlikte çalışmama ilham verdi. Bu ortak çalışma, Chromium Erişilebilirlik Ekibi ile çalışmam için kabul edildiğim Google Summer of Code deneyimim oldu.
Google Summer of Code programını başarıyla tamamladıktan sonra, performansı iyileştirmek için çözülmemiş bir kaydırma sorununu ele almaya devam ettim. Google'ın OpenCollective programından aldığımız iki bağış sayesinde, bu proje üzerinde çalışmaya devam ederken daha iyi performans için kodu basitleştirmeye odaklanan ek görevler de üstlenebildim.
Bu blog yayınında, son bir buçuk yıl içinde Chromium ile olan yolculuğumu paylaşıyorum. Özellikle performans alanında yaptığımız teknik iyileştirmeleri ayrıntılı bir şekilde ele alıyorum.
Erişilebilirlik kodu, Chrome'daki performansı nasıl etkiler?
Chrome'un erişilebilirlik kodu, ekran okuyucular gibi yardımcı teknolojilerin web'e erişmesine yardımcı olur. Ancak etkinleştirildiğinde yükleme sürelerini, performansı ve pil ömrünü etkileyebilir. Bu nedenle, gerekli olmadığında bu kod, performansın yavaşlamasını önlemek için etkin durumda kalmaz. Kullanıcıların yaklaşık% 5-10'unda erişilebilirlik kodu etkindir. Bu durum genellikle platform erişilebilirlik API'lerini kullanan şifre yöneticileri ve antivirüs yazılımları gibi araçlardan kaynaklanır. Bu araçlar, sayfa içeriğiyle etkileşime geçmek ve sayfa içeriğini değiştirmek için bu API'lerden yararlanır (ör. şifre yöneticileri ve form doldurucular için şifre alanlarının bulunması).
Temel metriklerde toplam düşüş henüz bilinmiyor ancak Erişimi Otomatik Olarak Devre Dışı Bırak (erişim kullanılmadığında devre dışı bırakma) adlı yakın tarihli bir deneme, bu oranın oldukça yüksek olduğunu gösteriyor. Sorun, Chrome'un erişilebilirlik kod tabanının iki ana alanında (oluşturucu ve tarayıcı) çok fazla hesaplama ve iletişim yapılmasından kaynaklanır. Oluşturucu, web içerikleri ve içerikteki değişiklikler hakkında bilgi toplar, bir düğüm ağacı için erişilebilirlik özelliklerini hesaplar. Ardından, kirli düğümler serileştirilir ve bir boru aracılığıyla tarayıcı işleminin ana kullanıcı arayüzü iş parçacığına gönderilir. Bu mesaj dizisi, bu bilgileri alır ve aynı düğüm ağacında seri dışına çıkarır, ardından ekran okuyucular gibi üçüncü taraf yardımcı teknolojiler için uygun bir biçime dönüştürür.
Chromium erişilebilirliğinde iyileştirmeler
Aşağıdaki projeler, Yaz Kodu Kampı sırasında ve sonrasında Google OpenCollective programı tarafından finanse edilerek tamamlandı.
Önbellek iyileştirmesi
Chrome'da, DOM ağacını yansıtan erişim ağacı adlı özel bir veri yapısı vardır. Yardımcı teknolojilerin web içeriğine erişmesine yardımcı olmak için kullanılır. Bazen bir cihazın bu ağaçtan bilgi alması gerektiğinde ağaç hazır olmayabilir. Bu nedenle, tarayıcının bu istekleri daha sonra için planlaması gerekir.
Daha önce bu planlama, geri çağırma işlevlerinin bir sıraya yerleştirilmesini içeren kapatma adı verilen bir yöntem kullanılarak gerçekleştiriliyordu. Bu yaklaşım, kapatma işlemlerinin işlenme şekli nedeniyle ek iş yükü getirdi.
Bu durumu iyileştirmek için enum kullanan bir sisteme geçtik. Her göreve belirli bir enum değeri atanır ve erişilebilirlik ağacı hazır olduğunda söz konusu göreve ait doğru yöntem çağrılır. Bu değişiklik, kodun anlaşılmasını kolaylaştırdı ve performansı %20'den fazla artırdı.
Kaydırma performansı sorunlarını bulma ve düzeltme
Ardından, sınır kutusu serileştirmesini devre dışı bıraktığımızda performansın nasıl arttığını araştırdım. Sınırlayıcı kutular, genişlik, yükseklik ve üst öğelerine göre konumları gibi ayrıntılar da dahil olmak üzere web sayfasındaki öğelerin konumları ve boyutlarıdır.
Bunu test etmek için, sınırlayıcı kutuları işleyen kodu geçici olarak kaldırdık ve etkiyi görmek için performans testleri çalıştırdık. focus-links.html adlı bir testte yaklaşık %1.618 oranında büyük bir iyileşme görüldü. Bu keşif, daha fazla çalışmanın temelini oluşturdu.
Yavaş testi inceleme
Söz konusu testin neden sınırlayıcı kutularla yavaş olduğunu incelemeye başladım. Testin tek yaptığı, birbiri ardına birkaç bağlantıya odaklanmaktı. Bu nedenle, ana sorun öğelere odaklanma veya odaklanma işlemiyle gerçekleşen kaydırma olmalıdır. Bunu test etmek için performans testindeki focus()
çağrısına {preventScroll: true}
ekledim ve kaydırmayı durdurdum.
Kaydırma devre dışıyken, sınır kutusu hesaplamaları etkinken test süresi 1,2 milisaniyeye düştü. Bu, gerçek sorunun kaydırma olduğunu gösterdi.
focus-links testini kopyalamak için scroll-in-page.html adlı yeni bir test oluşturdum. Bu testte, odaklanma yerine scrollIntoView()
ile öğeler arasında gezinilir. Hem sınırlayıcı kutu hesaplamaları hem de hesaplama olmadan hem sorunsuz hem de anında kaydırmayı test ettim.
Sonuçlar, anında kaydırma ve sınır kutuları ile işlemin yaklaşık 66 ms sürdüğünü gösterdi. Sorunsuz kaydırma ise yaklaşık 124 ms ile daha da yavaştı. Sınırlayıcı kutuları devre dışı bıraktığımızda hiçbir etkinlik tetiklenmediği için bu işlem hiç zaman almadı.
Durumu biliyorduk ancak neden böyle bir durum yaşanıyordu?
Erişilebilirlik serileştirmesinde yavaşlığın büyük bir kısmının kaydırmadan kaynaklandığını öğrenmiştik ancak nedenini bulmak için daha fazla çalışmamız gerekiyordu. Bunu analiz etmek için tarayıcı sürecinde yapılan çalışmaları ayrıntılı olarak incelemek üzere perf ve pprof adlı iki araç kullanıldı. Bu araçlar, genellikle C++'ta profil oluşturmak için kullanılır. Aşağıdaki grafiklerde ilginç bölümün bir snippet'i gösterilmektedir.
Yaptığımız incelemenin ardından, sorunun seri dışı kodlamayı gerçekleştirme kodunun kendisi değil, bu kod çağrılarının sıklığı olduğunu tespit ettik. Bunu anlamak için erişilebilirlik güncellemelerinin Chromium'da nasıl çalıştığına bakmamız gerekir. Güncellemeler ayrı ayrı gönderilmez. Bunun yerine, tüm mülkleri depolayan AXObjectCache
adlı merkezi bir konum vardır. Bir düğüm değiştiğinde çeşitli yöntemler, daha sonra serileştirme için söz konusu düğümü kirli olarak işaretlemesi için önbelleği bilgilendirir. Ardından, değişmeyen özellikler de dahil olmak üzere kirli notların tüm özellikleri serileştirilir ve tarayıcıya gönderilir. Bu tasarım, tek bir güncelleme yolu sunarak kodu basitleştirir ve karmaşıklığı azaltır. Ancak kaydırma gibi hızlı "kirli olarak işaretle" etkinlikleri olduğunda yavaşlar. Değişen tek şey scrollX
ve scrollY
değerleridir. Ancak, diğer mülkleri her seferinde bunlarla birlikte serileştiririz. Güncelleme hızı saniyede yirmiden fazlaya ulaştı.
Sınır kutusu serileştirmesi, yalnızca sınır kutusu ayrıntılarını gönderen daha hızlı bir serileştirme yolu kullanarak bu sorunu giderir ve diğer mülkleri etkilemeden hızlı güncellemelere olanak tanır. Bu yöntem, sınırlayıcı kutu değişikliklerini verimli bir şekilde yönetir.
Kaydırma düzeltmesi
Çözüm açıktı: Geçerli kaydırma ofsetlerini sınır kutusu serileştirmesine dahil edin. Bu sayede, kaydırma güncellemeleri hızlı yol üzerinden işlenir ve gereksiz gecikmeler olmadan performans artar. Kaydırma ofsetlerini sınır kutusu verileriyle paketleyerek süreci daha sorunsuz ve verimli güncellemeler için optimize ederiz. Böylece, erişilebilirlik özelliğini etkinleştirmiş kullanıcılar için daha sorunsuz bir deneyim oluştururuz. Düzeltme uygulandıktan sonra kaydırma testlerinde %825'e varan bir iyileşme elde edildi.
Kod basitleştirmeleri
Bu dönemde, Onion Soup adlı bir proje kapsamında kod kalitesine odaklandım. Bu proje, gereksiz yere katmanlar arasında dağıtılan kodu azaltarak veya kaldırarak kodu basitleştiriyor.
İlk proje, erişilebilirlik verilerinin oluşturucudan tarayıcıya serileştirilme şeklini kolaylaştırmayı amaçlıyordu. Daha önce verilerin hedefine ulaşmadan önce ek bir katmandan geçmesi gerekiyordu. Bu da gereksiz karmaşıklığa neden oluyordu. Aradaki aracıyı ortadan kaldırarak verilerin doğrudan gönderilmesine izin vererek bu süreci basitleştirdik.
Ayrıca, bir düzen tamamlandığında tetiklenenler gibi sistemde gereksiz işlere neden olan bazı eski etkinlikleri tespit edip kaldırdık. Bunları daha verimli bir çözümle değiştirdik.
Ayrıca küçük iyileştirmeler de yapıldı. Maalesef bu değişikliklerle ilgili performans iyileştirmeleri kaydedilmedi ancak kodun eskisinden çok daha net ve kendi kendini açıklayan bir hale geldiğini paylaşmaktan gurur duyuyoruz. Bu, gelecekte performans iyileştirmeleri yapmamıza yardımcı olur. Gerçek değişiklikleri gerrit profilimde kontrol edebilirsiniz.
Sonuç
Chromium Erişilebilirlik Ekibi ile çalışmak, ödüllendirici bir yolculuk oldu. Kaydırma performansını optimize etmekten kod tabanını basitleştirmeye kadar çeşitli zorluklarla mücadele ederek bu kadar büyük ölçekli bir projede geliştirme hakkında daha derin bir anlayış edindim ve profil oluşturmayla ilgili önemli araçlar öğrendim. Ayrıca, erişilebilirliğin herkesi kapsayan bir web oluşturmak için ne kadar önemli olduğunu öğrendim. Yaptığımız iyileştirmeler, yalnızca yardımcı teknolojilerden yararlanan kullanıcıların kullanıcı deneyimini iyileştirmekle kalmaz, aynı zamanda tarayıcının genel performansına ve verimliliğine de katkıda bulunur.
Performans sonuçları etkileyiciydi. Örneğin, görevleri planlamak için enum'lara geçiş, performansı %20'den fazla artırdı. Ayrıca, kaydırma düzeltmemiz kaydırma testlerinde %825'e varan bir azalma sağladı. Kod basitleştirme değişiklikleri, kodun daha net ve daha kolay yönetilebilir olmasının yanı sıra gelecekteki iyileştirmelerin de önünü açtı.
Yıl boyunca destek ve rehberliklerinden dolayı Stefan Zager, Chris Harrelson ve Mason Freed'e ve özellikle de bu fırsatın mümkün olabilmesi için elinden geleni yapan Aaron Leventhal'a teşekkür ederim. Ayrıca Tab Atkins-Bittner ve GSoC ekibine destekleri için teşekkür etmek isterim.
Anlamlı bir projeye katkıda bulunmak ve becerilerini geliştirmek isteyenlere Chromium'a katılmalarını kesinlikle öneririm. Bu, öğrenmenin mükemmel bir yoludur. Google Summer of Code gibi programlar, yolculuğunuza mükemmel bir başlangıç noktası sunar.