Habr урд талын хөгжүүлэгчийн бүртгэлүүд: дахин засварлах, тусгах

Habr урд талын хөгжүүлэгчийн бүртгэлүүд: дахин засварлах, тусгах

Хабрыг дотроос нь хэрхэн зохион байгуулж, ажлын урсгалыг хэрхэн зохион байгуулж, харилцаа холбоог хэрхэн зохион байгуулж, ямар стандартыг ашигладаг, кодыг энд ерөнхийд нь хэрхэн бичсэнийг үргэлж сонирхож байсан. Аз болоход, би саяхан хабра багийн нэг хэсэг болсон тул ийм боломж олдсон юм. Гар утасны хувилбарын жижиг рефакторын жишээг ашиглан би энд урд талд ажиллах ямар байдаг вэ гэсэн асуултанд хариулахыг хичээх болно. Хөтөлбөрт: Habr дахь хувийн туршлагаас авсан соустай Node, Vue, Vuex болон SSR.

Хөгжлийн багийн талаар хамгийн түрүүнд мэдэх ёстой зүйл бол бид цөөхөн байгаа явдал юм. Хангалтгүй - эдгээр нь гурван фронт, хоёр ар тал, бүх Хабрын техникийн удирдагч - Баксли юм. Тэнд мэдээж шалгагч, загвар зохион бүтээгч, гурван Вадим, гайхамшигт шүүр, маркетингийн мэргэжилтэн болон бусад Бумбурумууд бий. Гэхдээ Хабрын эх сурвалжид зөвхөн зургаан хүн шууд хувь нэмэр оруулдаг. Энэ нь маш ховор тохиолддог - олон сая долларын үзэгчидтэй төсөл нь гаднаасаа аварга том аж ахуйн нэгж мэт харагддаг ч бодит байдал дээр зохион байгуулалтын хамгийн хавтгай бүтэцтэй тухтай стартап шиг харагддаг.

Бусад олон мэдээллийн технологийн компаниудын нэгэн адил Хабр нь Agile санаа, CI практикийг хүлээн зөвшөөрдөг, тэгээд л энэ. Гэхдээ миний бодлоор Хабр нь бүтээгдэхүүн болохоосоо илүү долгион хэлбэрээр хөгжиж байна. Тиймээс бид хэд хэдэн спринт дараалан ямар нэг зүйлийг хичээнгүйлэн кодлож, дизайн хийж, дахин дизайн хийж, ямар нэг зүйлийг эвдэж засч, тасалбарыг шийдэж, шинээр бий болгож, тармуур дээр гишгэж, хөл рүү нь буудаж, эцэст нь энэ функцийг гаргана. үйлдвэрлэл. Дараа нь тодорхой нам гүм, дахин төлөвлөлтийн үе, "чухал-яаралтай биш" квадратад байгаа зүйлийг хийх цаг ирдэг.

Яг энэ "улирлын гадуурх" спринтыг доор хэлэлцэх болно. Энэ удаад Habr-ийн гар утасны хувилбарыг дахин засварлах ажлыг багтаасан. Ерөнхийдөө компани үүнд их найдаж байгаа бөгөөд ирээдүйд Хабрын хувилгаан амьтны хүрээлэнг бүхэлд нь сольж, бүх нийтийн платформ шийдэл болох ёстой. Хэзээ нэгэн цагт дасан зохицох загвар, PWA, офлайн горим, хэрэглэгчийн тохиргоо болон бусад олон сонирхолтой зүйлс байх болно.

Даалгавраа тавьцгаая

Нэгэн удаа, жирийн нэгэн стенд дээр нэг нь гар утасны хувилбарын сэтгэгдлийн бүрэлдэхүүн хэсгийн архитектурын асуудлын талаар ярьжээ. Үүнийг харгалзан бид бүлгийн сэтгэлзүйн эмчилгээний хэлбэрээр бичил уулзалт зохион байгууллаа. Хаана нь өвдөж байна гэж бүгд ээлжлэн хэлж, бүгдийг цаасан дээр буулгаж, өрөвдөж, хэн ч алга ташаагүйг эс тооцвол ойлгосон. Үүний үр дүнд 20 асуудлын жагсаалт гарсан бөгөөд энэ нь гар утасны Хабр амжилтанд хүрэх урт бөгөөд хэцүү зам хэвээр байгааг тодорхой харуулсан.

Би хамгийн түрүүнд нөөцийн ашиглалтын үр ашиг, гөлгөр интерфейс гэж нэрлэгддэг зүйлд санаа зовж байсан. Өдөр бүр гэр, ажил, гэр гэсэн маршрутын дагуу би хуучин утсаа мэдээллийн хэрэгслээр 20 гарчиг харуулахыг хичээж байхыг харлаа. Энэ нь иймэрхүү харагдаж байсан:

Habr урд талын хөгжүүлэгчийн бүртгэлүүд: дахин засварлах, тусгахRefactoring хийхээс өмнө Mobile Habr интерфейс

Энд юу болоод байна? Товчхондоо, сервер нь хэрэглэгч нэвтэрсэн эсэхээс үл хамааран HTML хуудсыг хүн бүрт ижил байдлаар үйлчилдэг. Дараа нь үйлчлүүлэгч JS-г ачаалж, шаардлагатай өгөгдлийг дахин хүсэх боловч зөвшөөрөл авахаар тохируулна. Өөрөөр хэлбэл, бид нэг ажлыг хоёр удаа хийсэн. Интерфэйс нь анивчиж, хэрэглэгч сайн зуун нэмэлт килобайт татаж авсан. Нарийвчилсан байдлаар бүх зүйл илүү аймшигтай харагдаж байв.

Habr урд талын хөгжүүлэгчийн бүртгэлүүд: дахин засварлах, тусгахХуучин SSR-CSR схем. Зөвшөөрөл нь зөвхөн Node JS нь HTML үүсгэх завгүй, API руу прокси хүсэлт илгээх боломжтой үед C3 ба C4 үе шатанд л боломжтой.

Хабр хэрэглэгчдийн нэг нь тухайн үеийн манай архитектурыг маш нарийн тодорхойлсон байдаг.

Гар утасны хувилбар нь тэнэг юм. Би үүнийг байгаагаар нь хэлж байна. SSR болон CSR-ийн аймшигтай хослол.

Хичнээн гунигтай байсан ч бид үүнийг хүлээн зөвшөөрөх ёстой байсан.

Би сонголтуудыг үнэлж, Жира дээр "одоо муу байна, үүнийг зөв хий" гэсэн түвшний тайлбар бүхий тасалбар үүсгэж, даалгаврыг өргөн цар хүрээтэй байдлаар задлав.

  • өгөгдлийг дахин ашиглах,
  • дахин зурах тоог багасгах,
  • давхардсан хүсэлтийг арилгах,
  • ачаалах үйл явцыг илүү тодорхой болгох.

Өгөгдлийг дахин ашиглацгаая

Онолын хувьд, сервер талын дүрслэл нь хайлтын системийн хязгаарлалтаас болж зовохгүй байх гэсэн хоёр асуудлыг шийдвэрлэх зорилготой юм. ДЦГ-ын индексжүүлэлт хэмжигдэхүүнийг сайжруулах Шүлхий (зайлшгүй муудаж байна TTI). Сонгодог хувилбараар бол эцэст нь 2013 онд Airbnb дээр боловсруулсан жил (Backbone.js дээр хэвээр), SSR нь Node орчинд ажиллаж байгаа ижил изоморф JS програм юм. Сервер нь үүсгэсэн байршлыг хүсэлтийн хариу болгон илгээдэг. Дараа нь шингэн сэлбэх нь үйлчлүүлэгчийн талд тохиолддог бөгөөд дараа нь бүх зүйл хуудсыг дахин ачаалахгүйгээр ажилладаг. Хабрын хувьд текст контент бүхий бусад олон эх сурвалжуудын нэгэн адил серверийн дүрслэл нь хайлтын системтэй найрсаг харилцаа тогтоох чухал элемент юм.

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

Яагаад? Энэ асуултад яг тодорхой хариулт алга. Тэд серверийн хариуны хэмжээг нэмэгдүүлэхийг хүсээгүй, эсвэл бусад архитектурын асуудлаас болж, эсвэл зүгээр л унасангүй. Ямар нэг байдлаар серверийн хийсэн бүх зүйлийг дахин ашиглах нь маш тохиромжтой бөгөөд хэрэгтэй юм шиг санагддаг. Даалгавар нь үнэндээ өчүүхэн - төрийг зүгээр л тарьдаг Гүйцэтгэлийн контекст руу оруулах ба Vue үүнийг автоматаар үүсгэсэн байршилд глобал хувьсагч болгон нэмнэ: window.__INITIAL_STATE__.

Үүссэн асуудлуудын нэг нь мөчлөгийн бүтцийг JSON болгон хөрвүүлэх боломжгүй байдаг (дугуй лавлагаа); Ийм бүтцийг зүгээр л хавтгай аналогиар нь солих замаар шийдсэн.

Нэмж дурдахад, UGC контенттой харьцахдаа HTML-г эвдэхгүйн тулд өгөгдлийг HTML нэгж болгон хувиргах хэрэгтэй гэдгийг санах хэрэгтэй. Эдгээр зорилгоор бид ашигладаг he.

Дахин зурахыг багасгах

Дээрх диаграмаас харахад манай тохиолдолд нэг Node JS инстанс нь хэрэглэгчийн зөвшөөрөл олгодог API дахь SSR болон "прокси" гэсэн хоёр функцийг гүйцэтгэдэг. Энэ нөхцөл байдал нь зангилаа нь нэг урсгалтай, SSR функц нь синхрон байдаг тул JS код сервер дээр ажиллаж байх үед зөвшөөрөл өгөх боломжгүй болгодог. Өөрөөр хэлбэл, callstack ямар нэг зүйлд завгүй байх үед сервер өөрөө өөртөө хүсэлт илгээж чадахгүй. Бид төлөвийг шинэчилсэн боловч хэрэглэгчийн сессийг харгалзан үйлчлүүлэгчийн өгөгдлийг шинэчлэх шаардлагатай байсан тул интерфэйс тайрахаа больсон. Бид хэрэглэгчийн нэвтрэлтийг харгалзан програмдаа зөв өгөгдлийг анхны төлөвт оруулахыг заах шаардлагатай болсон.

Асуудлыг шийдэх хоёр л шийдэл байсан:

  • сервер хоорондын хүсэлтэд зөвшөөрлийн өгөгдлийг хавсаргах;
  • Node JS давхаргыг хоёр тусдаа жишээ болгон хуваах.

Эхний шийдэл нь сервер дээр глобал хувьсагч ашиглах шаардлагатай байсан бол хоёр дахь нь даалгаврыг гүйцэтгэх эцсийн хугацааг дор хаяж нэг сараар сунгасан.

Хэрхэн сонголт хийх вэ? Хабр ихэвчлэн хамгийн бага эсэргүүцэлтэй замаар хөдөлдөг. Албан бусаар бол санаанаас прототип хүртэлх мөчлөгийг хамгийн бага хэмжээнд хүртэл бууруулах гэсэн ерөнхий хүсэл байдаг. Бүтээгдэхүүнд хандах хандлага нь booking.com сайтын зарчмуудыг зарим талаар санагдуулдаг бөгөөд цорын ганц ялгаа нь Хабр хэрэглэгчийн санал хүсэлтийг илүү нухацтай авч үздэг бөгөөд хөгжүүлэгчийн хувьд ийм шийдвэр гаргахад тань итгэдэг.

Энэ логик болон асуудлыг хурдан шийдэх гэсэн өөрийн хүслийн дагуу би глобал хувьсагчдыг сонгосон. Мөн ихэвчлэн тохиолддог шиг та эрт орой хэзээ нэгэн цагт тэдний төлбөрийг төлөх ёстой. Бид бараг тэр даруй төлсөн: бид амралтын өдрүүдэд ажиллаж, үр дагаврыг арилгасан, бичсэн дараахь үхлийн болон серверийг хоёр хэсэгт хувааж эхлэв. Алдаа нь маш тэнэг байсан бөгөөд үүнтэй холбоотой алдааг дахин гаргахад амаргүй байв. Тийм ээ, энэ нь ичмээр юм, гэхдээ ямар нэг байдлаар бүдэрч, гиншиж, дэлхийн хувьсагчтай миний PoC үйлдвэрлэлд орж, шинэ "хоёр зангилаа" архитектур руу шилжихийг хүлээж нэлээд амжилттай ажиллаж байна. Энэ нь чухал алхам байсан, учир нь албан ёсоор зорилгодоо хүрсэн - SSR нь ашиглахад бүрэн бэлэн хуудсыг хүргэж сурсан бөгөөд UI илүү тайван болсон.

Habr урд талын хөгжүүлэгчийн бүртгэлүүд: дахин засварлах, тусгахРефакторингын эхний шатны дараа Mobile Habr интерфейс

Эцсийн эцэст гар утасны хувилбарын SSR-CSR архитектур нь дараахь дүр зургийг авчирдаг.

Habr урд талын хөгжүүлэгчийн бүртгэлүүд: дахин засварлах, тусгах"Хоёр зангилаа" SSR-CSR хэлхээ. Node JS API нь асинхрон оролт/гаралтад үргэлж бэлэн байдаг бөгөөд SSR функцээр хаагддаггүй, учир нь сүүлийнх нь тусдаа хувилбарт байрладаг. №3 асуулгын сүлжээ шаардлагагүй.

Давхардсан хүсэлтийг арилгах

Засвар хийсний дараа хуудасны анхны дүрслэл нь эпилепси үүсгэхээ больсон. Гэхдээ Хабрыг SPA горимд цаашид ашиглах нь төөрөгдөл үүсгэсэн хэвээр байна.

Учир нь хэрэглэгчийн урсгалын үндэс нь маягтын шилжилт юм нийтлэлийн жагсаалт → нийтлэл → сэтгэгдэл эсрэгээр, энэ гинжин хэлхээний нөөцийн хэрэглээг хамгийн түрүүнд оновчтой болгох нь чухал байсан.

Habr урд талын хөгжүүлэгчийн бүртгэлүүд: дахин засварлах, тусгахНийтлэлийн тэжээл рүү буцах нь шинэ дата хүсэлтийг өдөөж байна

Гүн ухах шаардлагагүй байсан. Дээрх дэлгэцийн зураг дээр програм нь буцааж шударах үед нийтлэлүүдийн жагсаалтыг дахин хүсч байгааг харж болно, мөн хүсэлтийн явцад бид нийтлэлүүдийг харахгүй байгаа нь өмнөх өгөгдөл хаа нэгтээ алга болсон гэсэн үг юм. Өгүүллийн жагсаалтын бүрэлдэхүүн хэсэг нь орон нутгийн төлөвийг ашигладаг бөгөөд устгах үед үүнийг алддаг бололтой. Үнэн хэрэгтээ энэ програм нь дэлхийн төлөвийг ашигладаг байсан боловч Vuex архитектурыг толгой дээр нь барьсан: модулиуд нь хуудсуудтай холбогддог бөгөөд тэдгээр нь эргээд чиглүүлэлтүүдтэй холбоотой байдаг. Түүнээс гадна, бүх модулиуд нь "нэг удаагийн" байдаг - дараагийн хуудсанд зочлох бүрт модулийг бүхэлд нь дахин бичсэн болно.

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

Нийтдээ бид модультай байсан Нийтлэлийн жагсаалттөрлийн объектуудыг агуулсан дугаар зүйл болон модуль Хуудасны нийтлэл, энэ нь объектын өргөтгөсөн хувилбар байсан дугаар зүйл, төрлийн Нийтлэл дүүрэн. Ерөнхийдөө энэ хэрэгжилт нь өөрөө ямар ч аймшигтай зүйл агуулдаггүй - энэ нь маш энгийн, бүр гэнэн гэж хэлж болно, гэхдээ маш ойлгомжтой. Хэрэв та маршрутаа өөрчлөх болгондоо модулийг дахин тохируулбал түүнтэй хамт амьдрах боломжтой. Гэсэн хэдий ч, жишээ нь нийтлэлийн тэжээл хооронд шилжих /feed → /бүгд, хувийн тэжээлтэй холбоотой бүх зүйлийг хаях баталгаатай, учир нь бидэнд зөвхөн нэг л байдаг Нийтлэлийн жагсаалт, үүнд та шинэ өгөгдөл оруулах шаардлагатай. Энэ нь биднийг дахин хүсэлтийн давхардал руу хөтөлж байна.

Энэ сэдвээр ухаж төнхөж чадсан бүхнээ цуглуулсны эцэст би төрийн шинэ бүтцийг боловсруулж, хамт олондоо танилцуулсан. Хэлэлцүүлэг удаан үргэлжилсэн боловч эцэст нь дэмжсэн маргаан эргэлзээг давж, би хэрэгжүүлж эхэлсэн.

Шийдлийн логик нь хоёр үе шаттайгаар хамгийн сайн илчлэгддэг. Эхлээд бид Vuex модулийг хуудаснаас салгаж, чиглүүлэлтүүдтэй шууд холбохыг оролддог. Тийм ээ, дэлгүүрт бага зэрэг мэдээлэл байх болно, хүлээн авагчид арай илүү төвөгтэй болох болно, гэхдээ бид нийтлэлийг хоёр удаа ачаалахгүй. Гар утасны хувилбарын хувьд энэ нь магадгүй хамгийн хүчтэй аргумент юм. Энэ нь иймэрхүү харагдах болно:

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

Хэрэв нийтлэлийн жагсаалтууд олон маршрутын хооронд давхцаж байвал бид объектын өгөгдлийг дахин ашиглахыг хүсвэл яах вэ? дугаар зүйл шуудангийн хуудсыг хувиргах Нийтлэл дүүрэн? Энэ тохиолдолд ийм бүтцийг ашиглах нь илүү логик байх болно:

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

Нийтлэлийн жагсаалт Энэ бол зүгээр л нэг төрлийн нийтлэлийн сан юм. Хэрэглэгчийн сессийн үеэр татаж авсан бүх нийтлэл. Бид тэдэнд маш болгоомжтой ханддаг, учир нь энэ бол станцуудын хооронд метроны хаа нэгтээ өвдөлтөөр татагдсан байж болзошгүй замын хөдөлгөөн бөгөөд бид хэрэглэгчийг өмнө нь байгаа өгөгдлийг ачаалахыг албадах замаар дахин ийм зовлон учруулахыг хүсэхгүй байна. татаж авсан. Объект Нийтлэлийн дугаар Энэ нь зүгээр л объектуудын ID-уудын массив ("холбоос" гэх мэт) юм дугаар зүйл. Энэ бүтэц нь чиглүүлэлтийн нийтлэг өгөгдлийг хуулбарлах, объектыг дахин ашиглахаас зайлсхийх боломжийг олгодог дугаар зүйл Өргөтгөсөн өгөгдлийг нэгтгэх замаар шуудангийн хуудсыг үзүүлэх үед.

Өгүүллийн жагсаалтын гаралт мөн илүү ил тод болсон: давтагч бүрэлдэхүүн хэсэг нь нийтлэлийн ID-тай массиваар давтагдаж, өгүүллийн өдөөгч бүрэлдэхүүнийг зурж, Id-г тулгуур болгон дамжуулж, хүүхдийн бүрэлдэхүүн хэсэг нь эргээд шаардлагатай өгөгдлийг олж авдаг. Нийтлэлийн жагсаалт. Таныг нийтлэлийн хуудас руу ороход бид аль хэдийн байгаа огноог авах болно Нийтлэлийн жагсаалт, бид дутуу өгөгдлийг олж авах хүсэлтийг гаргаж, зүгээр л одоо байгаа объект руу нэмнэ.

Энэ арга нь яагаад илүү дээр вэ? Миний дээр бичсэнчлэн энэ арга нь татаж авсан өгөгдөлд илүү зөөлөн бөгөөд дахин ашиглах боломжийг танд олгоно. Гэхдээ үүнээс гадна энэ нь ийм архитектурт төгс тохирох зарим шинэ боломжуудын замыг нээж өгдөг. Жишээлбэл, нийтлэлүүдийг гарч ирэх үед нь санал асуулга авч, тэжээлд ачаалах. Бид хамгийн сүүлийн үеийн нийтлэлүүдийг "хадгалах" хэсэгт байрлуулж болно. Нийтлэлийн жагсаалт, шинэ ID-н жагсаалтыг тусад нь хадгал Нийтлэлийн дугаар мөн энэ тухай хэрэглэгчдэд мэдэгдэх. "Шинэ нийтлэлүүдийг харуулах" товчийг дарахад бид одоо байгаа нийтлэлийн жагсаалтын эхэнд шинэ ID оруулах бөгөөд бүх зүйл бараг ид шидтэй ажиллах болно.

Татаж авах нь илүү тааламжтай байх болно

Рефакторын бялуу дээрх мөстөлт нь араг ясны тухай ойлголт бөгөөд энэ нь удаан интернетээр контент татаж авах үйл явцыг бага зэрэг жигшүүртэй болгодог. Энэ асуудлаар ямар ч хэлэлцүүлэг хийгээгүй бөгөөд санаанаас прототип хүртэл хоёр цаг үргэлжилсэн. Дизайн нь бараг өөрөө зурсан бөгөөд бид өгөгдөл хүлээж байхдаа энгийн, бараг л анивчихгүй div блокуудыг үзүүлэхийг бүрэлдэхүүн хэсгүүддээ зааж өгсөн. Субъектив байдлаар ачаалах энэ арга нь хэрэглэгчийн бие дэх стресс дааврын хэмжээг бууруулдаг. Араг яс нь иймэрхүү харагдаж байна.

Habr урд талын хөгжүүлэгчийн бүртгэлүүд: дахин засварлах, тусгах
Habraloading

Тусгаж байна

Би Хабре хотод зургаан сар ажилласан ч найзууд маань одоо хүртэл асуудаг: Тэнд ямар таалагдаж байна вэ? За, тав тухтай - тийм ээ. Гэхдээ энэ бүтээлийг бусдаас ялгарах нэг зүйл бий. Би бүтээгдэхүүндээ огт хайхрамжгүй ханддаг, хэрэглэгчид нь хэн болохыг мэддэггүй, ойлгодоггүй багуудад ажилласан. Гэхдээ энд бүх зүйл өөр байна. Энд та хийж буй зүйлийнхээ хариуцлагыг мэдэрдэг. Онцлогыг хөгжүүлэх явцад та хэсэгчлэн түүний эзэмшигч болж, өөрийн үйл ажиллагаатай холбоотой бүх бүтээгдэхүүний уулзалтад оролцож, санал хүсэлтээ гаргаж, өөрөө шийдвэр гаргадаг. Өөрөө өдөр тутам хэрэглэдэг бүтээгдэхүүнээ хийх нь үнэхээр гайхалтай, гэхдээ чамаас илүү чадвартай хүмүүст зориулж код бичих нь үнэхээр гайхалтай мэдрэмж юм (ишиггүй).

Эдгээр бүх өөрчлөлтийг гаргасны дараа бид эерэг санал хүсэлтийг хүлээн авсан бөгөөд энэ нь маш, маш сайхан байсан. Энэ нь урам зориг өгч байна. Баярлалаа! Илүү их бичээрэй.

Глобал хувьсагчийн дараа бид архитектурыг өөрчилж, прокси давхаргыг тусдаа жишээ болгон хуваарилахаар шийдсэн гэдгийг сануулъя. "Хоёр зангилаа" архитектур нь нийтийн бета туршилтын хэлбэрээр аль хэдийн гарсан байна. Одоо хэн ч үүн рүү шилжиж, гар утасны Habr-г сайжруулахад бидэнд туслах боломжтой. Өнөөдрийн хувьд энэ л байна. Би таны бүх асуултанд сэтгэгдэл дээр хариулахдаа баяртай байх болно.

Эх сурвалж: www.habr.com

сэтгэгдэл нэмэх