Habr Front-End Entwéckler Logbicher: Refactoring a Reflexioun

Habr Front-End Entwéckler Logbicher: Refactoring a Reflexioun

Ech war ëmmer interesséiert wéi Habr vu bannen strukturéiert ass, wéi de Workflow strukturéiert ass, wéi d'Kommunikatioun strukturéiert ass, wéi eng Norme benotzt ginn a wéi Code allgemeng hei geschriwwe gëtt. Glécklecherweis krut ech esou eng Geleeënheet, well ech viru kuerzem Deel vun der habra Equipe ginn. Mat dem Beispill vun enger klenger Refactoring vun der mobiler Versioun probéieren ech d'Fro ze beäntweren: wéi ass et hei un der Front ze schaffen. Am Programm: Node, Vue, Vuex an SSR mat Zooss aus Notizen iwwer perséinlech Erfahrung an Habr.

Dat éischt wat Dir iwwer d'Entwécklungsteam wësse musst ass datt et wéineg vun eis sinn. Net genuch - dat sinn dräi viischt, zwee zréck an den technesche Virsprong vun all Habr - Baxley. Et gëtt natierlech och en Tester, en Designer, dräi Vadim, e Wonnerbesen, e Marketing Spezialist an aner Bumburums. Awer et ginn nëmme sechs direkt Mataarbechter un dem Habr seng Quellen. Dëst ass zimmlech rar - e Projet mat engem Multimillion-Dollar Publikum, dee vu baussen wéi e riesegen Entreprise ausgesäit, an der Realitéit méi ausgesäit wéi e gemittleche Startup mat der flaachster organisatorescher Struktur méiglech.

Wéi vill aner IT Firmen, professéiert Habr Agile Iddien, CI Praktiken, an dat ass alles. Awer no menge Gefiller entwéckelt Habr als Produkt méi a Wellen wéi kontinuéierlech. Also, fir e puer Sprint hannereneen, kodéiere mir fläisseg eppes, designen an nei designen, briechen eppes a fixéieren, léisen Ticketen op a kreéieren neier, trëppelen op eng Rake a schéisst eis an d'Féiss, fir endlech d'Feature erauszebréngen an Produktioun. An da kënnt et eng gewëssen Paus, eng Period vun der Sanéierung, Zäit fir ze maachen wat am "wichteg-net dréngend" Quadrant ass.

Et ass genee dësen "Off-season" Sprint deen hei ënnen diskutéiert gëtt. Dës Kéier huet et eng Refactoring vun der mobiler Versioun vum Habr abegraff. Am Allgemengen huet d'Firma héich Hoffnungen dofir, an an Zukunft sollt et den ganzen Zoo vun den Habr Inkarnatiounen ersetzen an eng universell Cross-Plattform Léisung ginn. Irgendwann gëtt et adaptiven Layout, PWA, offline Modus, Benotzerpersonaliséierung a vill aner interessant Saachen.

Loosst eis d'Aufgab setzen

Eemol, bei engem gewéinleche Stand-up, huet ee vun de Fronten iwwer Probleemer an der Architektur vun der Kommentarkomponent vun der mobiler Versioun geschwat. Mat deem Sënn hu mir eng Mikroversammlung am Format Gruppepsychotherapie organiséiert. Jiddereen huet sech ëmgedréint ze soen, wou et wéi deet, si hunn alles op Pabeier opgeholl, si hu sympathiséiert, si hu verstanen, ausser datt kee geklappt huet. D'Resultat war eng Lëscht vun 20 Probleemer, déi kloer gemaach hunn datt den mobilen Habr nach ëmmer e laangen an thornesche Wee zum Erfolleg hat.

Ech war virun allem besuergt iwwer Ressource Effizienz a wat e glat Interface genannt gëtt. All Dag, op der Heem-Aarbecht-Heem-Streck, hunn ech mäi alen Telefon verzweifelt gesinn, 20 Schlagzeilen am Feed ze weisen. Et huet sou eppes ausgesinn:

Habr Front-End Entwéckler Logbicher: Refactoring a ReflexiounMobile Habr Interface virum Refactoring

Wat ass hei lass? Kuerz gesot, de Server huet d'HTML-Säit jidderengem op déiselwecht Manéier servéiert, egal ob de Benotzer ageloggt war oder net. Da gëtt de Client JS gelueden a freet déi néideg Donnéeën erëm, awer fir d'Autorisatioun ugepasst. Dat heescht, mir hunn eigentlech zweemol déi selwecht Aarbecht gemaach. D'Interface huet geflickert, an de Benotzer huet eng gutt honnert extra Kilobytes erofgelueden. Am Detail huet alles nach méi grujheleg ausgesinn.

Habr Front-End Entwéckler Logbicher: Refactoring a ReflexiounAlt SSR-CSR Schema. Autorisatioun ass nëmme méiglech op Etappen C3 an C4, wann Node JS net beschäftegt ass HTML ze generéieren a Proxy Ufroen un d'API kann.

Eis Architektur vun där Zäit gouf ganz genee vun engem vun den Habr Benotzer beschriwwen:

Déi mobil Versioun ass schrecklech. Ech soen et wéi et ass. Eng schrecklech Kombinatioun vun SSR an CSR.

Mir hu missen zouginn, egal wéi traureg et war.

Ech hunn d'Optiounen bewäert, en Ticket zu Jira erstallt mat enger Beschreiwung um Niveau vun "et ass schlecht elo, maacht et richteg" an hunn d'Aufgab a grousse Striche ofgebaut:

  • Daten nei benotzen,
  • minimiséieren d'Zuel vun de Redraws,
  • eliminéiert duplizéiert Ufroen,
  • maachen de Luede Prozess méi offensichtlech.

Loosst eis d'Donnéeë weiderbenotzen

An Theorie ass Server-Säit Rendering entwéckelt fir zwee Probleemer ze léisen: net ënner Sichmotorbeschränkungen ze leiden a punkto SPA Indexéierung a verbessert d'Metrik FMP (onweigerlech verschlechtert TTI). An engem klassesche Szenario datt endlech 2013 bei Airbnb formuléiert Joer (nach ëmmer op Backbone.js), SSR ass déiselwecht isomorphesch JS Applikatioun déi am Node Ëmfeld leeft. De Server schéckt einfach de generéierte Layout als Äntwert op d'Ufro. Da geschitt Rehydratioun op der Client Säit, an da funktionnéiert alles ouni Säit nei lued. Fir Habr, wéi fir vill aner Ressourcen mat Textinhalt, ass d'Serverrendering e kriteschen Element fir frëndlech Bezéiunge mat Sichmotoren ze bauen.

Trotz der Tatsaach, datt méi wéi sechs Joer zanter dem Entstoe vun der Technologie vergaangen ass, a während dëser Zäit vill Waasser wierklech ënner der Bréck an der Front-End Welt geflunn ass, ass fir vill Entwéckler dës Iddi nach ëmmer am Geheimnis gehäit. Mir stoungen net op der Säit an hunn eng Vue Applikatioun mat SSR Support fir d'Produktioun ausgerullt, e klengen Detail fehlt: mir hunn den initialen Zoustand net un de Client geschéckt.

Firwat? Et gëtt keng exakt Äntwert op dës Fro. Entweder si wollten d'Gréisst vun der Äntwert vum Server net erhéijen, oder wéinst enger Rëtsch aner architektonesch Problemer, oder et huet einfach net ofgeholl. Op eng Manéier oder aner, Staat erausgeheien an alles nei ze benotzen wat de Server gemaach huet schéngt ganz passend an nëtzlech. D'Aufgab ass eigentlech trivial - Staat gëtt einfach injizéiert an den Ausféierungskontext, a Vue füügt et automatesch un de generéierte Layout als eng global Variabel: window.__INITIAL_STATE__.

Ee vun de Problemer déi entstanen ass ass d'Onméiglechkeet fir zyklesch Strukturen an JSON (kreesfërmeg Referenz); gouf geléist andeems se sou Strukturen einfach duerch hir flaach Géigeparteien ersetzen.

Zousätzlech, wann Dir mat UGC Inhalt handelt, sollt Dir drun erënneren datt d'Donnéeën an HTML Entitéiten ëmgewandelt ginn fir den HTML net ze briechen. Fir dës Zwecker benotze mir he.

Redraws minimiséieren

Wéi Dir aus dem Diagramm hei uewen kënnt gesinn, an eisem Fall mécht eng Node JS Instanz zwou Funktiounen: SSR an "Proxy" an der API, wou d'Benotzerautorisatioun geschitt. Dës Ëmstänn mécht et onméiglech ze autoriséieren während de JS Code um Server leeft, well de Node Single-threaded ass, an d'SSR Funktioun ass synchron. Dat ass, de Server kann einfach net Ufroe fir sech selwer schécken wann de Callstack mat eppes beschäftegt ass. Et huet sech erausgestallt datt mir de Staat aktualiséiert hunn, awer d'Interface huet net ophalen ze zéien, well d'Donnéeën iwwer de Client musse aktualiséiert ginn andeems d'Benotzersessioun berücksichtegt gëtt. Mir mussen eis Applikatioun léieren fir déi richteg Donnéeën an den initialen Zoustand ze setzen, andeems Dir de Login vum Benotzer berücksichtegt.

Et waren nëmmen zwou Léisunge fir de Problem:

  • befestegt Autorisatiounsdaten op Cross-Server Ufroen;
  • opgedeelt Node JS Schichten an zwee getrennten Instanzen.

Déi éischt Léisung erfuerdert d'Benotzung vu globale Variablen um Server, an déi zweet huet d'Deadline fir d'Aufgab op d'mannst ee Mount verlängert.

Wéi e Choix ze maachen? Habr beweegt sech dacks laanscht de Wee vun der mannsten Resistenz. Informell gëtt et en allgemenge Wonsch den Zyklus vun Iddi bis Prototyp op e Minimum ze reduzéieren. De Modell vun der Haltung zum Produkt erënnert e bëssen un d'Postulate vu booking.com, mam eenzegen Ënnerscheed ass datt den Habr Benotzer Feedback vill méi eescht hëlt an Iech als Entwéckler vertraut fir sou Entscheedungen ze treffen.

No dëser Logik a mengem eegene Wonsch de Problem séier ze léisen, hunn ech global Variablen gewielt. A wéi dacks geschitt, musst Dir desto oder spéider dofir bezuelen. Mir hu bal direkt bezuelt: mir hunn de Weekend geschafft, d'Konsequenzen opgekläert, geschriwwen postmortem an huet ugefaang de Server an zwee Deeler opzedeelen. De Feeler war ganz domm, an de Käfer mat deem et involvéiert war net einfach ze reproduzéieren. A jo, et ass schued fir dëst, awer op eng oder aner Manéier, stoussen a kräischen, meng PoC mat globalen Variablen ass trotzdem an d'Produktioun gaang a funktionnéiert zimlech erfollegräich wärend op de Beweegung an eng nei "Zwee-Node" Architektur waart. Dëst war e wichtege Schrëtt, well formell d'Zil erreecht gouf - SSR huet geléiert eng komplett prett-ze-benotzen Säit ze liwweren, an d'UI gouf vill méi roueg.

Habr Front-End Entwéckler Logbicher: Refactoring a ReflexiounMobile Habr Interface no der éischter Etapp vun refactoring

Schlussendlech féiert d'SSR-CSR Architektur vun der mobiler Versioun zu dësem Bild:

Habr Front-End Entwéckler Logbicher: Refactoring a Reflexioun"Zwee-Node" SSR-CSR Circuit. Den Node JS API ass ëmmer prett fir asynchronen I/O a gëtt net vun der SSR Funktioun blockéiert, well déi lescht an enger separater Instanz läit. Query Kette #3 ass net néideg.

Duplikat Ufroen eliminéieren

Nodeems d'Manipulatioune gemaach goufen, huet d'éischt Rendering vun der Säit keng Epilepsie méi provozéiert. Awer déi weider Notzung vum Habr am SPA Modus huet ëmmer nach Duercherneen verursaacht.

Zënter der Basis vum Benotzerfluss sinn Transitioune vun der Form Lëscht vun den Artikelen → Artikel → Kommentaren a Vize versa, et war wichteg d'Ressource Konsum vun dëser Kette an der éischter Plaz ze optimiséieren.

Habr Front-End Entwéckler Logbicher: Refactoring a ReflexiounZréck op de Postfeed provozéiert eng nei Datefro

Et war net néideg déif ze gräifen. Am Screencast uewendriwwer kënnt Dir gesinn datt d'Applikatioun d'Lëscht vun den Artikelen erfuerdert wann Dir zréck swipt, a wärend der Ufro gesi mir d'Artikelen net, wat heescht datt déi vireg Donnéeën iergendwou verschwannen. Et gesäit aus wéi den Artikel Lëscht Komponent engem lokal Staat benotzt a verléiert et op zerstéieren. Tatsächlech huet d'Applikatioun e globale Staat benotzt, awer d'Vuex Architektur gouf direkt gebaut: Moduler sinn op Säiten gebonnen, déi am Tour mat Strecken gebonnen sinn. Ausserdeem sinn all Moduler "weigweg" - all spéider Besuch op der Säit huet de ganze Modul nei geschriwwen:

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

Am Ganzen hate mir e Modul Artikel Lëscht, déi Objete vum Typ enthält Manifestatioun an Modul PageArtikel, wat eng erweidert Versioun vum Objet war Manifestatioun, zimmlech Artikel Voll. Am grousse Ganzen bréngt dës Ëmsetzung näischt schreckleches u sech selwer - et ass ganz einfach, et kann ee souguer naiv soen, awer extrem verständlech. Wann Dir de Modul all Kéier wann Dir d'Streck ännert zréckgesat, da kënnt Dir souguer domat liewen. Wéi och ëmmer, zum Beispill tëscht Artikelfeeds réckelen /feed → /all, ass garantéiert alles ze geheien am Zesummenhang mat der perséinlecher Feed, well mir hunn nëmmen eng Artikel Lëscht, an déi Dir musst nei Donnéeën setzen. Dëst féiert eis erëm zu Duplikatioun vun Ufroen.

Nodeems ech alles gesammelt hunn, wat ech zum Thema konnt erausgruewen, hunn ech eng nei Staatsstruktur formuléiert a menge Kollege virgestallt. D'Diskussiounen ware laang, mä um Enn hunn d'Argumenter dofir d'Zweifel iwwerwältegt, an ech hunn ugefaang mat der Ëmsetzung.

D'Logik vun enger Léisung ass am beschten an zwee Schrëtt opgedeckt. Als éischt probéieren mir de Vuex Modul vu Säiten ofzekoppelen an direkt un Strecken ze binden. Jo, et gëtt e bësse méi Donnéeën am Geschäft, Getters ginn e bësse méi komplex, awer mir lueden net zweemol Artikelen. Fir déi mobil Versioun ass dëst vläicht dat stäerkst Argument. Et wäert sou eppes ausgesinn:

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

Awer wat wann Artikellëschte kënnen tëscht verschidde Strecken iwwerlappen a wat wa mir Objektdaten nei benotze wëllen Manifestatioun fir d'Post Säit ze renderen, se an Artikel Voll? An dësem Fall wier et méi logesch esou eng Struktur ze benotzen:

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

Artikel Lëscht hei ass et just eng Zort Repository vun Artikelen. All Artikelen déi während der Benotzersitzung erofgeluede goufen. Mir behandelen se mat der gréisster Suergfalt, well dëst Traffic ass, deen duerch Péng iergendwou an der Metro tëscht Statiounen erofgeluede ka ginn, a mir wëllen de Benotzer definitiv net nach eng Kéier dëse Péng verursaachen andeems hien him forcéiert Donnéeën ze lueden, déi hie schonn huet erofgelueden. En Objet ArtikelIds ass einfach eng Array vun IDen (wéi wann "Links") op Objekter Manifestatioun. Dës Struktur erlaabt Iech d'Duplizéieren vun Daten ze vermeiden, déi gemeinsam sinn op Strecken an d'Wiederbenotzen vum Objet Manifestatioun wann Dir eng Post Säit rendert andeems Dir verlängert Donnéeën dran fusionéiert.

D'Output vun der Lëscht vun den Artikelen ass och méi transparent ginn: d'Iterator-Komponent iteréiert duerch d'Array mat Artikel-IDen an zitt den Artikel-Teaser-Komponent, passéiert d'Id als Requisiten, an d'Kand-Komponent hëlt erëm déi néideg Donnéeën aus Artikel Lëscht. Wann Dir op d'Publikatiounssäit gitt, kréie mir de schonn existent Datum vun Artikel Lëscht, mir maachen eng Demande fir déi fehlend Donnéeën ze kréien an einfach op dat existent Objet ze addéieren.

Firwat ass dës Approche besser? Wéi ech uewe geschriwwen hunn, ass dës Approche méi sanft mat Respekt fir déi erofgeluede Donnéeën an erlaabt Iech se erëm ze benotzen. Mee ausserdeem mécht et de Wee op fir e puer nei Méiglechkeeten, déi perfekt an esou eng Architektur passen. Zum Beispill Polling an Luede Artikelen an de Feed wéi se erschéngen. Mir kënnen déi lescht Posts einfach an e "Späichere" setzen Artikel Lëscht, späichert eng separat Lëscht vun neien IDen an ArtikelIds an informéiert de Benotzer doriwwer. Wa mir op de Knäppchen "Show nei Publikatiounen" klickt, setzen mir einfach nei Ids an den Ufank vun der Array vun der aktueller Lëscht vun Artikelen an alles funktionnéiert bal magesch.

Maacht den Download méi agreabel

D'Glace op der refactoring Kuch ass d'Konzept vun Skeletter, déi mécht de Prozess vun eroflueden Inhalt op engem luesen Internet e bësse manner Eekleges. Et goufe keng Diskussiounen iwwer dëst Thema, de Wee vun der Iddi zum Prototyp huet wuertwiertlech zwou Stonnen gedauert. Den Design huet sech praktesch gezeechent, a mir hunn eis Komponenten geléiert fir einfach, kaum flikkerend Div-Blöcke ze maachen wärend op Daten waarden. Subjektiv reduzéiert dës Approche fir d'Luede tatsächlech d'Quantitéit u Stresshormonen am Kierper vum Benotzer. De Skelett gesäit esou aus:

Habr Front-End Entwéckler Logbicher: Refactoring a Reflexioun
Habraloading

Reflexéieren

Ech schaffen zanter XNUMX Méint zu Habré a meng Frënn froen nach ëmmer: bon, wéi gefällt dir do? Okay, bequem - jo. Awer et gëtt eppes wat dës Aarbecht anescht mécht wéi anerer. Ech hunn an Teams geschafft, déi komplett indifferent zu hirem Produkt waren, net woussten oder verstanen hunn, wien hir Benotzer waren. Awer hei ass alles anescht. Hei fillt Dir Iech verantwortlech fir wat Dir maacht. Am Prozess vun der Entwécklung vun enger Feature, sidd Dir deelweis säi Besëtzer, huelt un all Produktversammlungen am Zesummenhang mat Ärer Funktionalitéit deel, maacht Suggestioune a maacht selwer Entscheedungen. E Produkt ze maachen dat Dir all Dag selwer benotzt ass ganz cool, awer Code schreiwen fir Leit déi wahrscheinlech besser sinn wéi Dir ass just en onheemlecht Gefill (kee Sarkasmus).

No der Verëffentlechung vun all dësen Ännerungen, hu mir positiv Feedback, an et war ganz, ganz flott. Et ass inspiréierend. Merci! Schreift méi.

Loosst mech Iech drun erënneren datt mir no global Variablen decidéiert hunn d'Architektur z'änneren an d'Proxy Layer an eng separat Instanz ze verdeelen. D'"Zwee-Node" Architektur huet scho Verëffentlechung a Form vun ëffentlechen Beta Testen erreecht. Elo kann jidderee dorop wiesselen an eis hëllefen den Handy Habr besser ze maachen. Dat ass alles fir haut. Ech wäert frou all Är Froen an de Kommentaren ze äntweren.

Source: will.com

Setzt e Commentaire