Habr алдыңкы иштеп чыгуучу журналдары: рефакторинг жана чагылдыруу

Habr алдыңкы иштеп чыгуучу журналдары: рефакторинг жана чагылдыруу

Мени ар дайым Хабрдын ичинен кандайча түзүлөөрү, иш процесси кантип түзүлөт, коммуникациялар кандай түзүлөт, кандай стандарттар колдонулат жана бул жерде жалпысынан код кантип жазылганы кызыкты. Бактыга жараша, менде ушундай мүмкүнчүлүк болду, анткени мен жакында хабра командасынын мүчөсү болдум. Мобилдик версиянын кичинекей рефакторингинин мисалын колдонуп, мен суроого жооп берүүгө аракет кылам: бул жерде фронтто иштөө кандай. Программада: Node, Vue, Vuex жана SSR Хабрдагы жеке тажрыйба жөнүндө жазуулардан соус менен.

Өнүктүрүү тобу жөнүндө сиз билишиңиз керек болгон биринчи нерсе - бул биздин аз экенибиз. Жетишсиз - бул үч фронт, эки арт жана бардык Хабрдын техникалык лидери - Бакслей. Албетте, ошондой эле тестиер, дизайнер, үч Vadim, керемет шыпыргы, маркетинг боюнча адис жана башка Bumburums бар. Бирок Хабрдын булактарына түз салым кошкон алты гана адам бар. Бул өтө сейрек кездешет - сыртынан алп ишкана сыяктуу көрүнгөн көп миллиондогон аудиториясы бар долбоор, чындыгында мүмкүн болушунча жалпак уюштуруу түзүмү менен ыңгайлуу стартапка окшош.

Көптөгөн башка IT компаниялары сыяктуу эле, Хабр Agile идеяларын, CI тажрыйбаларын айтат жана ушуну менен бүттү. Бирок менин сезимим боюнча, Хабр продукт катары үзгүлтүксүз эмес, толкунда көбүрөөк өнүгүп жатат. Ошентип, катары менен бир нече спринт үчүн биз бир нерсени кылдаттык менен коддойбуз, долбоорлойбуз жана кайра иштеп чыгабыз, бир нерсени бузуп, оңдойбуз, билеттерди чечебиз жана жаңысын түзөбүз, тырмоого басып, бутубузга ок атабыз, акырында функцияны чыгаруу үчүн өндүрүш. Анан белгилүү бир тыныгуу, кайра иштеп чыгуу мезгили, “маанилүү-шашылыш эмес” квадрантта эмнелерди жасоого убакыт келет.

Дал ушул "сезондон тышкары" спринт төмөндө талкууланат. Бул жолу ал Хабрдын мобилдик версиясын рефакторингди камтыды. Жалпысынан алганда, компания ага чоң үмүт артып жатат жана келечекте ал Хабрдын инкарнацияларынын бардык зоопарктарын алмаштырып, универсалдуу кросс-платформа чечими болушу керек. Бир күнү адаптациялоочу макет, PWA, оффлайн режими, колдонуучу ыңгайлаштыруу жана башка көптөгөн кызыктуу нерселер болот.

Келгиле, тапшырма коёлу

Бир жолу катардагы стендде алдыңкылардын бири мобилдик версиянын комментарийлер компонентинин архитектурасындагы көйгөйлөр жөнүндө айтып берди. Ошону эске алып, топтук психотерапия форматында микро жолугушуу уюштурдук. Кайсы жери ооруса, баары кезектешип айтып, баарын кагазга түшүрүштү, боор ооруду, түшүнүштү, эч ким кол чапкан жок. Жыйынтыгында 20 көйгөйлөрдүн тизмеси түзүлдү, бул мобилдик Хабр дагы деле ийгиликке карай узак жана татаал жолду басып өттү.

Мени биринчи кезекте ресурстун натыйжалуулугу жана жылмакай интерфейс деп атаган нерсе кызыктырды. Күн сайын үй-жумуш-үй каттамында мен эски телефонумдун түрмөгүндө 20 баш макаланы көрсөтүүгө аракет кылып жатканын көрдүм. Ал мындай көрүндү:

Habr алдыңкы иштеп чыгуучу журналдары: рефакторинг жана чагылдырууМобилдик Habr интерфейси рефакторингден мурун

Бул жакта эмне болуп жатат? Кыскача айтканда, сервер HTML баракчасын колдонуучу кирген же кирбегенине карабастан, баарына бирдей тейлеген. Андан кийин кардар JS жүктөлүп, керектүү маалыматтарды кайра сурайт, бирок авторизацияга туураланат. Башкача айтканда, биз иш жүзүндө бир эле ишти эки жолу аткардык. Интерфейс жаркылдап, колдонуучу жакшы жүз кошумча килобайт жүктөп алды. майда-чүйдөсүнө чейин баары ого бетер коркунучтуу көрүндү.

Habr алдыңкы иштеп чыгуучу журналдары: рефакторинг жана чагылдырууЭски ССР-КСР схемасы. Авторизация C3 жана C4 этаптарында, Node JS HTML түзүү менен алек болбогондо жана API'ге прокси сурамдарды бере алган учурда гана мүмкүн болот.

Ошол кездеги биздин архитектура Хабр колдонуучуларынын бири тарабынан абдан так сүрөттөлгөн:

Мобилдик версиясы жаман. Мен болсо ошондой айтып жатам. ССР менен КСРдин коркунучтуу айкалышы.

Канчалык кайгылуу болсо да моюнга алышыбыз керек болчу.

Мен варианттарды бааладым, Жирада "азыр жаман, туура кыл" деңгээлиндеги сыпаттамасы менен билет түздүм жана тапшырманы кеңири штрихтер менен бөлдүм:

  • маалыматтарды кайра колдонуу,
  • кайра чийүү санын азайтуу,
  • кайталанма суроо-талаптарды жок кылуу,
  • жүктөө процессин айкыныраак кылуу.

Келгиле, маалыматтарды кайра колдонолу

Теорияда сервердик рендеринг эки маселени чечүү үчүн иштелип чыккан: издөө системасынын чектөөлөрүнөн жапа чекпөө. SPA индекстөө жана метриканы жакшыртуу FMP (сөзсүз начарлайт TTI). Классикалык сценарийде, акыры 2013-жылы Airbnb тарабынан түзүлгөн жыл (дагы Backbone.js боюнча), SSR Node чөйрөсүндө иштеген ошол эле изоморфтук JS тиркемеси. Сервер жөн гана суроо-талапка жооп катары түзүлгөн макетти жөнөтөт. Андан кийин регидратация кардар тарапта болот, андан кийин баары баракты кайра жүктөөсүз иштейт. Хабр үчүн, тексттик мазмуну бар көптөгөн башка ресурстар сыяктуу эле, сервердик рендеринг издөө системалары менен достук мамилелерди түзүүнүн маанилүү элементи болуп саналат.

Технологиянын пайда болгондон бери алты жылдан ашык убакыт өткөнүнө жана бул убакыттын ичинде алдыңкы дүйнөдө көпүрөнүн астынан чындап эле көп суу агып өткөнүнө карабастан, көптөгөн иштеп чыгуучулар үчүн бул идея дагы эле жашыруун бойдон калууда. Биз четте турбай, өндүрүшкө SSR колдоосу менен Vue тиркемесин чыгардык, бир майда деталдарды калтырдык: биз кардарга баштапкы абалды жөнөткөн жокпуз.

Неге? Бул суроого так жооп жок. Же алар серверден жооптун көлөмүн көбөйтүүнү каалашкан жок, же башка архитектуралык көйгөйлөрдөн улам, же жөн эле чечилген жок. Кандайдыр бир жол менен, абалды жокко чыгаруу жана сервер жасаган нерселердин баарын кайра колдонуу абдан ылайыктуу жана пайдалуу көрүнөт. Тапшырма чындыгында анча маанилүү эмес - мамлекет жөн гана сайылган аткаруу контекстине жана Vue аны автоматтык түрдө глобалдык өзгөрмө катары түзүлгөн макетке кошот: window.__INITIAL_STATE__.

Пайда болгон көйгөйлөрдүн бири - циклдик структураларды JSONге айландыра албагандыгы (тегерек шилтеме); мындай конструкцияларды жалпак окшоштору менен жөн эле алмаштыруу менен чечилди.

Кошумчалай кетсек, UGC мазмуну менен иштөөдө, HTMLди бузуп албаш үчүн маалыматтар HTML объекттерине айландырылышы керек экенин эстен чыгарбоо керек. Бул максаттар үчүн биз колдонобуз he.

Кайра сызууларды азайтуу

Жогорудагы диаграммадан көрүнүп тургандай, биздин учурда бир Node JS инстанциясы эки функцияны аткарат: SSR жана API'де "прокси", колдонуучунун авторизациясы болгон жерде. Бул жагдай JS коду серверде иштеп турганда авторизациялоону мүмкүн эмес кылат, анткени түйүн бир жиптүү жана SSR функциясы синхрондуу. Башкача айтканда, callstack бир нерсе менен алек болуп турганда сервер өзүнө суроо-талаптарды жөнөтө албайт. Көрсө, биз абалды жаңыртып койдук, бирок интерфейс кыйшаюусун токтоткон жок, анткени кардардагы маалыматтар колдонуучунун сессиясын эске алуу менен жаңыртылышы керек болчу. Колдонмого колдонуучунун логинди эске алуу менен туура маалыматтарды баштапкы абалга келтирүүгө үйрөтүшүбүз керек болчу.

Көйгөйдүн эки гана чечими бар эле:

  • серверлер аралык суроо-талаптарга авторизация маалыматтарын тиркөө;
  • Node JS катмарларын эки башка инстанцияга бөлүңүз.

Биринчи чечим серверде глобалдык өзгөрмөлөрдү колдонууну талап кылса, экинчиси тапшырманы аткаруунун мөөнөтүн кеминде бир айга узартты.

Кантип тандоо керек? Хабр көбүнчө эң аз каршылыктын жолу менен жүрөт. Бейформал түрдө идеядан прототипке чейинки циклди минималдуу деңгээлге чейин кыскартууга жалпы каалоо бар. Продукцияга болгон мамиленин модели booking.com постулаттарын бир аз эске салат, бир гана айырмасы Хабр колдонуучулардын пикирлерин олуттуураак кабыл алып, иштеп чыгуучу катары ушундай чечимдерди кабыл алуу үчүн сизге ишенет.

Ушул логикага жана маселени тез арада чечүүгө болгон каалоомдун негизинде мен глобалдык өзгөрмөлөрдү тандадым. Жана, көп учурда, сиз алар үчүн төлөөгө эртеби-кечпи. Биз дээрлик дароо төлөп бердик: биз дем алыш күндөрү иштедик, кесепеттерин тазаладык, деп жазды өлгөндөн кийин жана серверди эки бөлүккө бөлө баштады. Ката абдан акылсыз жана аны камтыган катаны кайра чыгаруу оңой болгон жок. Ооба, бул уят, бирок кандайдыр бир жол менен, мүдүрүлүп, онтоп, менин глобалдык өзгөрмөлөрү бар PoC өндүрүшкө кирди жана жаңы "эки түйүндүү" архитектурага өтүүнү күтүп, ийгиликтүү иштеп жатат. Бул маанилүү кадам болду, анткени формалдуу түрдө максат ишке ашты - SSR колдонууга толугу менен даяр баракчаны жеткирүүгө үйрөндү жана UI кыйла тынчыраак болуп калды.

Habr алдыңкы иштеп чыгуучу журналдары: рефакторинг жана чагылдырууМобилдик Habr интерфейси рефакторингдин биринчи этабынан кийин

Акыр-аягы, мобилдик версиянын SSR-CSR архитектурасы бул сүрөткө алып келет:

Habr алдыңкы иштеп чыгуучу журналдары: рефакторинг жана чагылдыруу«Эки түйүндүү» ССР-КСР схемасы. Node JS API ар дайым асинхрондук киргизүү/чыгаруу үчүн даяр жана SSR функциясы тарабынан бөгөттөлбөйт, анткени акыркысы өзүнчө инстанцияда жайгашкан. №3 суроо тизмеги кереги жок.

Кайталанма сурамдарды жок кылуу

Манипуляциялар жасалгандан кийин, беттин алгачкы рендеринги эпилепсияны козгобой калды. Бирок Habrды SPA режиминде андан ары колдонуу дагы эле баш аламандыктарды жаратты.

Колдонуучу агымынын негизин форманын өтүүлөрү түзөт макалалардын тизмеси → макала → комментарийлер жана тескерисинче, биринчи кезекте бул чынжырдын ресурстарын керектөөнү оптималдаштыруу маанилүү болгон.

Habr алдыңкы иштеп чыгуучу журналдары: рефакторинг жана чагылдырууПосттун түрмөгүнө кайтуу жаңы маалымат сурамынын пайда болушуна себеп болот

Терең казуунун кереги жок болчу. Жогорудагы скринкастта тиркеме артка сүрүп жатканда макалалардын тизмесин кайра сурап жатканын көрө аласыз, ал эми суроо-талап учурунда биз макалаларды көрбөйбүз, демек мурунку маалыматтар бир жерде жок болуп кетет. Макала тизмеси компоненти локалдык абалды колдонуп, жок кылууда аны жоготот окшойт. Чынында, тиркеме глобалдык абалды колдонгон, бирок Vuex архитектурасы бетме-бет курулган: модулдар барактарга байланган, алар өз кезегинде маршруттарга байланган. Мындан тышкары, бардык модулдар "бир жолку" болуп саналат - баракка ар бир кийинки сапары бүт модулду кайра жазган:

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

Жалпысынан бизде модул бар болчу Макалалар тизмеситүрүндөгү объекттерди камтыйт макала жана модулу PageArticle, бул объекттин кеңейтилген версиясы болгон макала, сымал Макала толук. Жалпысынан алганда, бул ишке ашыруу эч кандай коркунучтуу эч нерсе алып келбейт - бул абдан жөнөкөй, ал тургай, жөнөкөй деп айтууга болот, бирок абдан түшүнүктүү. Эгер сиз маршрутту өзгөрткөн сайын модулду баштапкы абалга келтирсеңиз, анда сиз аны менен жашай аласыз. Бирок, мисалы, макала каналдарынын ортосунда өтүү /feed → /бардыгы, жеке каналга тиешелүү нерселердин баарын ыргытууга кепилдик берилет, анткени бизде бирөө гана бар Макалалар тизмеси, ага сиз жаңы маалыматтарды киргизишиңиз керек. Бул бизди кайрадан сурамдардын кайталанышына алып келет.

Тема боюнча казып алган нерселердин баарын чогултуп, мен жаңы мамлекеттик структураны түзүп, аны кесиптештериме сунуштадым. Талкуулар узакка созулду, бирок акырында пайдасына болгон аргументтер күмөн саноолордон ашып түштү, мен ишке ашырууга кириштим.

Чечимдин логикасы эң жакшы эки кадам менен ачылат. Адегенде биз Vuex модулун барактардан ажыратып, түз каттамдарга байланыштырууга аракет кылабыз. Ооба, дүкөндө бир аз көбүрөөк маалымат болот, алуучулар бир аз татаалдашат, бирок биз макалаларды эки жолу жүктөбөйбүз. Мобилдик версия үчүн бул, балким, эң күчтүү аргумент. Ал төмөнкүдөй көрүнөт:

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

Бирок макала тизмелери бир нече каттамдардын ортосунда бири-бирине дал келиши мүмкүн жана объекттин берилиштерин кайра колдонууну кааласакчы? макала пост барагын көрсөтүү, аны айландыруу Макала толук? Бул учурда, мындай структураны колдонуу логикалуураак болмок:

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

Макалалар тизмеси бул жерде бул жөн гана макалалардын репозиторий түрү. Колдонуучунун сессиясында жүктөлүп алынган бардык макалалар. Биз аларга өтө кылдат мамиле жасайбыз, анткени бул трафик, метронун кайсы бир жеринде станциялардын ортосундагы оору аркылуу жүктөлүп алынган болушу мүмкүн жана биз аны колдонуучуга буга чейин болгон маалыматтарды жүктөөгө мажбурлап, кайра бул ооруну жараткыбыз келбейт. жүктөлүп алынган. Объект ArticlesIds бул жөн гана объекттерге ID массивдери («шилтемелер» сыяктуу). макала. Бул структура каттамдар үчүн жалпы маалыматтарды кайталоодон жана объектти кайра колдонуудан качууга мүмкүндүк берет макала Пост барагын ага кеңейтилген маалыматтарды бириктирүү аркылуу көрсөтүүдө.

Макалалардын тизмесинин чыгышы дагы ачык-айкын болуп калды: итератор компоненти макаланын идентификаторлору менен массив аркылуу итерацияланат жана идентификаторду таяныч катары өткөрүп, макаланын тизер компонентин тартат, ал эми бала компоненти өз кезегинде керектүү маалыматтарды тартып алат. Макалалар тизмеси. Сиз жарыялоо барагына барганыңызда, биз мурунтан эле бар датаны алабыз Макалалар тизмеси, биз жетишпеген маалыматтарды алуу өтүнүчүн жасайбыз жана аны жөн гана учурдагы объектке кошобуз.

Эмне үчүн бул ыкма жакшыраак? Мен жогоруда жазгандай, бул ыкма жүктөлүп алынган маалыматтарга карата жумшак жана аны кайра колдонууга мүмкүндүк берет. Бирок мындан тышкары, мындай архитектурага эң сонун шайкеш келген жаңы мүмкүнчүлүктөргө жол ачат. Мисалы, сурамжылоо жана түрмөккө макалалар көрүнгөндөй жүктөө. Биз жөн гана акыркы билдирүүлөрдү "сактоочу жайга" сала алабыз. Макалалар тизмеси, жаңы идентификаторлордун өзүнчө тизмесин сактаңыз ArticlesIds жана бул тууралуу колдонуучуга кабарлаңыз. "Жаңы басылмаларды көрсөтүү" баскычын басканда, биз жөн гана жаңы идентификаторлорду макалалардын учурдагы тизмесинин башына киргизебиз жана бардыгы дээрлик сыйкырдуу иштейт.

Жүктөп алууну көбүрөөк жагымдуу кылуу

Рефакторинг тортундагы глазурь - бул скелет концепциясы, бул жай Интернетте мазмунду жүктөө процессин бир аз жийиркеничтүү кылат. Бул маселе боюнча эч кандай талкуу болгон жок; идеядан прототипке чейинки жол эки саатка созулду. Дизайн иш жүзүндө өзүн өзү тартты жана биз маалыматтарды күтүп жатып, компоненттерибизди жөнөкөй, араң бүлбүлдөгөн div блокторун көрсөтүүнү үйрөттүк. Субъективдүү түрдө жүктөөнүн бул ыкмасы колдонуучунун денесинде стресс гормондорунун көлөмүн азайтат. Скелет мындай көрүнөт:

Habr алдыңкы иштеп чыгуучу журналдары: рефакторинг жана чагылдыруу
Habraloading

чагылдыруу

Мен Хабреде алты айдан бери иштеп жатам жана досторум дагы эле сурашат: жакшы, ал жерде сага кандай жагасың? Макул, ыңгайлуу - ооба. Бирок бул ишти башкалардан айырмалап турган бир нерсе бар. Мен өз продукциясына таптакыр кайдыгер, колдонуучулары ким экенин билбеген же түшүнбөгөн командаларда иштедим. Бирок бул жерде баары башкача. Бул жерде сиз жасаган ишиңиз үчүн жоопкерчиликти сезесиз. Функцияны иштеп чыгуу процессинде сиз анын жарым-жартылай ээси болосуз, функционалдык мүмкүнчүлүктөрүңүзгө байланыштуу бардык өнүм жыйындарына катышып, сунуштарды киргизип, өзүңүз чечим кабыл аласыз. Өзүңүз күн сайын колдоно турган буюм жасоо абдан сонун, бирок сизден жакшыраак адамдар үчүн код жазуу - бул укмуштуудай сезим (сарказм жок).

Бул өзгөрүүлөрдүн бардыгын чыгаргандан кийин, биз оң пикир алдык, жана бул абдан, абдан жакшы болду. Бул шыктандыруучу. Рахмат! Дагы жаз.

Эске сала кетейин, глобалдык өзгөрмөлөрдөн кийин биз архитектураны өзгөртүүнү жана прокси катмарды өзүнчө инстанцияга бөлүүнү чечтик. "Эки түйүндүү" архитектура буга чейин коомдук бета тестирлөө түрүндө чыгарылган. Эми ага каалаган адам которулуп, мобилдик Habrды жакшыртууга жардам бере алат. Бүгүнкү күндө бардыгы ушул. Мен комментарийлерде бардык суроолоруңузга жооп берүүгө кубанычта болом.

Source: www.habr.com

Комментарий кошуу