Хабр фронт-енд програмер дневники: рефакторинг и рефлексија

Хабр фронт-енд програмер дневники: рефакторинг и рефлексија

Одувек ме је занимало како је Хабр структуриран изнутра, како је структуиран ток посла, како су структурисане комуникације, који се стандарди користе и како се код генерално овде пише. На срећу, добио сам такву прилику, јер сам недавно постао део хабра тима. На примеру малог преправљања мобилне верзије, покушаћу да одговорим на питање: како је радити овде на челу. У програму: Ноде, Вуе, Вуек и ССР са сосом из белешки о личном искуству у Хабру.

Прва ствар коју треба да знате о развојном тиму је да нас је мало. Недовољно – ово су три фронта, два бека и техничко вођство свих Хабр – Баксли. Ту су, наравно, и тестер, дизајнер, три Вадима, чудотворна метла, стручњак за маркетинг и други Бумбуруми. Али постоји само шест директних сарадника Хабрових извора. Ово је прилично ретко – пројекат са вишемилионском публиком, који споља изгледа као џиновско предузеће, у стварности више личи на удобан стартап са најравнијом могућом организационом структуром.

Као и многе друге ИТ компаније, Хабр исповеда Агиле идеје, ЦИ праксе, и то је све. Али према мом осећању, Хабр се као производ развија више таласно него континуирано. Дакле, неколико спринтева заредом марљиво нешто кодирамо, дизајнирамо и редизајнирамо, нешто ломимо и поправљамо, решавамо тикете и стварамо нове, газимо на грабуље и пуцамо себи у ноге, да бисмо коначно пустили функцију у производње. А онда долази извесно затишје, период поновног развоја, време да се уради оно што је у квадранту „важно-не хитно“.

Управо о овом „вансезонском“ спринту биће речи у наставку. Овај пут је укључивао рефакторисање мобилне верзије Хабра. Генерално, компанија у то полаже велике наде, ау будућности би требало да замени цео зоолошки врт Хабрових инкарнација и постане универзално решење за више платформи. Једног дана ће постојати прилагодљиви изглед, ПВА, офлајн режим, прилагођавање корисника и многе друге занимљиве ствари.

Хајде да поставимо задатак

Једном, на обичном станд-уп-у, један од предњих је говорио о проблемима у архитектури компоненте коментара мобилне верзије. Имајући то у виду, организовали смо микро-састанак у формату групне психотерапије. Сви су наизменично говорили где боли, све снимили на папир, саосећали, разумели, само што нико није пљескао. Резултат је била листа од 20 проблема, што је јасно дало до знања да мобилни Хабр још има дуг и трновит пут до успеха.

Пре свега сам био забринут због ефикасности коришћења ресурса и онога што се зове глатки интерфејс. Сваког дана, на путу кућа-посао-кућа, видео сам свој стари телефон како очајнички покушава да прикаже 20 наслова у фиду. Изгледало је отприлике овако:

Хабр фронт-енд програмер дневники: рефакторинг и рефлексијаМобилни Хабр интерфејс пре рефакторисања

Шта се дешава овде? Укратко, сервер је свима сервирао ХТМЛ страницу на исти начин, без обзира да ли је корисник пријављен или не. Затим се клијент ЈС учитава и поново тражи потребне податке, али прилагођен за ауторизацију. То јест, ми смо заправо два пута радили исти посао. Интерфејс је затреперио, а корисник је преузео добрих стотину додатних килобајта. У детаљима све је изгледало још језивије.

Хабр фронт-енд програмер дневники: рефакторинг и рефлексијаСтара шема ССР-ЦСР. Ауторизација је могућа само у фазама Ц3 и Ц4, када Ноде ЈС није заузет генерисањем ХТМЛ-а и може да прокси захтеве за АПИ.

Нашу тадашњу архитектуру је врло прецизно описао један од корисника Хабра:

Мобилна верзија је срање. Причам то како јесте. Ужасна комбинација РСБ-а и ЦСР-а.

Морали смо то признати, ма колико тужно било.

Проценио сам опције, направио тикет у Јира са описом на нивоу „сада је лоше, уради то како треба“ и разложио задатак у широким цртама:

  • поново користити податке,
  • минимизирати број поновних цртања,
  • елиминисати дупле захтеве,
  • учините процес учитавања очигледнијим.

Хајде да поново употребимо податке

У теорији, приказивање на страни сервера је дизајнирано да реши два проблема: да не пати од ограничења претраживача у смислу СПА индексирање и побољшати метрику ФМП (неизбежно погоршање ТТИ). У класичном сценарију који коначно формулисан на Аирбнб-у 2013 године (још увек на Бацкбоне.јс), ССР је иста изоморфна ЈС апликација која ради у Ноде окружењу. Сервер једноставно шаље генерисани изглед као одговор на захтев. Затим долази до рехидрације на страни клијента, а онда све функционише без поновног учитавања странице. За Хабр, као и за многе друге ресурсе са текстуалним садржајем, серверско приказивање је критичан елемент у изградњи пријатељских односа са претраживачима.

Упркос чињеници да је прошло више од шест година од појаве технологије, а за то време је много воде заиста пролетело испод моста у фронт-енд свету, за многе програмере ова идеја је још увек обавијена велом тајне. Нисмо стајали по страни и избацили Вуе апликацију са подршком за ССР у продукцију, при чему недостаје један мали детаљ: нисмо послали почетно стање клијенту.

Зашто? Не постоји тачан одговор на ово питање. Или нису хтели да повећају величину одговора са сервера, или због гомиле других архитектонских проблема, или једноставно није кренуло. На овај или онај начин, избацивање стања и поновно коришћење свега што је сервер урадио изгледа сасвим прикладно и корисно. Задатак је заправо тривијалан - стање се једноставно убризгава у контекст извршавања, а Вуе га аутоматски додаје у генерисани изглед као глобалну променљиву: window.__INITIAL_STATE__.

Један од проблема који се појавио је немогућност конвертовања цикличних структура у ЈСОН (кружна референца); је решено једноставном заменом таквих структура њиховим равним колегама.

Поред тога, када се бавите УГЦ садржајем, треба да запамтите да податке треба конвертовати у ХТМЛ ентитете како се не би разбио ХТМЛ. За ове сврхе користимо he.

Минимизирање поновног цртања

Као што можете видети из горњег дијаграма, у нашем случају, једна Ноде ЈС инстанца обавља две функције: ССР и „прокси“ у АПИ-ју, где се јавља ауторизација корисника. Ова околност онемогућава ауторизацију док ЈС код ради на серверу, пошто је чвор једнонитни, а ССР функција је синхрона. То јест, сервер једноставно не може да шаље захтеве себи док је стек позива заузет нечим. Испоставило се да смо ажурирали стање, али интерфејс није престао да се трза, пошто су подаци о клијенту морали да се ажурирају узимајући у обзир сесију корисника. Морали смо да научимо нашу апликацију да постави тачне податке у почетно стање, узимајући у обзир пријаву корисника.

Постојала су само два решења проблема:

  • приложити податке о ауторизацији захтевима за више сервера;
  • подели Ноде ЈС слојеве на две одвојене инстанце.

Прво решење захтевало је коришћење глобалних променљивих на серверу, а друго је продужило рок за извршење задатка за најмање месец дана.

Како направити избор? Хабр се често креће путем мањег отпора. Неформално, постоји општа жеља да се циклус од идеје до прототипа сведе на минимум. Модел односа према производу донекле подсећа на постулате боокинг.цом, са једином разликом што Хабр много озбиљније схвата повратне информације корисника и верује вама, као програмеру, да доносите такве одлуке.

Следећи ову логику и сопствену жељу да брзо решим проблем, изабрао сам глобалне варијабле. И, као што се често дешава, морате их платити пре или касније. Платили смо скоро одмах: радили смо викендом, рашчишћавали последице, писали пост мортем и почео да дели сервер на два дела. Грешка је била веома глупа, а грешку која је укључивала није било лако репродуковати. И да, штета за ово, али на овај или онај начин, посрћући и стењајући, мој ПоЦ са глобалним варијаблама је ипак ушао у производњу и ради прилично успешно док чека прелазак на нову архитектуру „два чвора“. Ово је био важан корак, јер је формално циљ постигнут - ССР је научио да испоручи страницу потпуно спремну за употребу, а кориснички интерфејс је постао много смиренији.

Хабр фронт-енд програмер дневники: рефакторинг и рефлексијаМобилни Хабр интерфејс након прве фазе рефакторисања

Коначно, ССР-ЦСР архитектура мобилне верзије доводи до ове слике:

Хабр фронт-енд програмер дневники: рефакторинг и рефлексијаССР-ЦСР коло „два чвора“. Ноде ЈС АПИ је увек спреман за асинхрони И/О и није блокиран функцијом ССР, пошто се ова друга налази у засебној инстанци. Ланац упита #3 није потребан.

Уклањање дупликата захтева

Након извршених манипулација, почетни приказ странице више није изазивао епилепсију. Али даља употреба Хабра у СПА режиму је ипак изазвала забуну.

Пошто су основа тока корисника прелази форме листа чланака → чланак → коментари и обрнуто, било је важно пре свега оптимизовати потрошњу ресурса овог ланца.

Хабр фронт-енд програмер дневники: рефакторинг и рефлексијаПовратак на пост феед изазива нови захтев за подацима

Није требало дубоко копати. На горњој слици можете видети да апликација поново захтева листу чланака када превучете уназад, а током захтева не видимо чланке, што значи да претходни подаци негде нестају. Изгледа да компонента листе чланака користи локално стање и губи га при уништавању. У ствари, апликација је користила глобално стање, али Вуек архитектура је изграђена директно: модули су везани за странице, које су заузврат везане за руте. Штавише, сви модули су „за једнократну употребу“ - свака наредна посета страници преписала је цео модул:

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

Укупно смо имали модул АртицлесЛист, који садржи објекте типа Чланак и модул ПагеАртицле, који је био проширена верзија објекта Чланак, као АртицлеФулл. Углавном, ова имплементација сама по себи не носи ништа страшно - врло је једноставна, могло би се рећи и наивна, али крајње разумљива. Ако ресетујете модул сваки пут када промените руту, онда чак можете и живети са њим. Међутим, кретање између фидова чланака, на пример /феед → /све, гарантовано ће бацити све што је у вези са личним феедом, пошто имамо само један АртицлесЛист, у који треба да унесете нове податке. Ово нас опет доводи до дуплирања захтева.

Сакупивши све што сам могао да ископам на ту тему, формулисао сам нову државну структуру и представио је својим колегама. Дискусије су биле дуге, али су на крају аргументи у прилог надмашили сумње и ја сам почео да спроводим.

Логика решења најбоље се открива у два корака. Прво покушавамо да одвојимо Вуек модул од страница и директно се повежемо са рутама. Да, биће мало више података у продавници, геттери ће постати мало сложенији, али нећемо два пута учитавати чланке. За мобилну верзију, ово је можда најјачи аргумент. Изгледаће отприлике овако:

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

Али шта ако се листе чланака могу преклапати између више рута и шта ако желимо да поново користимо податке о објектима Чланак да прикажете страницу поста, претварајући је у АртицлеФулл? У овом случају би било логичније користити такву структуру:

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

АртицлесЛист овде је то само нека врста спремишта чланака. Сви чланци који су преузети током корисничке сесије. Према њима поступамо са највећом пажњом, јер је то саобраћај који је можда преузет болом негде у метроу између станица, и дефинитивно не желимо да поново задајемо овај бол кориснику тако што га терамо да учитава податке које већ има преузето. Објекат АртицлесИдс је једноставно низ ИД-ова (као да су „линкови“) са објектима Чланак. Ова структура вам омогућава да избегнете дуплирање података уобичајених за руте и поновну употребу објекта Чланак приликом приказивања странице поста спајањем проширених података у њу.

Излаз листе чланака је такође постао транспарентнији: компонента итератора итерира низ са ИД-овима чланака и црта компоненту тизера чланка, прослеђујући Ид као проп, а подређена компонента, заузврат, преузима потребне податке из АртицлесЛист. Када одете на страницу публикације, добијамо већ постојећи датум од АртицлесЛист, постављамо захтев да добијемо податке који недостају и једноставно их додамо постојећем објекту.

Зашто је овај приступ бољи? Као што сам горе написао, овај приступ је блажи у односу на преузете податке и омогућава вам да их поново користите. Али поред тога, отвара пут ка неким новим могућностима које се савршено уклапају у такву архитектуру. На пример, анкетирање и учитавање чланака у фид онако како се појављују. Можемо једноставно да ставимо најновије постове у „складиште“ АртицлесЛист, сачувајте посебну листу нових ИД-ова у АртицлесИдс и обавести корисника о томе. Када кликнемо на дугме „Прикажи нове публикације“, једноставно ћемо убацити нове ИД-ове на почетак низа тренутне листе чланака и све ће функционисати готово магично.

Учините преузимање угоднијим

Шлаг на торти рефакторинга је концепт скелета, који процес преузимања садржаја на спором Интернету чини мало мање одвратним. О овом питању није било никаквих дискусија, пут од идеје до прототипа трајао је буквално два сата. Дизајн се практично сам нацртао, а ми смо научили наше компоненте да рендерују једноставне, једва трепереће див блокове док чекају податке. Субјективно, овај приступ учитавању заправо смањује количину хормона стреса у телу корисника. Скелет изгледа овако:

Хабр фронт-енд програмер дневники: рефакторинг и рефлексија
Хабралоадинг

Рефлецтинг

Радим у Хабреу шест месеци, а моји пријатељи и даље питају: па, како ти се свиђа тамо? Добро, удобно - да. Али постоји нешто што овај рад чини другачијим од других. Радио сам у тимовима који су били потпуно равнодушни према свом производу, који нису знали ни разумели ко су њихови корисници. Али овде је све другачије. Овде се осећате одговорним за оно што радите. У процесу развоја неке функције, делимично постајете њен власник, учествујете на свим састанцима производа који се односе на вашу функционалност, сами дајете предлоге и доносите одлуке. Прављење производа који сами користите сваки дан је веома кул, али писање кода за људе који су вероватно бољи у томе од вас је само невероватан осећај (без сарказма).

Након објављивања свих ових измена, добили смо позитивне повратне информације, и било је веома, веома лепо. То је инспиративно. Хвала вам! Напишите више.

Да вас подсетим да смо након глобалних променљивих одлучили да променимо архитектуру и доделимо проки слој у посебну инстанцу. Архитектура „два чвора“ је већ стигла до објављивања у облику јавног бета тестирања. Сада свако може да се пребаци на њега и помогне нам да побољшамо мобилни Хабр. То је све за данас. Радо ћу одговорити на сва ваша питања у коментарима.

Извор: ввв.хабр.цом

Додај коментар