Habr priekÅ”gala izstrādātāju žurnāli: pārstrukturÄ“Å”ana un atspoguļoÅ”ana

Habr priekÅ”gala izstrādātāju žurnāli: pārstrukturÄ“Å”ana un atspoguļoÅ”ana

Mani vienmēr ir interesējis, kā Habr ir strukturēts no iekÅ”puses, kā tiek strukturēta darbplÅ«sma, kā tiek strukturētas komunikācijas, kādi standarti tiek izmantoti un kā Å”eit parasti tiek rakstÄ«ts kods. Par laimi, man radās Ŕāda iespēja, jo nesen kļuvu par habras komandu. Izmantojot nelielu mobilās versijas pārveidoÅ”anas piemēru, es mēģināŔu atbildēt uz jautājumu: kā ir strādāt Å”eit, priekŔā. Programmā: Node, Vue, Vuex un SSR ar mērci no piezÄ«mēm par personÄ«go pieredzi Habr.

Pirmā lieta, kas jums jāzina par izstrādes komandu, ir tas, ka mÅ«su ir maz. Nepietiek ā€“ tās ir trÄ«s frontes, divas aizmugures un visa Habr ā€“ Bakslija tehniskais pārsvars. Ir, protams, arÄ« testētājs, dizainers, trÄ«s Vadimi, brÄ«numslota, mārketinga speciālists un citi Bumburi. Taču Habra avotiem ir tikai seÅ”i tieÅ”ie lÄ«dzstrādnieki. Tas notiek diezgan reti ā€“ projekts ar vairāku miljonu dolāru auditoriju, kas no malas izskatās pēc milzu uzņēmuma, patiesÄ«bā vairāk izskatās pēc omulÄ«ga startapa ar iespējami plakanāko organizatorisko struktÅ«ru.

Tāpat kā daudzi citi IT uzņēmumi, Habr piedāvā Agile idejas, CI praksi, un tas arÄ« viss. Bet pēc manām sajÅ«tām Habr kā produkts attÄ«stās vairāk viļņveidÄ«gi nekā nepārtraukti. Tā nu vairākus sprintus pēc kārtas cÄ«tÄ«gi kaut ko kodējam, projektējam un pārprojektējam, kaut ko laužam un labojam, risinām biļetes un veidojam jaunas, kāpjam uz grābekļa un Å”aujam sev kājās, lai beidzot atbrÄ«votu funkciju ražoÅ”anu. Un tad iestājas zināms klusums, pārbÅ«ves periods, laiks darÄ«t to, kas atrodas kvadrantā ā€œsvarÄ«gi-nesteidzamiā€.

TieÅ”i Å”is ā€œnesezonasā€ sprints tiks apspriests tālāk. Å oreiz tas ietvēra Habr mobilās versijas pārveidoÅ”anu. Kopumā uzņēmums uz to saista lielas cerÄ«bas, un nākotnē tam vajadzētu aizstāt visu Habra iemiesojumu zoodārzu un kļūt par universālu starpplatformu risinājumu. Kādreiz bÅ«s adaptÄ«vais izkārtojums, PWA, bezsaistes režīms, lietotāja pielāgoÅ”ana un daudzas citas interesantas lietas.

Izvirzīsim uzdevumu

Reiz parastajā stendā viens no priekŔējiem runāja par problēmām mobilās versijas komentāru komponenta arhitektÅ«rā. Ņemot to vērā, organizējām mikrosanāksmi grupu psihoterapijas formātā. Visi pēc kārtas stāstÄ«ja, kur sāp, visu pierakstÄ«ja uz papÄ«ra, juta lÄ«dzi, saprata, izņemot to, ka neviens neaplaudēja. Rezultātā tika izveidots 20 problēmu saraksts, kas skaidri parādÄ«ja, ka mobilajam Habram joprojām ir garÅ” un sarežģīts ceļŔ uz panākumiem.

Mani galvenokārt uztrauca resursu izmantoÅ”anas efektivitāte un tas, ko sauc par vienmērÄ«gu saskarni. Katru dienu marÅ”rutā mājasā€“darbsā€“mājas redzēju, kā mans vecais tālrunis izmisÄ«gi mēģināja plÅ«smā parādÄ«t 20 virsrakstus. Tas izskatÄ«jās apmēram Ŕādi:

Habr priekÅ”gala izstrādātāju žurnāli: pārstrukturÄ“Å”ana un atspoguļoÅ”anaMobilā Habr saskarne pirms pārstrukturÄ“Å”anas

Kas Å”eit notiek? ÄŖsāk sakot, serveris visiem apkalpoja HTML lapu vienādi, neatkarÄ«gi no tā, vai lietotājs bija pieteicies vai nē. Pēc tam klients JS tiek ielādēts un vēlreiz pieprasa nepiecieÅ”amos datus, bet tiek pielāgots autorizācijai. Tas ir, mēs faktiski veicām vienu un to paÅ”u darbu divas reizes. Interfeiss mirgoja, un lietotājs lejupielādēja labu simtu papildu kilobaitu. Detaļās viss izskatÄ«jās vēl Å”ausmÄ«gāk.

Habr priekÅ”gala izstrādātāju žurnāli: pārstrukturÄ“Å”ana un atspoguļoÅ”anaVecā SSR-CSR shēma. Autorizācija ir iespējama tikai C3 un C4 posmos, kad mezgls JS nav aizņemts ar HTML Ä£enerÄ“Å”anu un var nosÅ«tÄ«t starpniekservera pieprasÄ«jumus API.

Mūsu tā laika arhitektūru ļoti precīzi aprakstīja viens no Habr lietotājiem:

Mobilā versija ir muļķīga. Es to saku tā, kā tas ir. Briesmīga SSR un KSA kombinācija.

Mums tas bija jāatzīst, lai cik skumji tas nebūtu.

Izvērtēju iespējas, izveidoju biļeti Jirā ar aprakstu lÄ«menÄ« ā€œtagad ir slikti, dari pareiziā€ un uzdevumu sadalÄ«ju lielos vilcienos:

  • atkārtoti izmantot datus,
  • samazināt pārzÄ«mÄ“Å”anas gadÄ«jumu skaitu,
  • novērst dublētus pieprasÄ«jumus,
  • padariet iekrauÅ”anas procesu skaidrāku.

Izmantosim datus atkārtoti

Teorētiski servera puses renderÄ“Å”ana ir paredzēta, lai atrisinātu divas problēmas: lai neciestu no meklētājprogrammu ierobežojumiem saistÄ«bā ar SPA indeksācija un uzlabot metriku FMP (neizbēgami pasliktinās TSI). Klasiskā scenārijā, ka beidzot formulēts Airbnb 2013. gadā gadā (joprojām vietnē Backbone.js), SSR ir tā pati izomorfā JS lietojumprogramma, kas darbojas Node vidē. Serveris vienkārÅ”i nosÅ«ta Ä£enerēto izkārtojumu kā atbildi uz pieprasÄ«jumu. Pēc tam klienta pusē notiek rehidratācija, un tad viss darbojas bez lapu atkārtotas ielādes. Habram, tāpat kā daudziem citiem teksta satura resursiem, servera renderÄ“Å”ana ir bÅ«tisks elements draudzÄ«gu attiecÄ«bu veidoÅ”anā ar meklētājprogrammām.

Neskatoties uz to, ka kopÅ” tehnoloÄ£ijas parādÄ«Å”anās ir pagājuÅ”i vairāk nekā seÅ”i gadi, un Å”ajā laikā front-end pasaulē zem tilta patieŔām ir aizlidojis daudz Å«dens, daudziem izstrādātājiem Ŕī ideja joprojām ir noslēpumains. Mēs nestāvējām malā un izlaidām Vue lietojumprogrammu ar SSR atbalstu ražoÅ”anai, pietrÅ«kstot vienas sÄ«kas detaļas: klientam nenosÅ«tÄ«jām sākotnējo stāvokli.

Kāpēc? Uz Å”o jautājumu nav precÄ«zas atbildes. Vai nu viņi nevēlējās palielināt servera atbildes lielumu, vai arÄ« daudzu citu arhitektÅ«ras problēmu dēļ, vai arÄ« tā vienkārÅ”i nepacēlās. Tā vai citādi izmest stāvokli un atkārtoti izmantot visu, ko darÄ«ja serveris, Ŕķiet diezgan piemēroti un noderÄ«gi. Uzdevums patiesÄ«bā ir triviāls - valsts vienkārÅ”i tiek injicēta izpildes kontekstā, un Vue automātiski pievieno to Ä£enerētajam izkārtojumam kā globālo mainÄ«go: window.__INITIAL_STATE__.

Viena no problēmām, kas raduŔās, ir nespēja pārveidot cikliskās struktÅ«ras par JSON (apļveida atsauce); tika atrisināts, vienkārÅ”i aizstājot Ŕādas konstrukcijas ar to plakanajām konstrukcijām.

Turklāt, strādājot ar UGC saturu, jums jāatceras, ka dati ir jāpārvērÅ” par HTML entÄ«tijām, lai nepārkāptu HTML. Å iem nolÅ«kiem mēs izmantojam he.

PārzÄ«mējumu samazināŔana lÄ«dz minimumam

Kā redzat no iepriekÅ” redzamās diagrammas, mÅ«su gadÄ«jumā viens Node JS gadÄ«jums veic divas funkcijas: SSR un ā€œstarpniekserverisā€ API, kur notiek lietotāja autorizācija. Å is apstāklis ā€‹ā€‹padara neiespējamu autorizāciju, kamēr JS kods darbojas serverÄ«, jo mezglam ir viens pavediens un SSR funkcija ir sinhrona. Tas nozÄ«mē, ka serveris vienkārÅ”i nevar nosÅ«tÄ«t pieprasÄ«jumus sev, kamēr zvanu steks ir ar kaut ko aizņemts. IzrādÄ«jās, ka mēs atjauninājām stāvokli, taču saskarne nepārstāja raustÄ«ties, jo klienta dati bija jāatjaunina, ņemot vērā lietotāja sesiju. Mums bija jāiemāca mÅ«su lietojumprogrammai ievietot pareizos datus sākotnējā stāvoklÄ«, ņemot vērā lietotāja pieteikÅ”anos.

Problēmai bija tikai divi risinājumi:

  • pievienot autorizācijas datus starpserveru pieprasÄ«jumiem;
  • sadalÄ«t Node JS slāņus divos atseviŔķos gadÄ«jumos.

Pirmais risinājums prasÄ«ja serverÄ« izmantot globālos mainÄ«gos, bet otrais uzdevuma izpildes termiņŔ pagarināja vismaz par mēnesi.

Kā izdarÄ«t izvēli? Habrs bieži pārvietojas pa mazākās pretestÄ«bas ceļu. Neformāli ir vispārēja vēlme ciklu no idejas lÄ«dz prototipam samazināt lÄ«dz minimumam. Attieksmes modelis pret produktu nedaudz atgādina booking.com postulātus, ar vienÄ«go atŔķirÄ«bu, ka Habrs daudz nopietnāk uztver lietotāju atsauksmes un uzticas jums kā izstrādātājam Ŕādu lēmumu pieņemÅ”anā.

Sekojot Å”ai loÄ£ikai un savai vēlmei ātri atrisināt problēmu, es izvēlējos globālos mainÄ«gos. Un, kā tas bieži notiek, jums par tiem agrāk vai vēlāk ir jāmaksā. GandrÄ«z uzreiz samaksājām: nedēļas nogalē strādājām, noskaidrojām sekas, rakstÄ«jām lÄ«Ä·a sekcija un sāka sadalÄ«t serveri divās daļās. Kļūda bija ļoti muļķīga, un ar to saistÄ«to kļūdu nebija viegli reproducēt. Un jā, par to ir žēl, taču tā vai citādi, klupdams un stenot, mans PoC ar globālajiem mainÄ«gajiem tomēr nonāca ražoÅ”anā un darbojas diezgan veiksmÄ«gi, gaidot pāreju uz jaunu ā€œdivu mezgluā€ arhitektÅ«ru. Tas bija nozÄ«mÄ«gs solis, jo formāli mērÄ·is tika sasniegts ā€“ SSR iemācÄ«jās piegādāt pilnÄ«bā lietoÅ”anai gatavu lapu, un lietotāja saskarne kļuva daudz mierÄ«gāka.

Habr priekÅ”gala izstrādātāju žurnāli: pārstrukturÄ“Å”ana un atspoguļoÅ”anaMobilā Habr saskarne pēc pirmā pārstrukturÄ“Å”anas posma

Galu galā mobilās versijas SSR-CSR arhitektÅ«ra noved pie Ŕāda attēla:

ļæ¼Habr priekÅ”gala izstrādātāju žurnāli: pārstrukturÄ“Å”ana un atspoguļoÅ”anaā€œDivu mezgluā€ SSR-CSR ķēde. Node JS API vienmēr ir gatavs asinhronai ievadei/izvadei, un SSR funkcija to nebloķē, jo tā atrodas atseviŔķā instancē. Vaicājuma ķēde #3 nav nepiecieÅ”ama.

Dublētu pieprasÄ«jumu novērÅ”ana

Pēc manipulāciju veikÅ”anas sākotnējā lapas atveidoÅ”ana vairs neizraisÄ«ja epilepsiju. Bet turpmākā Habr izmantoÅ”ana SPA režīmā tik un tā radÄ«ja neizpratni.

Tā kā lietotāju plÅ«smas pamatā ir formas pārejas rakstu saraksts ā†’ raksts ā†’ komentāri un otrādi, vispirms bija svarÄ«gi optimizēt Ŕīs ķēdes resursu patēriņu.

Habr priekÅ”gala izstrādātāju žurnāli: pārstrukturÄ“Å”ana un atspoguļoÅ”anaAtgrieÅ”anās pie ziņu plÅ«smas izraisa jaunu datu pieprasÄ«jumu

Nevajadzēja dziļi rakt. AugŔējā ekrānuzņēmumā var redzēt, ka, velkot atpakaļ, programma atkārtoti pieprasa rakstu sarakstu, un pieprasÄ«juma laikā mēs neredzam rakstus, kas nozÄ«mē, ka iepriekŔējie dati kaut kur pazÅ«d. Å Ä·iet, ka rakstu saraksta komponents izmanto vietējo stāvokli un zaudē to iznÄ«cināŔanas laikā. Faktiski lietojumprogramma izmantoja globālu stāvokli, bet Vuex arhitektÅ«ra tika veidota uz priekÅ”u: moduļi ir piesaistÄ«ti lapām, kuras savukārt ir saistÄ«tas ar marÅ”rutiem. Turklāt visi moduļi ir ā€œvienreiz lietojamiā€ - katrs nākamais lapas apmeklējums pārrakstÄ«ja visu moduli:

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

Kopumā mums bija modulis Rakstu saraksts, kurā ir tipa objekti Raksts un modulis LapaRaksts, kas bija objekta paplaÅ”ināta versija Raksts, it kā Raksts Pilns. Kopumā Ŕī realizācija pati par sevi nenes neko briesmÄ«gu - tā ir ļoti vienkārÅ”a, varētu pat teikt, naiva, bet ārkārtÄ«gi saprotama. Ja moduli atiestatÄ«siet katru reizi, kad maināt marÅ”rutu, tad jÅ«s pat varat dzÄ«vot ar to. Tomēr, piemēram, pārvietojoties starp rakstu plÅ«smām /feed ā†’ /all, tiek garantēts, ka izmetÄ«s visu, kas saistÄ«ts ar personÄ«go barÄ«bu, jo mums ir tikai viens Rakstu saraksts, kurā jāievieto jauni dati. Tas atkal noved pie pieprasÄ«jumu dublÄ“Å”anās.

Savācis visu, ko varēju izrakt par tēmu, formulēju jaunu valsts struktÅ«ru un iepazÄ«stināju ar to saviem kolēģiem. Diskusijas bija garas, taču galu galā argumenti par labu atsvēra Å”aubas, un es sāku Ä«stenot.

Risinājuma loÄ£iku vislabāk atklāj divos posmos. Vispirms mēs cenÅ”amies atsaistÄ«t Vuex moduli no lapām un saistÄ«t tieÅ”i ar marÅ”rutiem. Jā, veikalā bÅ«s nedaudz vairāk datu, getteri kļūs nedaudz sarežģītāki, bet rakstus divreiz neielādēsim. Mobilajai versijai tas, iespējams, ir spēcÄ«gākais arguments. Tas izskatÄ«sies apmēram Ŕādi:

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

Bet ko darÄ«t, ja rakstu saraksti var pārklāties starp vairākiem marÅ”rutiem un ja mēs vēlamies atkārtoti izmantot objektu datus Raksts lai renderētu ziņas lapu, pārvērÅ”ot to par Raksts Pilns? Å ajā gadÄ«jumā loÄ£iskāk bÅ«tu izmantot Ŕādu struktÅ«ru:

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

Rakstu saraksts Å”eit tā ir tikai sava veida rakstu krātuve. Visi raksti, kas tika lejupielādēti lietotāja sesijas laikā. Mēs pret tiem izturamies ar vislielāko piesardzÄ«bu, jo Ŕī ir satiksme, kas, iespējams, ir lejupielādēta sāpju dēļ kaut kur metro starp stacijām, un mēs noteikti nevēlamies atkārtoti izraisÄ«t Ŕīs sāpes lietotājam, piespiežot viņu ielādēt datus, kas viņam jau ir lejupielādēts. Objekts Rakstu ID ir vienkārÅ”i ID masÄ«vs (it kā ā€œsaitesā€) uz objektiem Raksts. Å Ä« struktÅ«ra ļauj izvairÄ«ties no marÅ”rutiem kopÄ«gu datu dublÄ“Å”anas un objekta atkārtotas izmantoÅ”anas Raksts renderējot ziņas lapu, apvienojot tajā paplaÅ”inātos datus.

ArÄ« rakstu saraksta izvade ir kļuvusi pārskatāmāka: iteratora komponents iterē cauri masÄ«vam ar rakstu ID un zÄ«mē raksta teaser komponentu, nododot Id kā rekvizÄ«tu, savukārt pakārtotais komponents izgÅ«st nepiecieÅ”amos datus no Rakstu saraksts. Pārejot uz publikācijas lapu, mēs iegÅ«stam jau esoÅ”o datumu no Rakstu saraksts, mēs veicam pieprasÄ«jumu iegÅ«t trÅ«kstoÅ”os datus un vienkārÅ”i pievienot tos esoÅ”ajam objektam.

Kāpēc Ŕī pieeja ir labāka? Kā jau rakstÄ«ju iepriekÅ”, Ŕī pieeja ir saudzÄ«gāka attiecÄ«bā uz lejupielādētajiem datiem un ļauj tos izmantot atkārtoti. Bet turklāt tas paver ceļu uz dažām jaunām iespējām, kas lieliski iekļaujas Ŕādā arhitektÅ«rā. Piemēram, aptauju un rakstu ielāde plÅ«smā, kad tie parādās. Mēs varam vienkārÅ”i ievietot jaunākās ziņas "krātuvē" Rakstu saraksts, saglabājiet atseviŔķu jauno ID sarakstu Rakstu ID un paziņot par to lietotājam. NoklikŔķinot uz pogas ā€œRādÄ«t jaunas publikācijasā€, mēs vienkārÅ”i ievietosim jaunus ID paÅ”reizējā rakstu saraksta masÄ«va sākumā, un viss darbosies gandrÄ«z maÄ£iski.

Padarot lejupielādi patīkamāku

KukurÅ«za uz pārveidoÅ”anas kÅ«kas ir skeletu jēdziens, kas satura lejupielādes procesu lēnā internetā padara nedaudz mazāk pretÄ«gu. Diskusijas par Å”o jautājumu nenotika; ceļŔ no idejas lÄ«dz prototipam aizņēma burtiski divas stundas. Dizains praktiski uzzÄ«mēja pats sevi, un mēs mācÄ«jām mÅ«su komponentiem atveidot vienkārÅ”us, tikko mirgojoÅ”us div blokus, gaidot datus. SubjektÄ«vi Ŕī pieeja iekrauÅ”anai faktiski samazina stresa hormonu daudzumu lietotāja organismā. Skelets izskatās Ŕādi:

Habr priekÅ”gala izstrādātāju žurnāli: pārstrukturÄ“Å”ana un atspoguļoÅ”ana
Habraloading

Atspoguļojot

Es strādāju Habrē seÅ”us mēneÅ”us, un mani draugi joprojām jautā: nu, kā jums tur patÄ«k? Labi, ērti - jā. Bet ir kaut kas, kas padara Å”o darbu atŔķirÄ«gu no citiem. Es strādāju komandās, kuras bija pilnÄ«gi vienaldzÄ«gas pret savu produktu, nezināja un nesaprata, kas ir viņu lietotāji. Bet Å”eit viss ir savādāk. Å eit tu jÅ«ties atbildÄ«gs par to, ko dari. Funkcijas izstrādes procesā jÅ«s daļēji kļūstat par tās Ä«paÅ”nieku, piedalāties visās ar jÅ«su funkcionalitāti saistÄ«tās produktu sanāksmēs, pats sniedzat ieteikumus un pieņemat lēmumus. Izgatavot produktu, ko pats lietojat ikdienā, ir ļoti forÅ”i, taču rakstÄ«t kodu cilvēkiem, kuri, iespējams, ir labāki par jums, ir vienkārÅ”i neticama sajÅ«ta (bez sarkasma).

Pēc visu Å”o izmaiņu izdoÅ”anas saņēmām pozitÄ«vas atsauksmes, un tas bija ļoti, ļoti jauki. Tas ir iedvesmojoÅ”i. Paldies! Rakstiet vairāk.

AtgādināŔu, ka pēc globālajiem mainÄ«gajiem mēs nolēmām mainÄ«t arhitektÅ«ru un pieŔķirt starpniekservera slāni atseviŔķā instancē. ā€œDivu mezgluā€ arhitektÅ«ra jau ir izlaista publiskas beta testÄ“Å”anas veidā. Tagad ikviens var pārslēgties uz to un palÄ«dzēt mums uzlabot mobilo Habr. Tas Å”odienai viss. Ar prieku atbildÄ“Å”u uz visiem jÅ«su jautājumiem komentāros.

Avots: www.habr.com

Pievieno komentāru