Habri esiotsa arendaja logid: ümbertöötamine ja kajastamine

Habri esiotsa arendaja logid: ümbertöötamine ja kajastamine

Mind on alati huvitanud, kuidas Habr on seestpoolt üles ehitatud, kuidas on üles ehitatud töövoog, kuidas on üles ehitatud suhtlus, milliseid standardeid kasutatakse ja kuidas siin üldiselt kood kirjas on. Õnneks sain selle võimaluse, sest sattusin hiljuti habra tiimi. Mobiiliversiooni väikese ümbertegemise näitel püüan vastata küsimusele: mis tunne on siin eesliinil töötada? Saates: Node, Vue, Vuex ja SSR kastmega märkmetest isikliku kogemuse kohta Habris.

Esimene asi, mida pead arendusmeeskonna kohta teadma, on see, et oleme väikesed. Little on kolm esiosa, kaks taga ja tehniline edumaa Habr - Baxley. Seal on loomulikult ka testija, disainer, kolm Vadimi, imeluud, turundaja ja muud Bumburumid. Kuid Habri saitidel on ainult kuus otsest kaastöötajat. See on üsna haruldane – mitmemiljonilise vaatajaskonnaga projekt, mis väliselt paistab hiiglasliku ettevõttena, on tegelikult pigem hubane startup, millel on kõige lamedama organisatsiooniline struktuur.

Nagu paljud teised IT-ettevõtted, tunnustab Habr agiilseid ideid, CI tavasid ja see on kõik. Aga minu arvates areneb Habr kui toode pigem lainetena kui pidevalt. Nii et mitu spurti järjest kodeerime usinalt midagi, kujundame ja kujundame ümber, lõhume midagi ja parandame, lahendame pileteid ja loome uusi, astume rehale ja tulistame endale jalgu, et funktsioon lõpuks välja anda. tulevik. Ja siis saabub teatav tuulevaikus, ümberkujundamise periood, aeg teha seda, mis on kvadrandis "tähtis-mitte kiireloomuline".

Allpool käsitletakse just seda "hooajavälist" sprinti. Seekord hõlmas see Habri mobiiliversiooni ümberkujundamist. Üldiselt on ettevõttel sellele suured lootused ning tulevikus peaks see välja vahetama kogu Habri kehastuste loomaaia ning muutuma universaalseks platvormideüleseks lahenduseks. Ühel päeval on olemas adaptiivne paigutus, PWA, võrguühenduseta režiim, kasutaja kohandamine ja palju muud huvitavat.

Paneme ülesande paika

Kord rääkis üks esirinnas tavalisel stand-up'il mobiiliversiooni kommentaaride komponendi arhitektuuri probleemidest. Selle ettepanekuga korraldasime grupipsühhoteraapia formaadis mikrokohtumise. Kõik rääkisid kordamööda, kus valus on, panid kõik paberile kirja, tundsid kaasa, said aru, ainult et keegi ei plaksutanud. Tulemuseks oli 20 probleemi loend, mis andis mõista, et mobiilsel Habril on eduni veel pikk ja okkaline tee.

Eelkõige muretsesin ressursitõhususe ja nn sujuva liidese pärast. Iga päev nägin marsruudil "kodu-töö-kodu" oma vana telefoni meeleheitlikult 20 pealkirja voos kuvamas. See nägi välja umbes selline:

Habri esiotsa arendaja logid: ümbertöötamine ja kajastamineMobile Habr liides enne refaktoreerimist

Mis siin toimub? Lühidalt öeldes teenindas server HTML-lehte kõigile ühtemoodi, sõltumata sellest, kas kasutaja oli sisse logitud või mitte. Seejärel laaditakse klient JS ja küsib uuesti vajalikke andmeid, kuid seekord on autoriseerimiseks kohandatud. See tähendab, et tegelikult tegime sama tööd kaks korda. Liides virvendas ja kasutaja laadis alla tubli sada kilobaiti. Detailides tundus kõik veelgi jubedam.

Habri esiotsa arendaja logid: ümbertöötamine ja kajastamineVana SSR-CSR skeem. Autoriseerimine on võimalik ainult etappides C3 ja C4, kui Node JS ei ole hõivatud HTML-i genereerimisega ja saab API-le puhverserveri taotlusi esitada.

Meie tolleaegset arhitektuuri kirjeldas väga täpselt üks Habri kasutajatest:

Mobiiliversioon on jama. Ma räägin seda nii, nagu see on. SSR-i ja CSR-i kohutav kombinatsioon.

Olime sunnitud seda tunnistama, ükskõik kui kurb see ka polnud.

Hindasin võimalusi, lõin Jiras pileti, mille kirjeldus oli tasemel “see on nüüd halb, tee kõik korda” ja lahkasin ülesande laias laastus:

  • taaskasutada andmeid,
  • minimeerida uuesti joonistuste arvu,
  • kõrvaldada dubleerivad taotlused,
  • muuta laadimisprotsess ilmsemaks.

Kasutame andmeid uuesti

Teoreetiliselt on serveripoolne renderdamine mõeldud kahe probleemi lahendamiseks: mitte kannatama otsingumootori piirangute tõttu. SPA indekseerimine ja parandada mõõdikuid FMP (paratamatult halveneb TTI). Klassikalises stsenaariumis, et lõpuks sõnastatud Airbnb-s 2013. aastal aastal (tagasi saidil Backbone.js), on SSR sama isomorfne JS-i rakendus, mis töötab Node keskkonnas. Server lihtsalt tagastab loodud paigutuse vastusena päringule. Seejärel toimub kliendi poolel rehüdratsioon ja seejärel toimib kõik ilma lehekülge uuesti laadimata. Habri jaoks, nagu ka paljude teiste tekstisisu sisaldavate ressursside puhul, on serveri renderdamine otsingumootoritega sõbralike suhete loomisel kriitiline element.

Hoolimata asjaolust, et tehnoloogia ilmumisest on möödunud üle kuue aasta ja selle aja jooksul on esiotsa maailmas silla alt läbi käinud palju vett, on paljude arendajate jaoks see idee endiselt saladuskatte all. Me ei jäänud kõrvale ja juurutasime SSR-i toega Vue rakenduse tootmisse, jättes puudu ühe väikese detaili: me ei edastanud kliendile algolekut.

Miks? Sellele küsimusele pole täpset vastust. Nad kas ei tahtnud serveri vastuse suurust suurendada või paljude muude arhitektuuriprobleemide tõttu või see lihtsalt ei tõusnud. Nii või teisiti tundub oleku väljaviskamine ja kõige serveri taaskasutamine üsna asjakohane ja kasulik. Ülesanne on tegelikult triviaalne. olek lihtsalt süstitakse täitmiskonteksti ja Vue lisab selle automaatselt genereeritud paigutusele globaalse muutujana: window.__INITIAL_STATE__.

Üks esilekerkinud probleeme on suutmatus teisendada tsüklilisi struktuure JSON-iks (ringviide); lahendati lihtsalt asendades sellised struktuurid nende lamedate kolleegidega.

Lisaks peaksite UGC-sisu käsitlemisel meeles pidama, et andmed tuleks teisendada HTML-i olemiteks, et HTML-i mitte rikkuda. Nendel eesmärkidel kasutame he.

Ümberjoonistamise minimeerimine

Nagu ülaltoodud diagrammil näha, täidab meie puhul üks Node JS-i eksemplar kahte funktsiooni: SSR ja API-s "puhverserver", kus toimub kasutaja autoriseerimine. See asjaolu muudab JS-koodi serveris töötamise ajal autoriseerimise võimatuks, kuna sõlm on ühe lõimega ja SSR-funktsioon on sünkroonne. See tähendab, et server lihtsalt ei saa endale päringuid saata, kui kõnepinn on millegagi hõivatud. Selgus, et värskendasime olekut, kuid liides ei lõpetanud tõmblemist, kuna kliendi andmeid tuli värskendada, võttes arvesse kasutaja seanssi. Oli vaja õpetada meie rakendust õigeid andmeid algolekusse panema, võttes arvesse kasutaja sisselogimist.

Probleemile oli ainult kaks lahendust:

  • linkida autoriseerimisandmed serveriüleste päringutega;
  • jagage Node JS kihid kaheks eraldi eksemplariks.

Esimene lahendus eeldas globaalsete muutujate kasutamist serveris ja teine ​​pikendas ülesande täitmise ajaraami vähemalt kuu võrra.

Kuidas teha valikut? Habr liigub sageli mööda kergema vastupanu teed. Mitteametlikult on üldine soov viia tsükkel ideest prototüübini miinimumini. Tootesse suhtumise mudel meenutab mõneti booking.com-i postulaate, ainsa erinevusega, et Habr suhtub kasutajate tagasisidesse palju tõsisemalt ja usaldab sellised otsused sinu kui arendaja teha.

Järgides seda loogikat ja enda soovi probleem kiiresti lahendada, valisin globaalsed muutujad. Ja nagu sageli juhtub, peate varem või hiljem nende eest maksma. Maksime peaaegu kohe: töötasime nädalavahetusel, klaarisime tagajärgi, kirjutasime surmajärgne ja hakkas serverit kaheks osaks jagama. Viga oli väga rumal ja sellega seotud viga ei olnud lihtne reprodutseerida. Ja jah, sellest on kahju, aga nii või teisiti, komistades ja ägades, läks mu globaalsete muutujatega PoC siiski tootmisse ja töötab üsna edukalt, oodates uuele “kahesõlme” arhitektuurile üleminekut. See oli oluline samm, sest formaalselt sai eesmärk täidetud – SSR õppis tarnima täiesti kasutusvalmis lehte ning kasutajaliides muutus palju rahulikumaks.

Habri esiotsa arendaja logid: ümbertöötamine ja kajastamineMobile Habri liides pärast refaktoreerimise esimest etappi

Lõppkokkuvõttes annab mobiiliversiooni SSR-CSR arhitektuur järgmise pildi:

Habri esiotsa arendaja logid: ümbertöötamine ja kajastamine"Kahe sõlmega" SSR-CSR ahel. Node JS API on alati asünkroonseks sisendiks/väljundiks valmis ja SSR-funktsioon seda ei blokeeri, kuna viimane asub eraldi eksemplaris. Päringuahelat nr 3 pole vaja.

Duplikaattaotluste kõrvaldamine

Pärast manipulatsioonide sooritamist lehe esialgne renderdamine enam epilepsiat ei kutsunud esile. Aga Habri edasine kasutamine SPA režiimis tekitas ikka segadust.

Kuna kasutajavoo aluseks on vormi üleminekud artiklite loend → artikkel → kommentaarid ja vastupidi, esmajoones oli oluline optimeerida selle ahela ressursitarbimist.

Habri esiotsa arendaja logid: ümbertöötamine ja kajastaminePostitusvoo juurde naasmine käivitab uue andmepäringu

Sügavalt kaevama polnud vaja. Ülalolevas ekraanisaates on näha, et rakendus küsib tagasi libistades uuesti artiklite nimekirja ning päringu ajal me artikleid ei näe, mis tähendab, et varasemad andmed kaovad kuhugi. Näib, et artikliloendi komponent kasutab kohalikku olekut ja kaotab selle hävitamiseks. Tegelikult kasutas rakendus globaalset olekut, kuid Vuexi arhitektuur ehitati üles: moodulid on seotud lehtedega, mis omakorda on seotud marsruutidega. Lisaks on kõik moodulid "ühekordsed" - iga järgnev lehe külastus kirjutas kogu mooduli ümber:

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

Kokku oli meil moodul Artiklite loend, mis sisaldab tüüpi objekte Artikkel ja moodul LehekülgArtikkel, mis oli objekti laiendatud versioon Artikkel, midagi sarnast Artikkel täis. Üldiselt ei sisalda see teostus iseenesest midagi kohutavat - see on väga lihtne, võib isegi öelda, et naiivne, kuid äärmiselt arusaadav. Kui lähtestate mooduli iga kord, kui muudate marsruuti, saate sellega isegi elada. Küll aga näiteks üleminek artiklite voogude vahel /feed → /all, viskate kindlasti minema kõik, mis on seotud teie isikliku söödaga, kuna meil on ainult üks Artiklite loend, millesse peate sisestama uued andmed. See viib meid taas taotluste dubleerimiseni.

Olles kogunud kõik, mis mul õnnestus sellel teemal välja kaevata, sõnastasin uue riigistruktuuri ja tutvustasin seda oma kolleegidele. Arutelud olid pikad, kuid lõpuks kaalusid pooltargumendid kahtlused üles ja asusin ellu viima.

Otsuse loogika avaldub kõige paremini kahes etapis. Esmalt proovime Vuexi mooduli lehtedest lahti siduda ja otse marsruutidega siduda. Jah, poes on natuke rohkem andmeid, hankijad muutuvad veidi keerukamaks, kuid me ei laadi artikleid kaks korda. Mobiiliversiooni puhul on see ehk tugevaim argument. See näeb välja umbes selline:

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

Aga mis siis, kui artiklite loendid võivad mitme marsruudi vahel kattuda ja mis siis, kui soovime objekti andmeid uuesti kasutada Artikkel postituse lehe renderdamiseks, muutes selle järgmiseks Artikkel täis? Sel juhul oleks loogilisem kasutada sellist struktuuri:

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

Artiklite loend siin on lihtsalt omamoodi artiklite hoidla. Kõik artiklid, mis kasutaja seansi ajal alla laaditi. Suhtume neisse ülima ettevaatusega, sest tegemist on liiklusega, mis võis olla kuskil metroos jaamade vahel koormatud ja kindlasti ei taha me kasutajale seda valu uuesti tekitada, sundides teda laadima andmeid, mille ta on juba alla laadinud. . Objekt Artiklite ID-d on lihtsalt objektide ID-de massiiv (nagu "lingid"). Artikkel. See struktuur võimaldab vältida marsruutidele ühiste andmete dubleerimist ja objekti taaskasutamist Artikkel postituslehe renderdamisel, liites sinna laiendatud andmed.

Läbipaistvamaks on muutunud ka artiklite loendi väljund: iteraatori komponent itereerib läbi massiivi artiklite ID-dega ja joonistab artiklite tiiseri komponendi, edastades ID rekvisiidina ning alamkomponent omakorda hangib vajalikud andmed Artiklite loend. Kui lähete avaldamislehele, leiame olemasoleva kuupäeva alates Artiklite loend, teeme päringu puuduvate andmete saamiseks ja lisame need lihtsalt olemasolevale objektile.

Miks see lähenemine parem on? Nagu ma eespool kirjutasin, on see lähenemisviis allalaaditud andmete suhtes ettevaatlikum ja võimaldab teil neid uuesti kasutada. Kuid lisaks sellele avab see tee uutele võimalustele, mis sobivad ideaalselt sellisesse arhitektuuri. Näiteks küsitlemine ja artiklite laadimine voogu nende ilmumisel. Viimased postitused saame lihtsalt salvestusruumi panna Artiklite loend, salvestage uutest ID-dest eraldi loend Artiklite ID-d ja teavitage sellest kasutajat. Kui klõpsame nupul „Näita uusi väljaandeid”, lisame lihtsalt praeguse artiklite loendi massiivi algusesse uued ID-d ja kõik töötab peaaegu võluväel.

Tee allalaadimine nauditavamaks

Kirsiks ümbertöötlemise tordil on skelettide kontseptsioon, mis muudab aeglases Internetis sisu laadimise protsessi pisut vähem masentavaks. Sellel teemal arutelusid ei toimunud, tee ideest prototüübini võttis sõna otseses mõttes kaks tundi. Kujundus joonistas praktiliselt ise ja me õpetasime oma komponente andmeid oodates renderdama lihtsaid, vaevu vilkuvaid div-plokke. Subjektiivselt vähendab selline laadimisviis tegelikult stressihormoonide hulka kasutaja kehas. Skelett näeb välja selline:

Habri esiotsa arendaja logid: ümbertöötamine ja kajastamine
Habraloading

Peegeldav

Olen kuus kuud Habris töötanud ja sõbrad ikka küsivad: no kuidas sulle seal meeldib? Olgu, mugav - jah. Kuid on midagi, mis eristab seda tööd teistest. Töötasin meeskondades, kes suhtusid oma tootesse täiesti ükskõikselt, ei teadnud ega mõistnud, kes on nende kasutajad. Kuid siin on kõik teisiti. Siin tunnete vastutust selle eest, mida teete. Funktsiooni arendamise käigus saate osaliselt selle omanikuks, osalete kõikidel teie funktsionaalsusega seotud tootekoosolekutel, teete ise ettepanekuid ja otsuseid. Ise igapäevaselt kasutatava toote valmistamine on väga lahe ja koodi kirjutamine inimestele, kes sellest ilmselt sinust paremini aru saavad, on lihtsalt uskumatu tunne (ilma sarkasmita).

Pärast kõigi nende muudatuste avaldamist saime positiivset tagasisidet ja see oli väga-väga tore. See on inspireeriv. Aitäh! Kirjuta veel.

Lubage mul teile meelde tuletada, et pärast globaalseid muutujaid otsustasime muuta arhitektuuri ja eraldada puhverserveri kiht eraldi eksemplari. "Kahe sõlme" arhitektuur on juba avaliku beetatestimise vormis avaldatud. Nüüd saab igaüks sellele lülituda ja aidata meil mobiilset Habrit paremaks muuta. See on tänaseks kõik. Vastan hea meelega kõigile teie küsimustele kommentaarides.

Allikas: www.habr.com

Lisa kommentaar