Habr qabaqcıl tərtibatçı qeydləri: refaktorinq və əks etdirmə

Habr qabaqcıl tərtibatçı qeydləri: refaktorinq və əks etdirmə

Mən həmişə Habrın içəridən necə qurulduğu, iş axınının necə qurulduğu, kommunikasiyaların necə qurulduğu, hansı standartlardan istifadə edildiyi və ümumiyyətlə burada kodun necə yazıldığı ilə maraqlanmışam. Xoşbəxtlikdən belə bir fürsət əldə etdim, çünki bu yaxınlarda habra komandasının bir hissəsi oldum. Mobil versiyanın kiçik bir refaktorinq nümunəsindən istifadə edərək, suala cavab verməyə çalışacağam: burada cəbhədə işləmək necədir. Proqramda: Node, Vue, Vuex və SSR Habr-da şəxsi təcrübə haqqında qeydlərdən souslu.

İnkişaf komandası haqqında bilməli olduğunuz ilk şey bizim az olmamızdır. Kifayət qədər deyil - bunlar üç cəbhə, iki arxa və bütün Habr-ın texniki rəhbəri - Baxley. Əlbəttə ki, bir tester, bir dizayner, üç Vadim, bir möcüzə süpürgəsi, marketinq mütəxəssisi və digər Bumburumlar var. Ancaq Habrın mənbələrinə yalnız altı birbaşa töhfə verən var. Bu, olduqca nadirdir - kənardan nəhəng müəssisə kimi görünən çoxmilyonluq auditoriyaya malik layihə, reallıqda mümkün olan ən düz təşkilati struktura malik rahat startap kimi görünür.

Bir çox digər İT şirkətləri kimi, Habr da Agile ideyalarını, CI təcrübələrini bəyan edir və hamısı budur. Ancaq hisslərimə görə, Habr bir məhsul olaraq davamlı deyil, dalğalarda daha çox inkişaf edir. Beləliklə, ardıcıl bir neçə sprint üçün biz səylə bir şeyi kodlaşdırırıq, dizayn edir və yenidən dizayn edirik, nəyisə sındırırıq və düzəldirik, biletləri həll edirik və yenilərini yaradırıq, dırmıqda addımlayırıq və nəhayət xüsusiyyəti buraxmaq üçün ayaqlarımıza atəş edirik. istehsal. Və sonra müəyyən bir sakitlik, yenidən inkişaf dövrü, "vacib-təcili olmayan" kvadrantda olanı etmək vaxtı gəlir.

Məhz bu "mövsümdənkənar" sprint aşağıda müzakirə olunacaq. Bu dəfə o, Habr-ın mobil versiyasının refaktorinqini əhatə etdi. Ümumiyyətlə, şirkət buna böyük ümidlər bəsləyir və gələcəkdə o, Habr inkarnasiyalarının bütün zooparkını əvəz etməli və universal çarpaz platforma həllinə çevrilməlidir. Bir gün adaptiv layout, PWA, oflayn rejim, istifadəçi fərdiləşdirməsi və bir çox başqa maraqlı şeylər olacaq.

Tapşırığı təyin edək

Bir dəfə adi bir stand-upda cəbhəçilərdən biri mobil versiyanın şərh komponentinin arxitekturasındakı problemlərdən danışdı. Bunu nəzərə alaraq qrup psixoterapiyası formatında mikro görüş təşkil etdik. Hamı növbə ilə deyirdi ki, hara ağrıdı, hər şeyi kağıza yazdılar, rəğbət bəslədilər, başa düşdülər, ondan başqa heç kim əl çalmadı. Nəticə 20 problemin siyahısı oldu və bu, mobil Habr-ın hələ də uğura aparan uzun və çətin bir yolu olduğunu aydınlaşdırdı.

Məni ilk növbədə resursdan istifadənin səmərəliliyi və hamar interfeys deyilən şey maraqlandırırdı. Hər gün ev-iş-ev marşrutunda köhnə telefonumun çarəsiz şəkildə lentdə 20 başlıq göstərməyə çalışdığını gördüm. Bu kimi bir şey görünürdü:

Habr qabaqcıl tərtibatçı qeydləri: refaktorinq və əks etdirməRefaktorinqdən əvvəl Mobil Habr interfeysi

Burda nə baş verir? Bir sözlə, istifadəçinin daxil olub-olmamasından asılı olmayaraq server HTML səhifəsini hamıya eyni şəkildə təqdim edirdi. Sonra müştəri JS yüklənir və lazımi məlumatları yenidən tələb edir, lakin avtorizasiya üçün düzəliş edilir. Yəni əslində iki dəfə eyni işi görmüşük. İnterfeys titrədi və istifadəçi yaxşı yüz əlavə kilobayt yüklədi. Təfərrüatlarda hər şey daha ürpertici görünürdü.

Habr qabaqcıl tərtibatçı qeydləri: refaktorinq və əks etdirməKöhnə SSR-CSR sxemi. Avtorizasiya yalnız C3 və C4 mərhələlərində mümkündür, o zaman ki, Node JS HTML yaratmaqla məşğul deyil və API sorğularını proxy edə bilər.

O dövrün memarlığımızı Habr istifadəçilərindən biri çox dəqiq təsvir etmişdi:

Mobil versiya cəfəngiyatdır. Mən bunu olduğu kimi deyirəm. SSR və CSR-nin dəhşətli birləşməsi.

Nə qədər kədərli olsa da, etiraf etməli idik.

Variantları qiymətləndirdim, Jira-da "indi pisdir, bunu düzgün et" səviyyəsində təsviri olan bir bilet yaratdım və tapşırığı geniş vuruşlarla parçaladım:

  • məlumatların təkrar istifadəsi,
  • yenidən çəkilişlərin sayını minimuma endirmək,
  • dublikat sorğuları aradan qaldırmaq,
  • yükləmə prosesini daha aydın etmək.

Gəlin məlumatları yenidən istifadə edək

Nəzəri olaraq, server tərəfində göstərmə iki problemi həll etmək üçün nəzərdə tutulmuşdur: axtarış sisteminin məhdudiyyətlərindən əziyyət çəkməmək. SPA indeksləşdirilməsi və metrikanı təkmilləşdirin FMP (qaçılmaz olaraq pisləşir TTI). Klassik ssenaridə nəhayət 2013-cü ildə Airbnb-də tərtib edilmişdir il (hələ də Backbone.js-də), SSR Node mühitində işləyən eyni izomorfik JS tətbiqidir. Server sadəcə sorğuya cavab olaraq yaradılan planı göndərir. Sonra rehidrasiya müştəri tərəfində baş verir və sonra hər şey səhifəni yenidən yükləmədən işləyir. Habr üçün, mətn məzmunlu bir çox digər resurslarda olduğu kimi, server göstərilməsi axtarış motorları ilə dostluq əlaqələrinin qurulmasında mühüm elementdir.

Texnologiyanın ortaya çıxmasından altı ildən çox vaxt keçməsinə və bu müddət ərzində cəbhə dünyasında həqiqətən körpünün altından çoxlu su axmasına baxmayaraq, bir çox tərtibatçılar üçün bu fikir hələ də məxfi olaraq qalır. Biz kənara durmadıq və istehsala SSR dəstəyi ilə Vue tətbiqini yaydıq, kiçik bir detalı əldən verdik: müştəriyə ilkin vəziyyəti göndərmədik.

Niyə? Bu sualın dəqiq cavabı yoxdur. Ya serverdən gələn cavabın ölçüsünü artırmaq istəmədilər, ya da bir sıra digər memarlıq problemlərinə görə, ya da sadəcə olaraq alınmadı. Bu və ya digər şəkildə, vəziyyəti atmaq və serverin etdiyi hər şeyi yenidən istifadə etmək olduqca uyğun və faydalı görünür. Tapşırıq əslində əhəmiyyətsizdir - dövlət sadəcə olaraq vurulur icra kontekstinə daxil olur və Vue onu avtomatik olaraq qlobal dəyişən kimi yaradılan tərtibata əlavə edir: window.__INITIAL_STATE__.

Yaranan problemlərdən biri tsiklik strukturları JSON-a çevirə bilməməkdir (dairə istinadı); sadəcə olaraq belə strukturları düz analoqları ilə əvəz etməklə həll olundu.

Bundan əlavə, UGC məzmunu ilə məşğul olarkən yadda saxlamalısınız ki, HTML-i pozmamaq üçün verilənlər HTML obyektlərinə çevrilməlidir. Bu məqsədlər üçün istifadə edirik he.

Yenidən çəkilişlərin minimuma endirilməsi

Yuxarıdakı diaqramdan göründüyü kimi, bizim vəziyyətimizdə bir Node JS nümunəsi iki funksiyanı yerinə yetirir: istifadəçi avtorizasiyasının baş verdiyi API-də SSR və “proksi”. Bu hal JS kodu serverdə işləyərkən avtorizasiya etməyi qeyri-mümkün edir, çünki qovşaq tək yivlidir və SSR funksiyası sinxrondur. Yəni, zəng yığını nə iləsə məşğul olarkən server sadəcə özünə sorğu göndərə bilmir. Məlum oldu ki, vəziyyəti yenilədik, lakin interfeys seğirməyi dayandırmadı, çünki müştəridəki məlumatlar istifadəçi sessiyasını nəzərə alaraq yenilənməli idi. Tətbiqimizə istifadəçinin girişini nəzərə alaraq düzgün məlumatları ilkin vəziyyətə qoymağı öyrətməli olduq.

Problemin yalnız iki həlli var idi:

  • serverlər arası sorğulara avtorizasiya məlumatlarını əlavə edin;
  • Node JS qatlarını iki ayrı instansiyaya bölün.

Birinci həll serverdə qlobal dəyişənlərin istifadəsini tələb edirdi, ikincisi isə tapşırığın yerinə yetirilməsi üçün son müddəti ən azı bir ay uzadırdı.

Seçimi necə etmək olar? Habr tez-tez ən az müqavimət yolu ilə hərəkət edir. Qeyri-rəsmi olaraq, ideyadan prototipə qədər dövrü minimuma endirmək üçün ümumi bir istək var. Məhsula münasibət modeli bir qədər booking.com-un postulatlarını xatırladır, yeganə fərq odur ki, Habr istifadəçi rəylərinə daha ciddi yanaşır və bu cür qərarlar qəbul etmək üçün bir tərtibatçı kimi sizə etibar edir.

Bu məntiqə və problemi tez həll etmək istəyimə əməl edərək qlobal dəyişənləri seçdim. Və tez-tez baş verdiyi kimi, gec-tez onlar üçün ödəməlisən. Demək olar ki, dərhal ödədik: həftə sonu işlədik, nəticələri təmizlədik, yazdıq postmortem və serveri iki hissəyə bölməyə başladı. Səhv çox axmaq idi və onunla əlaqəli səhvi təkrarlamaq asan deyildi. Bəli, bunun üçün ayıbdır, amma bu və ya digər şəkildə büdrəyərək və inildəyərək qlobal dəyişənlərim olan PoC-im buna baxmayaraq istehsala keçdi və yeni "iki düyünlü" arxitekturaya keçidi gözləyərkən olduqca uğurla işləyir. Bu, vacib bir addım idi, çünki formal olaraq məqsədə nail olundu - SSR tamamilə istifadəyə hazır səhifəni çatdırmağı öyrəndi və UI daha sakitləşdi.

Habr qabaqcıl tərtibatçı qeydləri: refaktorinq və əks etdirməRefaktorinqin birinci mərhələsindən sonra Mobil Habr interfeysi

Nəhayət, mobil versiyanın SSR-CSR arxitekturası bu mənzərəyə gətirib çıxarır:

Habr qabaqcıl tərtibatçı qeydləri: refaktorinq və əks etdirmə“İki node” SSR-CSR sxemi. Node JS API həmişə asinxron I/O üçün hazırdır və SSR funksiyası tərəfindən bloklanmır, çünki sonuncu ayrıca instansiyada yerləşir. №3 sorğu zənciri lazım deyil.

Dublikat sorğuların aradan qaldırılması

Manipulyasiyalar aparıldıqdan sonra səhifənin ilkin göstərilməsi artıq epilepsiyaya səbəb olmadı. Lakin Habr-ın SPA rejimində sonrakı istifadəsi yenə də çaşqınlıq yaratdı.

Çünki istifadəçi axınının əsasını forma keçidləri təşkil edir məqalələrin siyahısı → məqalə → şərhlər və əksinə, ilk növbədə bu zəncirin resurs istehlakını optimallaşdırmaq vacib idi.

Habr qabaqcıl tərtibatçı qeydləri: refaktorinq və əks etdirməPost lentinə qayıtmaq yeni məlumat sorğusuna səbəb olur

Dərin qazmağa ehtiyac yoxdu. Yuxarıdakı ekran görüntüsündə görə bilərsiniz ki, proqram geri sürüşdürərkən məqalələrin siyahısını yenidən tələb edir və sorğu zamanı biz məqalələri görmürük, yəni əvvəlki məlumatlar hardasa yox olur. Deyəsən, məqalə siyahısı komponenti yerli vəziyyətdən istifadə edir və məhv edildikdə onu itirir. Əslində, proqram qlobal bir vəziyyətdən istifadə etdi, lakin Vuex arxitekturası birbaşa quruldu: modullar səhifələrə bağlanır, onlar da marşrutlara bağlıdır. Üstəlik, bütün modullar "birdəfəlik istifadə olunur" - səhifəyə hər növbəti ziyarət bütün modulu yenidən yazdı:

ArticlesList: [
  { Article1 },
  ...
],
PageArticle: { ArticleFull1 },

Ümumilikdə bir modulumuz var idi Məqalələr siyahısıtipli obyektləri ehtiva edən Məqalə və modul Səhifə Məqaləsi, bu obyektin genişləndirilmiş versiyası idi Məqalə, kimi Tam məqalə. Ümumiyyətlə, bu tətbiq özlüyündə dəhşətli bir şey daşımır - çox sadədir, hətta sadəlövh deyilə bilər, lakin son dərəcə başa düşüləndir. Əgər marşrutu hər dəfə dəyişdirdiyiniz zaman modulu sıfırlasanız, hətta onunla yaşaya bilərsiniz. Bununla belə, məsələn, məqalə lentləri arasında hərəkət etmək /feed → /hamısı, şəxsi lentlə əlaqəli hər şeyi atmağa zəmanət verilir, çünki bizdə yalnız bir var Məqalələr siyahısı, yeni məlumatlar yerləşdirməli olduğunuz. Bu, bizi yenidən sorğuların təkrarlanmasına gətirib çıxarır.

Mövzu ilə bağlı öyrənə bildiyim hər şeyi toplayıb, yeni dövlət strukturunu formalaşdırıb həmkarlarıma təqdim etdim. Müzakirələr uzun sürdü, amma sonda lehinə olan arqumentlər şübhələri üstələdi və mən həyata keçirməyə başladım.

Həllin məntiqi ən yaxşı şəkildə iki mərhələdə aşkarlanır. Əvvəlcə Vuex modulunu səhifələrdən ayırmağa və birbaşa marşrutlara bağlamağa çalışırıq. Bəli, mağazada bir az daha çox məlumat olacaq, alıcılar bir az daha mürəkkəbləşəcək, amma məqalələri iki dəfə yükləməyəcəyik. Mobil versiya üçün bu, bəlkə də ən güclü arqumentdir. Bu kimi bir şey görünəcək:

ArticlesList: {
  ROUTE_FEED: [ 
    { Article1 },
    ...
  ],
  ROUTE_ALL: [ 
    { Article2 },
    ...
  ],
}

Bəs məqalə siyahıları bir çox marşrutlar arasında üst-üstə düşə bilərsə və obyekt məlumatlarından yenidən istifadə etmək istəsək nə olacaq? Məqalə poçt səhifəsini göstərmək, onu çevirmək Tam məqalə? Bu vəziyyətdə belə bir quruluşdan istifadə etmək daha məntiqli olardı:

ArticlesIds: {
  ROUTE_FEED: [ '1', ... ],
  ROUTE_ALL: [ '1', '2', ... ],
},
ArticlesList: {
  '1': { Article1 }, 
  '2': { Article2 },
  ...
}

Məqalələr siyahısı burada sadəcə bir növ məqalə anbarıdır. İstifadəçi sessiyası zamanı yüklənmiş bütün məqalələr. Biz onlara son dərəcə diqqətlə yanaşırıq, çünki bu, stansiyalar arasında metronun hardasa ağrıları nəticəsində yüklənmiş ola biləcək trafikdir və biz mütləq istifadəçini artıq olduğu məlumatları yükləməyə məcbur etməklə bir daha bu ağrıya səbəb olmaq istəmirik. endirilib. Bir obyekt Məqalələrİdləri sadəcə olaraq obyektlərə identifikatorlar massividir (sanki “bağlantılar”). Məqalə. Bu struktur marşrutlar üçün ümumi məlumatların təkrarlanmasının qarşısını almağa və obyektdən təkrar istifadə etməyə imkan verir Məqalə genişləndirilmiş məlumatları birləşdirərək bir poçt səhifəsini göstərərkən.

Məqalələr siyahısının çıxışı da daha şəffaf oldu: iterator komponenti məqalə identifikatorları ilə massivdə təkrarlanır və İd-i rekvizit kimi ötürərək məqalə tizer komponentini çəkir, uşaq komponent isə öz növbəsində lazımi məlumatları əldə edir. Məqalələr siyahısı. Nəşr səhifəsinə keçdiyiniz zaman artıq mövcud tarixi əldə edirik Məqalələr siyahısı, çatışmayan məlumatları əldə etmək və sadəcə mövcud obyektə əlavə etmək üçün sorğu edirik.

Niyə bu yanaşma daha yaxşıdır? Yuxarıda yazdığım kimi, bu yanaşma yüklənmiş məlumatlara münasibətdə daha yumşaqdır və onu təkrar istifadə etməyə imkan verir. Bununla yanaşı, belə bir arxitekturaya mükəmməl uyğunlaşan bəzi yeni imkanlara yol açır. Məsələn, sorğu və məqalələrin göründükləri kimi lentə yüklənməsi. Biz sadəcə olaraq ən son yazıları “anbara” qoya bilərik Məqalələr siyahısı, yeni ID-lərin ayrıca siyahısını saxlayın Məqalələrİdləri və bu barədə istifadəçini xəbərdar edin. "Yeni nəşrləri göstər" düyməsini kliklədikdə, biz sadəcə olaraq mövcud məqalələr siyahısının əvvəlinə yeni İdlər əlavə edəcəyik və hər şey demək olar ki, sehrli şəkildə işləyəcək.

Yükləməni daha zövqlü etmək

Refaktorinq tortunun üzərindəki buzlanma skeletlər konsepsiyasıdır ki, bu da yavaş İnternetdə məzmunun yüklənməsi prosesini bir az daha az iyrənc edir. Bu mövzuda heç bir müzakirə aparılmadı, ideyadan prototipə qədər olan yol sözün həqiqi mənasında iki saat çəkdi. Dizayn praktiki olaraq özünü çəkdi və biz komponentlərimizə məlumatları gözləyərkən sadə, azca titrəyən div bloklarını göstərməyi öyrətdik. Subyektiv olaraq, yükləməyə bu yanaşma əslində istifadəçinin bədənində stress hormonlarının miqdarını azaldır. Skelet belə görünür:

Habr qabaqcıl tərtibatçı qeydləri: refaktorinq və əks etdirmə
Habraloading

əks etdirən

Mən altı aydır Habrédə işləyirəm və dostlarım hələ də soruşurlar: yaxşı, orda necədir? Yaxşı, rahat - bəli. Amma bu əsəri digərlərindən fərqləndirən bir şey var. Məhsullarına tamamilə laqeyd yanaşan, istifadəçilərinin kim olduğunu bilməyən və anlamayan komandalarda işləmişəm. Ancaq burada hər şey fərqlidir. Burada etdiyiniz iş üçün məsuliyyət hiss edirsiniz. Xüsusiyyətin inkişafı prosesində siz qismən onun sahibi olursunuz, funksionallığınızla bağlı bütün məhsul görüşlərində iştirak edir, təkliflər verir və özünüz qərar verirsiniz. Hər gün istifadə etdiyiniz bir məhsul hazırlamaq çox gözəldir, lakin sizdən daha yaxşı olan insanlar üçün kod yazmaq sadəcə inanılmaz bir hissdir (sarkazm yoxdur).

Bütün bu dəyişiklikləri buraxdıqdan sonra müsbət rəy aldıq və bu, çox, çox gözəl idi. Bu ruhlandırıcıdır. Çox sağ ol! Daha çox yazın.

Nəzərinizə çatdırım ki, qlobal dəyişənlərdən sonra biz arxitekturanı dəyişmək və proksi qatını ayrıca instansiyaya ayırmaq qərarına gəldik. “İki qovşaqlı” arxitektura artıq ictimai beta testi şəklində buraxılışa çatmışdır. İndi hər kəs ona keçə və mobil Habr-ı daha yaxşı etməkdə bizə kömək edə bilər. Bu gün üçün hamısı budur. Şərhlərdə bütün suallarınıza cavab verməkdən məmnun olaram.

Mənbə: www.habr.com

Добавить комментарий