Habr front-end garatzaileen erregistroak: birfactorizazioa eta hausnarketa

Habr front-end garatzaileen erregistroak: birfactorizazioa eta hausnarketa

Betidanik interesatu izan zait Habr barrutik nola egituratzen den, lan-fluxua nola egituratzen den, komunikazioak nola egituratzen diren, zer estandar erabiltzen diren eta kodea nola idazten den orokorrean hemen. Zorionez, halako aukera bat izan nuen, duela gutxi habra taldean sartu nintzelako. Mugikorren bertsioaren refactoring txiki baten adibidea erabiliz, galdera honi erantzuten saiatuko naiz: zer den hemen aurrealdean lan egitea. Programan: Node, Vue, Vuex eta SSR Habr-en esperientzia pertsonalari buruzko oharren saltsarekin.

Garapen-taldeari buruz jakin behar duzun lehenengo gauza gutxi garela da. Ez da nahikoa - hiru aurrealde, bi atzelari eta Habr guztien lider teknikoa dira - Baxley. Badira, noski, probatzaile bat, diseinatzaile bat, hiru Vadim, erratza miragarri bat, marketin espezialista eta beste Bumburum batzuk ere. Baina Habr-en iturrietan sei kolaboratzaile zuzen baino ez daude. Hau nahiko arraroa da: milioi askoko publikoa duen proiektu bat, kanpotik enpresa erraldoi baten itxura duena, errealitatean ahalik eta antolakuntza-egiturarik laueneko startup erosoa dirudiena.

Beste informatika-enpresa askok bezala, Habr-ek Agile ideiak, CI praktikak aldarrikatzen ditu, eta hori da guztia. Baina nire sentimenduen arabera, Habr produktu gisa gehiago uhinetan garatzen ari da etengabe baino. Beraz, jarraian hainbat sprint egiteko, arretaz kodetzen dugu zerbait, diseinatzen eta birdiseinatzen dugu, zerbait apurtu eta konpondu, sarrerak konpondu eta berriak sortzen ditugu, arraste bat zapaldu eta oinetan tiro egiten dugu, azkenik funtzioa kaleratzeko. ekoizpena. Eta badator nolabaiteko barealdi bat, birmoldaketa aldi bat, β€œgarrantzitsu-ez premiazko” koadrantean dagoena egiteko garaia.

Hain zuzen ere, "denboraldiz kanpoko" esprint hori da jarraian eztabaidatuko dena. Oraingoan Habr-en mugikorren bertsioaren birfactorizazioa sartu zen. Oro har, konpainiak itxaropen handiak ditu, eta etorkizunean Habr-en enkarnazioen zoo osoa ordezkatu beharko luke eta plataforma anitzeko irtenbide unibertsala bihurtu beharko luke. Noizbait diseinu moldagarria, PWA, lineaz kanpoko modua, erabiltzaileen pertsonalizazioa eta beste gauza interesgarri asko egongo dira.

Ezar dezagun zeregina

Behin, stand-up arrunt batean, aurrealdeko batek mugikorreko bertsioaren iruzkinen osagaiaren arkitekturako arazoei buruz hitz egin zuen. Gauzak horrela, talde psikoterapia formatuan mikrotopaketa bat antolatu genuen. Denek txandaka esaten zuten non egiten zuen minik, dena paperean grabatu zuten, sinpatia egiten zuten, ulertzen zuten, inork txalorik egiten ez zuela izan ezik. Emaitza 20 arazoren zerrenda bat izan zen, eta horrek argi utzi zuen Habr mugikorrak oraindik arrakastarako bide luze eta arantzatsua zuela.

Batez ere baliabideen erabileraren eraginkortasunaz eta interfaze leuna deitzen denak kezkatzen ninduen. Egunero, etxe-lana-etxeko ibilbidean, nire telefono zaharra jarioan 20 titular bistaratzen saiatzen ari zela ikusten nuen. Honelako itxura zuen:

Habr front-end garatzaileen erregistroak: birfactorizazioa eta hausnarketaMugikorra Habr interfazea birfactorizatu aurretik

Zer gertatzen da hemen? Laburbilduz, zerbitzariak modu berean zerbitzatzen zien HTML orria guztiei, erabiltzailea saioa hasita zegoen ala ez kontuan hartu gabe. Ondoren, JS bezeroa kargatzen da eta beharrezkoak diren datuak berriro eskatzen ditu, baina baimentzeko egokituta. Hau da, benetan bi aldiz egin genuen lan bera. Interfazeak keinu egin zuen, eta erabiltzaileak ehun kilobyte gehigarri deskargatu zituen. Xehetasunez dena are beldurgarriagoa zen.

Habr front-end garatzaileen erregistroak: birfactorizazioa eta hausnarketaSSR-CSR eskema zaharra. Baimena C3 eta C4 etapetan bakarrik da posible, Node JS HTMLa sortzen lanpetuta ez dagoenean eta APIra eskaerak proxy ditzakeenean.

Garai hartako gure arkitektura oso zehatz deskribatu zuen Habr-eko erabiltzaileetako batek:

Mugikorreko bertsioa kaskarra da. den bezala esaten ari naiz. SSR eta CSR konbinazio izugarria.

Aitortu behar izan genuen, tristea izan arren.

Aukerak baloratu, Jira-n txartel bat sortu nuen "orain txarto dago, ondo egin" mailan deskribapen batekin eta zeregina modu zabalean deskonposatu nuen:

  • datuak berrerabili,
  • murrizketa kopurua murriztea,
  • ezabatu eskaera bikoiztuak,
  • kargatzeko prozesua agerikoagoa izatea.

Berrerabili ditzagun datuak

Teorian, zerbitzariaren errendatzea bi arazo konpontzeko diseinatuta dago: bilatzaileen mugak ez jasateko. SPA indexatzea eta metrika hobetu FMP (ezinbestean okerrera egiten du TTI). Eszenatoki klasiko batean hori azkenean 2013an Airbnb-en formulatua urtean (oraindik Backbone.js-en), SSR Node ingurunean exekutatzen den JS isomorfiko aplikazio bera da. Zerbitzariak sortutako diseinua besterik gabe bidaltzen du eskaeraren erantzun gisa. Ondoren, rehidratazioa bezeroaren aldetik gertatzen da, eta gero dena funtzionatzen du orrialdeak birkargatu gabe. Habr-entzat, testu-edukia duten beste baliabide askorentzat bezala, zerbitzarien errendatzea elementu kritikoa da bilatzaileekin harreman adiskidetsuak eraikitzeko.

Teknologiaren etorreratik sei urte baino gehiago igaro diren arren, eta denbora horretan ur asko benetan zubiaren azpian hegan egin den front-end munduan, garatzaile askorentzat ideia hau sekretupean dago oraindik. Ez genuen alde batera utzi eta SSR euskarria duen Vue aplikazio bat zabaldu genuen produkziorako, xehetasun txiki bat falta zitzaigun: ez genion hasierako egoera bezeroari bidali.

Zergatik? Ez dago galdera honi erantzun zehatzik. Edo ez zuten zerbitzariaren erantzunaren tamaina handitu nahi, edo beste arazo arkitektoniko mordo batengatik, edo besterik gabe ez zen hartu. Nola edo hala, egoera botatzea eta zerbitzariak egin zuen guztia berrerabiltzea nahiko egokia eta erabilgarria dirudi. Zeregin hutsala da benetan - egoera besterik gabe injektatzen da exekuzio-testuinguruan sartu, eta Vuek automatikoki gehitzen dio sortutako diseinuari aldagai global gisa: window.__INITIAL_STATE__.

Sortu den arazoetako bat egitura ziklikoak JSON bihurtzeko ezintasuna da (erreferentzia zirkularra); horrelako egiturak euren pareko lauekin ordezkatuz konpondu zen.

Horrez gain, UGC edukia tratatzerakoan, gogoratu behar duzu datuak HTML entitateetara bihurtu behar direla HTMLa ez apurtzeko. Helburu horietarako erabiltzen dugu he.

Birmarrazketak gutxitzea

Goiko diagraman ikus dezakezun bezala, gure kasuan, Node JS instantzia batek bi funtzio betetzen ditu: SSR eta "proxy" APIan, non erabiltzaileen baimena gertatzen den. Zirkunstantzia honek ezinezkoa egiten du JS kodea zerbitzarian exekutatzen ari den bitartean baimentzea, nodoa hari bakarrekoa baita eta SSR funtzioa sinkronoa baita. Hau da, zerbitzariak ezin du bere buruari eskaerak bidali dei-pila zerbaitekin okupatuta dagoen bitartean. Egoera eguneratu genuen, baina interfazeak ez zuen geldirik gelditu, bezeroaren datuak eguneratu behar baitziren erabiltzailearen saioa kontuan hartuta. Gure aplikazioari datu zuzenak hasierako egoeran jartzen irakatsi behar genion, erabiltzailearen saioa kontuan hartuta.

Arazoari bi irtenbide baino ez zeuden:

  • erantsi baimen-datuak zerbitzarien arteko eskaerei;
  • zatitu Node JS geruzak bi instantzia ezberdinetan.

Lehenengo irtenbideak zerbitzarian aldagai globalak erabiltzea eskatzen zuen, eta bigarrenak zeregina betetzeko epea gutxienez hilabetez luzatu zuen.

Nola egin aukeraketa? Habr askotan erresistentzia gutxieneko bidetik mugitzen da. Informalki, ideiatik prototiporako zikloa gutxienera murrizteko nahi orokorra dago. Produktuarekiko jarrera-ereduak zertxobait gogorarazten ditu booking.com-en postulatuak, eta desberdintasun bakarra da Habr-ek erabiltzaileen iritzia askoz serioago hartzen duela eta zuregan konfiantza duela, garatzaile gisa, horrelako erabakiak hartzeko.

Logika honi eta arazoa azkar konpontzeko nire nahiari jarraituz, aldagai globalak aukeratu nituen. Eta, askotan gertatzen den bezala, lehenago edo beranduago ordaindu behar dituzu. Ia berehala ordaindu genuen: asteburuan lan egin, ondorioak argitu, idatzi postmortem eta zerbitzaria bi zatitan banatzen hasi zen. Errorea oso ergela izan zen, eta akatsa ez zen erreproduzitzen erraza. Eta bai, pena da hau, baina nola edo hala, estropezuka eta intzirika, nire PoC aldagai globalekin, hala ere, produkzioan sartu zen eta nahiko arrakastatsuan ari da "bi nodo" arkitektura berrira pasatzeko zain dagoen bitartean. Urrats garrantzitsua izan zen, formalki helburua lortu zelako - SSR-k guztiz erabiltzeko prest dagoen orria ematen ikasi zuen eta UI-a askoz lasaiago bihurtu zen.

Habr front-end garatzaileen erregistroak: birfactorizazioa eta hausnarketaHabr mugikorren interfazea birfactorizazioaren lehen fasearen ondoren

Azken finean, mugikorreko bertsioaren SSR-CSR arkitekturak argazki honetara eramaten du:

οΏΌHabr front-end garatzaileen erregistroak: birfactorizazioa eta hausnarketa"Bi nodo" SSR-CSR zirkuitua. Node JS APIa beti dago prest I/O asinkronoetarako eta SSR funtzioak ez du blokeatzen, azken hau instantzia bereizi batean baitago. Ez da beharrezkoa 3. kontsulta-katea.

Eskaera bikoiztuak ezabatzea

Manipulazioak egin ondoren, orrialdearen hasierako errendatzeak ez zuen gehiago epilepsia eragin. Baina SPA moduan Habr gehiago erabiltzeak nahasmena eragin zuen oraindik.

Erabiltzaile-fluxuaren oinarria inprimakiaren trantsizioak direnez artikuluen zerrenda β†’ artikulua β†’ iruzkinak eta alderantziz, lehenik eta behin kate horren baliabideen kontsumoa optimizatzea garrantzitsua zen.

Habr front-end garatzaileen erregistroak: birfactorizazioa eta hausnarketaArgitalpen-jariora itzultzeak datu-eskaera berri bat eragiten du

Ez zegoen sakondu beharrik. Goiko screencast-ean ikus dezakezu aplikazioak berriro eskatzen duela artikulu-zerrenda atzera egitean, eta eskaeran zehar ez ditugu artikuluak ikusten, hau da, aurreko datuak nonbait desagertzen direla esan nahi du. Badirudi artikulu zerrendaren osagaiak tokiko egoera erabiltzen duela eta suntsitzean galtzen duela. Izan ere, aplikazioak egoera globala erabiltzen zuen, baina Vuex arkitektura buru-belarri eraiki zen: moduluak orriei lotuta daude, eta, aldi berean, ibilbideei lotuta daude. Gainera, modulu guztiak "botagarriak" dira - orrialdera egindako bisita bakoitzak modulu osoa berridatzi zuen:

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

Guztira, modulu bat genuen Artikuluen zerrenda, motako objektuak dituena Artikuluan eta modulua OrrialdeaArtikulua, objektuaren bertsio hedatua zen Artikuluan, modukoa Artikulu osoa. Orokorrean, inplementazio honek ez du ezer ikaragarririk darama berez - oso erraza da, inozoa ere esan liteke, baina oso ulergarria. Ibilbidea aldatzen duzun bakoitzean modulua berrezartzen baduzu, horrekin ere bizi zaitezke. Hala ere, artikulu-jarioen artean mugitzea, adibidez /feed β†’ /guztia, jario pertsonalarekin zerikusia duen guztia botatzea bermatuta dago, bakarra baitugu Artikuluen zerrenda, eta bertan datu berriak jarri behar dituzu. Horrek berriro ere eskaerak bikoiztera garamatza.

Gaiari buruz argitu ahal izan dudan guztia bilduta, estatu egitura berri bat formulatu eta nire lankideei aurkeztu nien. Eztabaidak luzeak izan ziren, baina azkenean aldeko argudioek zalantzak gainditzen zituzten, eta gauzatzen hasi nintzen.

Soluzio baten logika bi urratsetan azaltzen da onena. Lehenik Vuex modulua orrietatik desakoplatzen eta ibilbideetara zuzenean lotzen saiatzen gara. Bai, dendan datu apur bat gehiago egongo da, getters pixka bat konplexuagoa izango da, baina ez ditugu bi aldiz kargatuko artikuluak. Mugikorrerako bertsiorako, hau da agian argudiorik indartsuena. Honelako itxura izango du:

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

Baina zer gertatzen da artikulu-zerrendak hainbat bideren artean gainjar daitezkeen eta objektuen datuak berrerabili nahi baditugu Artikuluan argitalpen orria errendatzeko, bihurtuz Artikulu osoa? Kasu honetan, logikoagoa litzateke egitura hori erabiltzea:

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

Artikuluen zerrenda hemen artikuluen biltegi moduko bat besterik ez da. Erabiltzailearen saioan deskargatu diren artikulu guztiak. Arreta handiz tratatzen ditugu, geltokien arteko metroan minaren ondorioz deskargatu daitekeen trafikoa delako, eta, zalantzarik gabe, ez diogu min hori berriro eragin nahi erabiltzaileari, dagoeneko dituen datuak kargatzera behartuz. deskargatu. Objektu bat ArtikuluenId objektuekiko ID-sorta bat besterik ez da (Β«estekaΒ» balitz bezala). Artikuluan. Egitura honek ibilbideetan ohikoak diren datuak bikoiztea eta objektua berrerabiltzea saihesteko aukera ematen du Artikuluan argitalpen-orri bat errendatzean datu hedatuak bertan batuz.

Artikuluen zerrendaren irteera ere gardenagoa bihurtu da: iteratzailea osagaiak array-n zehar itertzen du artikulu-IDekin eta artikulu-zigorra osagaia marrazten du, Id-a apropos gisa pasatuz, eta haurren osagaiak, aldi berean, beharrezko datuak berreskuratzen ditu. Artikuluen zerrenda. Argitalpen orrira zoazenean, lehendik dagoen data jasotzen dugu Artikuluen zerrenda, falta diren datuak lortzeko eskaera egiten dugu eta besterik gabe lehendik dagoen objektuari gehitzen diogu.

Zergatik da hobea planteamendu hau? Goian idatzi dudan bezala, ikuspegi hau leunagoa da deskargatutako datuei dagokienez eta berrerabiltzeko aukera ematen du. Baina honetaz gain, halako arkitektura batean ezin hobeto egokitzen diren aukera berri batzuei bidea irekitzen die. Adibidez, bozketa eta artikuluak jarioan kargatzea, agertzen diren heinean. Besterik gabe, azken mezuak "biltegiratze" batean jar ditzakegu Artikuluen zerrenda, gorde ID berrien zerrenda bereizi batean ArtikuluenId eta erabiltzaileari horren berri eman. "Erakutsi argitalpen berriak" botoian klik egiten dugunean, ID berriak txertatuko ditugu uneko artikulu-zerrendaren matrizearen hasieran eta dena ia magikoki funtzionatuko du.

Deskargatzea atseginagoa eginez

Refactoring pastelaren gizena eskeletoen kontzeptua da, eta horrek Internet geldoan edukia deskargatzeko prozesua apur bat nazkagarriagoa bihurtzen du. Ez zen gai honi buruzko eztabaidarik izan; ideiatik prototiporako bidea literalki bi ordu behar izan zuen. Diseinuak ia bere burua marraztu zuen, eta gure osagaiak div-bloke sinpleak eta apenas keinuka egiten irakatsi genien datuen zain bitartean. Subjektiboki, kargatzeko ikuspegi honek erabiltzailearen gorputzeko estres hormona kopurua murrizten du. Hezurdurak honela dauka:

Habr front-end garatzaileen erregistroak: birfactorizazioa eta hausnarketa
Habraloading

Hausnartzen

Sei hilabete daramatzat HabrΓ©n lanean eta nire lagunek oraindik galdetzen dute: ba, nola gustatzen zaizu han? Ados, eroso - bai. Baina bada lan hau besteengandik ezberdintzen duen zerbait. Beren produktuarekiko guztiz axolagabeak ziren taldeetan lan egin nuen, ez zekiten edo ulertzen ez zuten erabiltzaileak nor ziren. Baina hemen dena ezberdina da. Hemen egiten duzunaren ardura sentitzen zara. Ezaugarri bat garatzeko prozesuan, partzialki haren jabe bihurtzen zara, zure funtzionaltasunarekin lotutako produktuen bilera guztietan parte hartzen duzu, iradokizunak egiten dituzu eta erabakiak hartzen dituzu. Egunero erabiltzen duzun produktu bat egitea oso polita da, baina ziurrenik zu baino hobeak diren pertsonentzako kodea idaztea izugarrizko sentsazioa da (sarkasmorik ez).

Aldaketa hauek guztiak kaleratu ostean, iritzi positiboak jaso genituen, eta oso-oso polita izan zen. Inspiratzen da. Eskerrik asko! Gehiago idatzi.

Gogorarazten dizut aldagai globalen ondoren arkitektura aldatzea eta proxy geruza instantzia bereizi batean esleitzea erabaki genuela. "Bi nodoko" arkitektura beta proba publiko moduan kaleratu da dagoeneko. Orain edonork horretara aldatu eta Habr mugikorra hobetzen lagundu gaitzake. Hori da dena gaurko. Pozik erantzungo ditut zure galdera guztiak iruzkinetan.

Iturria: www.habr.com

Gehitu iruzkin berria