„Habr“ sąsajos kūrėjų žurnalai: pertvarkymas ir atspindys

„Habr“ sąsajos kūrėjų žurnalai: pertvarkymas ir atspindys

Mane visada domino, kaip Habr yra struktūrizuotas iš vidaus, kaip struktūrizuota darbo eiga, kaip struktūrizuojama komunikacija, kokie standartai naudojami ir kaip čia apskritai parašytas kodas. Laimei, tokią galimybę gavau, nes neseniai tapau habra komandos dalimi. Remdamasis nedidelio mobiliosios versijos pertvarkymo pavyzdžiu, pabandysiu atsakyti į klausimą: kaip čia dirbti priekinėje linijoje? Programoje: Node, Vue, Vuex ir SSR su padažu iš užrašų apie asmeninę patirtį Habr.

Pirmas dalykas, kurį reikia žinoti apie kūrėjų komandą, yra tai, kad esame maži. Little yra trys frontai, du nugarai ir techninis Habr - Baxley lyderis. Yra, žinoma, ir testuotojas, dizaineris, trys Vadimai, stebuklinga šluota, rinkodaros specialistė ir kiti Bumburumai. Tačiau yra tik šeši tiesioginiai Habro svetainių bendradarbiai. Tai gana reta – projektas su milijonine auditorija, kuris iš išorės atrodo kaip milžiniška įmonė, iš tikrųjų labiau primena jaukų startuolį, kurio organizacinė struktūra yra plokščia.

Kaip ir daugelis kitų IT įmonių, Habras išpažįsta Agile idėjas, CI praktiką ir viskas. Tačiau, mano nuomone, Habras kaip produktas vystosi bangomis, o ne nuolat. Taigi, kelis sprintus iš eilės stropiai kažką koduojame, projektuojame ir perkuriame, kažką laužome ir taisome, sprendžiame bilietus ir kuriame naujus, lipame ant grėblio ir šauname sau į kojas, kad pagaliau išleistume funkciją ateities. Ir tada ateina tam tikras užliūlis, pertvarkymo laikotarpis, laikas daryti tai, kas yra „svarbu-neskubu“ kvadrante.

Būtent šis „ne sezono“ sprintas bus aptartas toliau. Šį kartą buvo pertvarkyta mobilioji Habr versija. Apskritai įmonė į tai deda daug vilčių, o ateityje ji turėtų pakeisti visą Habro įsikūnijimų zoologijos sodą ir tapti universaliu tarpplatforminiu sprendimu. Kada nors bus pritaikytas išdėstymas, PWA, neprisijungus režimas, vartotojo pritaikymas ir daug kitų įdomių dalykų.

Nustatykime užduotį

Kartą įprasto stendo metu vienas iš priekinių kalbėjo apie mobiliosios versijos komentarų komponento architektūros problemas. Su šiuo pasiūlymu organizavome mikrosusitikimą grupinės psichoterapijos formatu. Visi paeiliui sakydavo, kur skauda, ​​viską fiksavo popieriuje, užjautė, suprato, išskyrus tai, kad niekas neplojo. Rezultatas buvo 20 problemų sąrašas, kuris aiškiai parodė, kad mobilusis Habras vis dar turi ilgą ir sudėtingą kelią į sėkmę.

Man pirmiausia rūpėjo išteklių efektyvumas ir tai, kas vadinama sklandžia sąsaja. Kiekvieną dieną kelyje „namai–darbas–namai“ matydavau savo seną telefoną, kuris desperatiškai bandė sklaidos kanale rodyti 20 antraščių. Tai atrodė maždaug taip:

„Habr“ sąsajos kūrėjų žurnalai: pertvarkymas ir atspindysMobilioji Habr sąsaja prieš pertvarkymą

Kas čia vyksta? Trumpai tariant, serveris HTML puslapį teikė visiems vienodai, nepriklausomai nuo to, ar vartotojas buvo prisijungęs, ar ne. Tada klientas JS įkeliamas ir vėl prašo reikalingų duomenų, tačiau šį kartą pakoreguotas autorizacijai. Tai yra, mes iš tikrųjų atlikome tą patį darbą du kartus. Sąsaja mirgėjo, o vartotojas atsisiuntė gerą šimtą papildomų kilobaitų. Detalėse viskas atrodė dar baisiau.

„Habr“ sąsajos kūrėjų žurnalai: pertvarkymas ir atspindysSena SSR-CSR schema. Autorizacija galima tik C3 ir C4 etapuose, kai mazgas JS nėra užsiėmęs generuodamas HTML ir gali pateikti tarpinio serverio užklausas API.

Mūsų tuometinę architektūrą labai tiksliai apibūdino vienas iš Habr vartotojų:

Mobilioji versija yra kvaila. Sakau taip, kaip yra. Siaubingas SSR ir CSR derinys.

Buvome priversti tai pripažinti, kad ir kaip būtų liūdna.

Įvertinau variantus, sukūriau bilietą Jira su aprašymu lygiu „dabar blogai, padaryk viską gerai“ ir išskaidžiau užduotį plačiais potėpiais:

  • pakartotinai naudoti duomenis,
  • sumažinti perpiešimų skaičių,
  • pašalinti pasikartojančius prašymus,
  • kad pakrovimo procesas būtų aiškesnis.

Panaudokime duomenis pakartotinai

Teoriškai serverio pusės atvaizdavimas skirtas išspręsti dvi problemas: nepakenkti dėl paieškos sistemos apribojimų. SPA indeksavimas ir pagerinti metriką FMP (neišvengiamai blogėja TTI). Pagal klasikinį scenarijų, kad pagaliau suformuluotas „Airbnb“ 2013 m metų (grįžta Backbone.js), SSR yra ta pati izomorfinė JS programa, veikianti Node aplinkoje. Serveris tiesiog grąžina sugeneruotą maketą kaip atsakymą į užklausą. Tada kliento pusėje įvyksta rehidratacija, o tada viskas veikia be puslapio perkrovimo. Habrui, kaip ir daugeliui kitų teksto turinio išteklių, serverio atvaizdavimas yra esminis elementas kuriant draugiškus santykius su paieškos sistemomis.

Nepaisant to, kad nuo technologijos atsiradimo praėjo daugiau nei šešeri metai ir per tą laiką po tiltu pratekėjo daug vandens front-end pasaulyje, daugeliui kūrėjų šią idėją vis dar gaubia paslaptis. Neatstovėjome nuošalyje ir išleidome Vue programą su SSR palaikymu į gamybą, pasigedę vienos smulkmenos: klientui neperdavėme pradinės būsenos.

Kodėl? Tikslaus atsakymo į šį klausimą nėra. Arba jie nenorėjo padidinti atsakymo iš serverio, arba dėl daugybės kitų architektūrinių problemų, arba jis tiesiog nepasirodė. Vienaip ar kitaip išmesti būseną ir pakartotinai panaudoti viską, ką padarė serveris, atrodo visai tinkama ir naudinga. Užduotis iš tikrųjų yra nereikšminga. būsena tiesiog suleidžiama į vykdymo kontekstą, o Vue automatiškai prideda jį prie sugeneruoto išdėstymo kaip visuotinį kintamąjį: window.__INITIAL_STATE__.

Viena iš iškilusių problemų yra nesugebėjimas konvertuoti ciklinių struktūrų į JSON (žiedinė nuoroda); buvo išspręsta tiesiog pakeičiant tokias konstrukcijas plokščiomis jų atitikmenimis.

Be to, dirbdami su NST turiniu, turėtumėte atsiminti, kad duomenys turi būti konvertuojami į HTML objektus, kad nepažeistumėte HTML. Šiems tikslams naudojame he.

Perbraižymų sumažinimas

Kaip matote iš aukščiau pateiktos diagramos, mūsų atveju vienas Node JS egzempliorius atlieka dvi funkcijas: SSR ir „proxy“ API, kur įvyksta vartotojo autorizacija. Ši aplinkybė neleidžia autorizuoti, kol JS kodas veikia serveryje, nes mazgas yra vienos gijos, o SSR funkcija yra sinchroninė. Tai reiškia, kad serveris tiesiog negali siųsti užklausų sau, kol skambučių paketas yra kažkuo užimtas. Paaiškėjo, kad atnaujinome būseną, tačiau sąsaja nenustojo trūkčioti, nes kliento duomenys turėjo būti atnaujinti atsižvelgiant į vartotojo seansą. Reikėjo išmokyti mūsų programą įdėti teisingus duomenis į pradinę būseną, atsižvelgiant į vartotojo prisijungimą.

Buvo tik du problemos sprendimai:

  • susieti autorizacijos duomenis su kelių serverių užklausomis;
  • padalinti Node JS sluoksnius į du atskirus egzempliorius.

Pirmajame sprendime serveryje reikėjo naudoti globalius kintamuosius, o antrasis užduoties atlikimo terminas buvo pratęstas mažiausiai mėnesiu.

Kaip padaryti pasirinkimą? Habras dažnai juda mažiausio pasipriešinimo keliu. Neoficialiai yra bendras noras iki minimumo sumažinti ciklą nuo idėjos iki prototipo. Požiūrio į produktą modelis kažkuo primena booking.com postulatus, tik skirtumas tas, kad Habras daug rimčiau žiūri į vartotojų atsiliepimus ir tokius sprendimus patiki jums, kaip kūrėjui.

Vadovaudamasis šia logika ir savo noru greitai išspręsti problemą, pasirinkau globalius kintamuosius. Ir, kaip dažnai nutinka, anksčiau ar vėliau už juos tenka susimokėti. Sumokėjome beveik iš karto: dirbome savaitgalį, išsiaiškinome pasekmes, rašėme po mirties ir pradėjo dalyti serverį į dvi dalis. Klaida buvo labai kvaila, o su ja susijusią klaidą nebuvo lengva atkurti. Ir taip, gaila už tai, bet vienaip ar kitaip klupdamas ir dejuodamas mano PoC su globaliais kintamaisiais vis dėlto buvo pradėtas gaminti ir veikia gana sėkmingai, laukdamas perėjimo prie naujos „dviejų mazgų“ architektūros. Tai buvo svarbus žingsnis, nes formaliai tikslas buvo pasiektas – SSR išmoko pristatyti visiškai paruoštą naudoti puslapį, o vartotojo sąsaja tapo daug ramesnė.

„Habr“ sąsajos kūrėjų žurnalai: pertvarkymas ir atspindysMobilioji Habr sąsaja po pirmojo pertvarkymo etapo

Galiausiai mobiliosios versijos SSR-CSR architektūra rodo tokį vaizdą:

„Habr“ sąsajos kūrėjų žurnalai: pertvarkymas ir atspindys„Dviejų mazgų“ SSR-CSR grandinė. Mazgo JS API visada paruošta asinchroniniam įvesties / išvesties ryšiui ir jos neblokuoja funkcija SSR, nes pastaroji yra atskirame egzemplioriuje. 3 užklausos grandinė nereikalinga.

Pasikartojančių užklausų pašalinimas

Atlikus manipuliacijas, pirminis puslapio atvaizdavimas epilepsijos nebeprovokavo. Tačiau tolesnis Habr naudojimas SPA režimu vis tiek sukėlė sumaištį.

Kadangi vartotojų srauto pagrindas yra formos perėjimai straipsnių sąrašas → straipsnis → komentarai ir atvirkščiai, visų pirma buvo svarbu optimizuoti šios grandinės išteklių suvartojimą.

„Habr“ sąsajos kūrėjų žurnalai: pertvarkymas ir atspindysGrįžus į įrašų sklaidos kanalą, suaktyvinama nauja duomenų užklausa

Giliai kasti nereikėjo. Viršuje esančiame ekrano įraše matote, kad programa braukiant atgal iš naujo prašo straipsnių sąrašo, o užklausos metu straipsnių nematome, vadinasi, ankstesni duomenys kažkur dingsta. Atrodo, kad straipsnių sąrašo komponentas naudoja vietinę būseną ir praranda ją, kad sunaikintų. Tiesą sakant, programa naudojo pasaulinę būseną, tačiau „Vuex“ architektūra buvo sukurta tiesiai: moduliai yra susieti su puslapiais, kurie savo ruožtu yra susieti su maršrutais. Be to, visi moduliai yra „vienkartiniai“ - kiekvienas paskesnis apsilankymas puslapyje perrašė visą modulį:

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

Iš viso turėjome modulį Straipsnių sąrašas, kuriame yra tipo objektai Straipsnis ir modulis PuslapisStraipsnis, kuri buvo išplėstinė objekto versija Straipsnis, maždaug Pilnas straipsnis. Apskritai, šis įgyvendinimas savaime neatneša nieko baisaus - jis labai paprastas, netgi galima sakyti, naivus, bet nepaprastai suprantamas. Jei kiekvieną kartą keisdami maršrutą modulį nustatysite iš naujo, galėsite net gyventi su juo. Tačiau, pavyzdžiui, perėjimas tarp straipsnių kanalų /feed → /all, garantuotai išmesite viską, kas susiję su jūsų asmeniniu pašaru, nes turime tik vieną Straipsnių sąrašas, į kurią reikia įdėti naujų duomenų. Tai vėl priveda prie užklausų dubliavimo.

Surinkęs viską, ką pavyko iškasti ta tema, suformulavau naują valstybės struktūrą ir pristačiau ją kolegoms. Diskusijos buvo ilgos, bet galiausiai argumentai „už“ nusvėrė abejones, ir aš pradėjau įgyvendinti.

Sprendimo logika geriausiai atsiskleidžia dviem etapais. Pirmiausia bandome atsieti Vuex modulį nuo puslapių ir tiesiogiai susieti su maršrutais. Taip, parduotuvėje bus šiek tiek daugiau duomenų, geteriai taps šiek tiek sudėtingesni, bet straipsnių du kartus neįkelsime. Mobiliajai versijai tai bene stipriausias argumentas. Tai atrodys maždaug taip:

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

Bet kas, jei straipsnių sąrašai gali sutapti keliuose maršrutuose, o jei norime pakartotinai naudoti objekto duomenis Straipsnis Norėdami pateikti įrašo puslapį, paverčiant jį į Pilnas straipsnis? Šiuo atveju logiškiau būtų naudoti tokią struktūrą:

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

Straipsnių sąrašas čia tik savotiška straipsnių saugykla. Visi straipsniai, kurie buvo atsisiųsti per vartotojo sesiją. Mes su jais elgiamės labai atsargiai, nes tai yra srautas, kuris galėjo būti apkrautas kažkur metro tarp stočių, ir tikrai nenorime vėl sukelti tokio skausmo vartotojui, versdami jį įkelti duomenis, kuriuos jis jau atsisiuntė. . Objektas Straipsnių ID yra tiesiog ID (pvz., „nuorodų“) į objektus masyvas Straipsnis. Ši struktūra leidžia išvengti maršrutams įprastų duomenų dubliavimo ir objekto pakartotinio naudojimo Straipsnis atvaizduojant įrašo puslapį sujungiant į jį išplėstinius duomenis.

Straipsnių sąrašo išvestis taip pat tapo skaidresnė: iteratoriaus komponentas iteruoja per masyvą su straipsnių ID ir nubrėžia straipsnio anonso komponentą, perduodamas ID kaip rekvizitus, o antrinis komponentas, savo ruožtu, nuskaito reikiamus duomenis iš Straipsnių sąrašas. Kai einate į publikacijos puslapį, gauname esamą datą nuo Straipsnių sąrašas, pateikiame prašymą gauti trūkstamus duomenis ir tiesiog pridedame prie esamo objekto.

Kodėl šis metodas yra geresnis? Kaip rašiau aukščiau, šis metodas yra atsargesnis atsisiųstų duomenų atžvilgiu ir leidžia pakartotinai juos naudoti. Bet be to, tai atveria kelią naujoms galimybėms, kurios puikiai tinka tokiai architektūrai. Pavyzdžiui, apklausa ir straipsnių įkėlimas į sklaidos kanalą, kai jie pasirodo. Naujausius įrašus galime tiesiog įdėti į „saugyklą“ Straipsnių sąrašas, išsaugokite atskirą naujų ID sąrašą Straipsnių ID ir apie tai pranešti vartotojui. Paspaudę mygtuką „Rodyti naujus leidinius“, tiesiog įterpsime naujus ID į dabartinio straipsnių sąrašo pradžią ir viskas veiks beveik stebuklingai.

Kad atsisiuntimas būtų malonesnis

Vyšna ant pertvarkymo pyrago yra skeletų koncepcija, dėl kurios turinio įkėlimo į lėtą internetą procesas tampa mažiau varginantis. Diskusijų šiuo klausimu nebuvo, kelias nuo idėjos iki prototipo užtruko tiesiog dvi valandas. Dizainas praktiškai nupiešė save, o mes išmokėme savo komponentus pateikti paprastus, vos mirksinčius div blokus, kol laukiame duomenų. Subjektyviai toks požiūris į apkrovą iš tikrųjų sumažina streso hormonų kiekį vartotojo organizme. Skeletas atrodo taip:

„Habr“ sąsajos kūrėjų žurnalai: pertvarkymas ir atspindys
Habraloading

Atspindintys

Aš dirbu Habre šešis mėnesius ir mano draugai vis dar klausia: na, kaip tau ten patinka? Gerai, patogu - taip. Tačiau yra kažkas, kas išskiria šį darbą iš kitų. Dirbau komandose, kurios buvo visiškai abejingos savo produktui, nežinojo ir nesuprato, kas yra jų vartotojai. Bet čia viskas kitaip. Čia jautiesi atsakingas už tai, ką darai. Kurdami funkciją, jūs iš dalies tampate jos savininku, dalyvaujate visuose produkto susitikimuose, susijusiuose su jūsų funkcionalumu, teikiate pasiūlymus ir patys priimate sprendimus. Pačiam gaminti produktą, kurį naudojate kasdien, yra labai šaunu, o kodo rašymas žmonėms, kurie tikriausiai tai supranta geriau nei jūs, yra tiesiog neįtikėtinas jausmas (be sarkazmo).

Po visų šių pakeitimų išleidimo sulaukėme teigiamų atsiliepimų ir tai buvo labai labai malonu. Tai įkvepia. Ačiū! Rašyk daugiau.

Leiskite jums priminti, kad po globalių kintamųjų nusprendėme pakeisti architektūrą ir priskirti tarpinio serverio sluoksnį į atskirą egzempliorių. „Dviejų mazgų“ architektūra jau buvo išleista viešo beta versijos testavimo forma. Dabar bet kas gali pereiti prie jo ir padėti mums tobulinti mobilųjį „Habr“. Tai viskas siandienai. Mielai atsakysiu į visus jūsų klausimus komentaruose.

Šaltinis: www.habr.com

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