Установяване на нов стандарт за предни услуги

В един идеалистичен свят пренаписването на приложения би било оптималното решение за повечето проблеми с програмирането. Проблеми с наследството? Пренапишете ги! Загубен контекст на това, което включва услугата? Препишете вашето разбиране! Въпреки това, такъв наивен подход за решаване на подобни проблеми не винаги е правилният начин, като се имат предвид ограниченията в реалния свят, като фиксирани количества време за завършване на проекти и извличане на приходи (на свой ред плащане на нашите заплати!), за да поддържаме инерцията на проекта.

Тогава някой може да попита: „Защо трябва да се заемем с този проект, за да пренапишем нашата услуга WordPress за предния край?“

Резултатът за нас, обобщен в един ред: „Установяване на нов стандарт за предни услуги“

Установяване на нови стандарти

„Установяването на нов стандарт“ тук предполага основна промяна в нашата организация относно начина, по който гледаме на нашите предни приложения и предизвикване на съществена реформа, за да предизвика вълни от промяна към по-добро. Към момента на предлагане на пренаписването на приложението екипите на Viki вече бяха изпробвали различни инструменти. Един такъв инструмент беше ReactJS, който беше използван в „основния сайт на Viki“ и в по-голяма степен „Soompi Awards“, разклонен сайт от Soompi, който използва React-router за създаване на Single Page Application (SPA).

С течение на времето открихме, че React е по-добър от другите инструменти, които използвахме за предни компоненти. Например, едно предимство, което открихме, беше, че React може да се използва за създаване на компоненти с много малко свързване с основния технологичен стек. Този потенциал за повторна употреба беше по-добър от нашето използване на компоненти на CoffeeScript, което беше свързано с друго приложение Ruby on Rails (RoR).

Горното подчертава идеята за изграждане за повторна употреба между несвързани услуги на непосредствения екип и като разширение компанията. Чрез изграждането на повече модели в същия дух като горния, ние се стремим към изграждането на „шаблон“ от инструменти, които можем да използваме за всички предни услуги. Това е от голяма полза за екипа, тъй като превключването на контекста е сведено до минимум, когато членовете на екипа се преназначават между различни проекти.

Манталитетът се разшири отвъд технологичния стек - разгледахме натрупаните подобрения на производителността, които направихме в различни услуги, и ги приложихме в това пренаписване, за да разрешим проблеми с производителността, които открихме в нашето текущо приложение WordPress. Инфраструктурата и мащабирането също се основават на опита, натрупан от изграждането на микроуслуги с помощта на AppEngine, където наблюдавахме ползата от опростяването на основните инфраструктурни отговорности и умения на нашия екип, което ни позволява да се съсредоточим върху набори от функции, свързани с предния край.

Клиентски изглед като стандарт — SPA + Isomorphic

Започнахме нашето пренаписване с изследване на изобразения изглед за потребителите. Нашето WordPress приложение изобразява съдържание предимно от страната на сървъра. Това оставя клиентската страна като „неизползвана мина на ценни ресурси“. За тази цел решаваме да разгледаме принципите на „архитектурата на обвивката на приложението“ или по-точния подход, SPA.

SPA се дефинира по следния начин — приложение, което преразглежда част от изгледа за различни комбинации от „контекст“. „Контекст“ тук може да се отнася до пълно квалифицирано име на домейн (FQDN), път и състояние (като бисквитки за използване на сесия или GET параметри, които обозначават опции за изобразяване на текущата страница).

За това пренаписване SPA би се превърнало в прилагане на логика от страна на клиента, която преразглежда уеб страницата, когато контекстът на страницата се промени. Това е в рязък контраст с нашето WordPress приложение, където всяка HTTP заявка, формирана от същия „контекст“, води до новоизобразен изглед от сървъра.

Някой може да попита: „Как преместването на отговорностите за изобразяване от страната на сървъра към страната на клиента допринася за по-добро потребителско изживяване?“ Отговорът на това се крие в оптимизирането на поведението на браузърите при зареждане на клиентски уеб страници. Традиционно зареждането на страница връща HTML отговор от страната на сървъра на услугата, което от своя страна предоставя инструкциите за анализиране на браузъра. Това е последвано от изтегляне на различни активи (JavaScript, CSS и шрифт) и създаване на DOM елементи със свързаните обратни извиквания на събития (не е необходимо в този ред).

За SPA зареждането на първата страница прави същото, но следващите страници не водят до допълнителни разходи за презареждане и анализиране на активи, както и за пълния изглед. Това води до по-добро забавяне за зареждане на всяка страница поради по-малко активи за изтегляне и по този начин по-високи нива на удовлетвореност на потребителите и по-ниски разходи за честотна лента за нашите услуги.

Внедряване

Използвахме React-Router, за да създадем наш собствен SPA. Това беше направено чрез препращане към текущия контекст на страницата към различни компоненти, ориентирани към маршрута. Например, URL адрес с пътя като „/“ ще използва компонента за начален маршрут, докато URL адрес с пътя „/article/:id“ ще използва компонента за маршрут на статия. Промените в URL адреса чрез щракване върху вътрешни връзки в сайта ще задействат актуализация на използвания в момента компонент на маршрута.

Важно е да се отбележи, че различните общи функции на всяка страница не са свързани с компонентите на маршрута, за да се увеличи максимално повторното използване и да се улеснят бъдещите актуализации на тези функции. Тези функционалности могат да бъдат разделени на две области — компоненти на ниво страница и компоненти на ниво полезност.

Компонентите на ниво страница са както се наблюдава на фигура 1 по-горе, чрез елемента „Navbar“. Безопасно е да се предположи, че лентата за навигация не се различава между компонентите на маршрута за едно уеб приложение. Следователно, този тип функционалности трябва да се визуализират независимо от маршрутите, както се вижда в „renderRoutes“ по-горе.

Компонентите на ниво полезност са основните градивни елементи на приложението. Един такъв пример е компонент „Въвеждане“, който дава предупреждение, ако въведените символи надхвърлят ограничението, предадено чрез реквизитите на компонента. Този компонент може да се използва повторно при създаване на нов потребителски акаунт или писане на коментар към статия. Следователно би било разумно да се отдели от маршрута, като се осигурят многократно използвани компоненти в рамките на различни компоненти на маршрут или дори компоненти на ниво страница.

В допълнение към горното компонентите, ориентирани към маршрута, трябва да обхващат модела на обвивката на приложението. Това означава, че всеки компонент на маршрута трябва да бъде свързан с маршрут от страна на сървъра, който осигурява отговор (често JSON), който информира съответния компонент какво трябва да бъде изобразено. Може също да има идентификатори, независими от маршрута, като идентификатори в URL адреса (напр. „/article/1“, където „1“ е идентификаторът, а „article“ препраща към компонента на статията), които се предават в рамките на заявката към страната на сървъра за индивидуален отговор. На фигура 2 по-горе можем да видим как това е представено, където маршрут може да съществува в различни състояния, докато съдържанието не бъде извлечено.

SEO и изоморфизъм

Въпреки това, услуга, прилагаща само SPA, ще се сблъска с проблеми с оптимизацията за търсачки (SEO). Това е така, защото първоначалният HTML изход на страницата съдържа само „обвивката“ на SPA и няма съдържание, както се наблюдава на Фигура 2 по-горе. Ако някой робот, свързан със SEO, не поддържа изтеглянето, анализирането и изпълнението на активи на JavaScript, обхождането на страницата няма да доведе до смислени резултати от търсенето само от „черупката“.

За да разрешим това, въвеждаме концепцията за изобразяване от страна на сървъра за първоначалното зареждане и по същество създаваме изоморфно приложение. JavaScript двигател (напр. V8) се използва от страната на сървъра, за да изпълни абсолютно същата задача като клиентската страна за първоначалното зареждане. Това ни позволява да запазим архитектурата на обвивката на приложението, необходима за последващи промени в контекста на страницата. Благодарение на изобразяването на информация в рамките на първоначалното зареждане, ние позволяваме на ботовете да извличат значима информация, която искаме да свържем с нашите резултати от търсенето.

Стандартизиране на инфраструктурата – Google Cloud

Нека прегледаме нашата инфраструктура, преди да мигрираме към „Google App Engine“. Нашето WordPress приложение беше хоствано на няколко ръчно осигурени виртуални машини (докато бяха контейнеризирани с помощта на Docker) от облачен доставчик, затворено зад балансиращо натоварване. Тръбопроводът за непрекъсната интеграция + непрекъсната доставка (CICD) беше направен с помощта на вариант на Jenkins, с ръчно внедряване с помощта на вътрешно разработени скриптове. Що се отнася до статичните активи, като компилираните JS и CSS, бяха обслужвани от Amazon CloudFront като мрежа за доставка на съдържание (CDN).

Когато анализираме тези компоненти на нашата инфраструктура, забелязваме, че последният е напълно обзаведен от външен партньор. Тъй като CDN компонентът вече предоставяше предимствата, които търсехме при предоставянето на статични активи, поддържани и усъвършенствани сами по себе си, ние не се опитахме да работим върху подобряването на този компонент. Вместо това се съсредоточихме върху подобряването на инфраструктурата за тръбопровод за внедряване и приложение.

Част 1: CICD с Cloud Build и интеграции на IAM

За актуализациите на тръбопровода на CICD ние използвахме Cloud Build, предимно за мащабируемо CI изживяване. Това беше от съществено значение, тъй като нашият вътрешен CI беше хостван на една машина и щеше да страда от забавяне на производителността или дори прекъсвания, когато повече крайни потребители (разработчици) го използваха.

Друг плюс беше, че при използването на Cloud Build можехме да се възползваме от предимствата за App Engine, предоставени от същия партньор. Едно решаващо предимство беше използването на Cloud IAM, където можехме да използваме схема за привилегии, за да систематизираме работния процес чрез акаунти за услуги, използвани от различни инструменти на Google Cloud, както се вижда на Фигура 3. Това също означаваше, че по силата на това, че сме в същата екосистема , няма нужда да печете идентификационните данни в нашия CICD канал за акаунта на услугата, който извършва доставката или внедряването.

В допълнение към предоставянето на привилегии на акаунти за услуги, ние можем също да създадем персонализирани роли за различни нива на привилегии за всеки инженер. Това позволява на инженерите да имат достатъчно права за преглед, за да наблюдават изправността на приложението, но не и директни привилегии за внедряване, така че проверките и балансите да могат да бъдат интегрирани във формални процеси (като налагане на автоматизирани тестове преди автоматизирано внедряване или доставка) чрез нашата CICD линия. Като използваме това споразумение, можем да сведем до минимум човешката грешка, като гарантираме, че само акаунти за услуги могат да извършват определени действия, като например внедряване.

При използването на Cloud Build ние също така подготвяме различни конфигурации за различни среди, които се съпоставят с имена на клонове чрез съвпадение на регулярни изрази. С помощта на скриптове на обвивка, които регистрирахме, и задействания за уеб закачане към Cloud Build, разработчиците можеха или да поръчат „изграждане и повторно разполагане“ в етапа, или „изграждане и доставяне“ в производство, от тяхната локална конзола на обвивката. Редовните ангажименти, от друга страна, ще задействат само автоматизираните тестове. Обратната връзка за целия процес на компилация за различни конфигурации се предава към канал Slack — за необходимите коригиращи действия или за разделяне на трафика между изпратените компилации в Производството, след като доставката приключи.

Фигура 5 по-горе показва работния процес за нашата сцена за среда. Cloud Build ни позволява да изпълняваме задачи паралелно и можем да извличаме зависимости на подмодули, както и да инсталираме модули за тестови възли едновременно. Това е последвано от стартиране на нашия тестов пакет, след като горните изисквания са изпълнени. След успешното завършване на тестовете, активите се компилират и качват, с настройка на изображението на производствената среда и внедряване в нашето етапно приложение App Engine.

Част II: App Engine Flex и Stackdriver за наблюдение и регистриране

След това ще преминем към актуализациите за приложението, което ще се обслужва чрез App Engine. Когато оценявахме опциите, които имахме, не искахме нещо като „Compute Engine“, поради приликите с използването на IaaS като нашата предишна конфигурация. Kubernetes би бил по-добър избор поради по-високото ниво на абстракция в сравнение с Compute Engine и други подобни. Въпреки това, когато разглеждахме предложенията в индустрията, открихме, че PaaS, в този случай App Engine, е много по-желателно поради по-простия подход, който можехме да предприемем за мащабиране на приложението. Нашият екип може да се концентрира върху функциите на предния край, без да отделя твърде много време за разработване и поддържане на инфраструктурата.

В рамките на App Engine бяха представени два избора, „Стандарт срещу Flex“. App Engine Flex предлага по-голяма гъвкавост в езика за програмиране и библиотеките, където не изисква използването на библиотеки на доставчика за изпълнение на прости задачи, което ни позволява да предотвратим появата на заключване на доставчика. От друга страна, App Engine Standard обещава по-бързи времена за реакция при мащабиране, времена за внедряване и по-ниски разходи. В крайна сметка избираме App Engine Flex, поради проблемите с гъвкавостта, споменати по-горе. Това решение беше взето също така, за да не се повтарят същите грешки от нашата текуща главоблъсканица на WordPress, която включва тежко свързване на код с плъгини, които са ефективни само в собствената си екосистема.

За да внедрите нова версия на вашето приложение в App Engine за NodeJS, са необходими файловете `app.yaml` и `package.json`. `app.yaml` ще съдържа конфигурацията за използваните машини и логиката за мащабиране за приложението, докато `package.json` ще съдържа зависимостите, версията на възела и методологията за стартиране на приложението.

От обвивката можем да издаваме команди за внедряване с помощта на двата файла по-горе и да заменим текущата версия, която обслужва нашите потребители. Въпреки това, както беше обяснено в по-ранна глава, искахме само Cloud Build да има правата за внедряване или доставяне на приложението, за минимизиране на човешката грешка. Докато разгръщането за етапи не изисква никаква ръчна намеса, доставката за производствената среда изисква инженерът по внедряването да провери дали условията са правилни, преди да се извърши превключването на услугите на живо. Промените за производство се извършват с помощта на конзолата, както се вижда тук:

За всяка версия краткият хеш на ангажимента се използва като негова идентичност. Чрез идентифициране на всяка версия можем да контролираме внедряването чрез стартиране, спиране или оставяне на паралелни версии да работят едновременно чрез разделяне на трафика.

С това създадохме CICD тръбопровода в Cloud Build и използвахме App Engine, за да се възползваме от решенията за мащабиране с конзолата за внедряване, за да завършим работния поток на CICD за доставка от етапа до производството.

Изграждане на стандарт запроизводителност

Друг проблем, с който искахме да се заемем, беше производителността. Това, че производителността е отговорност единствено на страната на сървъра, е концепция от миналото. Съвременните уеб браузъри са в състояние да оптимизират производителността, като позволяват на уеб услугите като цяло да мащабират усилията за оптимизиране от страна на клиента.

И все пак, напредъкът на уеб технологиите не се намира само в царството на браузърите. Напредъкът в методологиите за скриптове от страна на клиента ни позволи да можем да използваме по-нови начини, за да подобрим изживяването на всеки потребител. Една такава концепция, която сме използвали, мързеливото зареждане, ни позволява да зареждаме съдържание само когато потребителят го преглежда, спестявайки честотна лента и изчислителни ресурси не само от страна на сървъра, но и чрез обработката му от POV на клиента.

По-долу ще споделим какви оптимизации са направени за подобряване на ефективността на сайта от страна на клиента и ще дадем съвети относно нивото на трудност.

Концепция №1: Отложено зареждане на синхронни скриптове, асинхронно зареждане на независими скриптове

Трудност при интегрирането: ⅕ (⅖ ако разчитате на `$( document ).ready()` от jQuery)

Подобрение на латентността: ⅗

Подобрение на честотната лента: - (Страницата все още зарежда същото съдържание)

Както се вижда на фигура 8 по-горе, включването на асинхронно или отложено зареждане към външни скриптове включва само HTML атрибут на DOM елемента „скрипт“, което го прави много лесна оптимизация върху текущо написан HTML или шаблони за преглед. Но как тези свойства помагат при зареждането на страница?

На фигура 8. по-горе виждаме, че както „defer“, така и „async“ не блокира изобразяването на страницата, позволявайки събитието „DOMContentLoaded“ на обекта на документа да се задейства много по-рано, отколкото ако има блокиращи скриптове в страницата. Това означава за потребителите на нашия сайт, че не е необходимо да гледат бял екран за продължителни периоди, докато страницата се зарежда, което се изразява в по-добро възприемане на латентността на страницата, дори ако времето за пълно зареждане остава същото. Както съобщава KissMetrics в 2011 г., „1 секунда забавяне на отговора на страницата може да доведе до 7% реализации“. Това е особено важно за нас като сайт за публикации, където можем да привлечем вниманието на потребителите много по-рано и да намалим степента на отпадане.

За „асинхронни“ скриптове това са скриптове, които трябва да се използват, ако имате независими компоненти, тъй като времето за зареждане+разбор+изпълнение заедно не е детерминистично и не чака друго съдържание или потенциални зависимости. Скриптовете „Defer“ предлагат лека версия на „async“, като предлагат анализиране и изпълнение на скриптове в реда, в който е деклариран в страницата, независимо кога скриптовете са извлечени. Това ни позволява да предотвратим блокирането при изобразяване на страницата, като същевременно запазим зависимостите между извлечените активи на скрипта.

За съществуващи кодови бази, които са силно вкоренени в популярната JavaScript библиотека jQuery и използването на $(document).ready(), внедряването на „defer“ в скриптовия елемент jQuery ще бъде малко по-предизвикателно. Това е така, защото $ е недефиниран в момента на анализиране на HTML документа.

Позовавайки се на фиг. 9 по-горе, това може да бъде променено, за да се използва събитието „DOMContentLoaded“ на обекта на документа, което обсъдихме накратко. Чрез използването на това събитие, същото поведение при инициализация от използването на $(document).ready() може да бъде копирано, без да се налага да се прибягва до блокиране на времето за изобразяване на DOM от зареждане на библиотеката jQuery.

Концепция №2: Мързеливо зареждане на изображения, адаптивни изображения и прогресивно зареждане на изображения

Трудност на интегрирането: ⅖

Подобрение на латентността: ⅘

Подобрение на честотната лента: ⅗

Мързеливото зареждане на изображения ни позволява да забавим зареждането на активите на изображения в рамките на страницата, докато потребителят не превърти до даденото съдържание. Това е особено важно за Soompi, където всяка страница е изпъстрена с изображения, като се има предвид, че искаме да предложим възможност на потребителите да изследват всяка страница и да продължат към други страници. Като активираме отложено зареждане на изображения, можем да спестим честотна лента както от страната на сървъра, така и от страната на клиента, спестявайки изчислителни разходи и ресурси, както и по-добро потребителско изживяване от по-ниско използване на ресурсите на клиентите (особено това на ограничени мобилни данни в днешната епоха).

Друг проблем е, че адаптивният уеб дизайн е направен, за да се гарантира, че изгледът е оптимален за крайни потребители с различни размери на екрана. За елементите на изображението източниците на изображения остават едни и същи за различните портове за изглед, което води до по-малки екрани, зареждащи това, което може да се счита за изображения с по-висока разделителна способност, и загуба на честотна лента на клиента. За да оптимизираме това, можем да използваме адаптивни изображения, предоставени чрез атрибута „srcset” на img DOM елементи.

Чрез предоставяне на картографиране на размерите на порта за изглед към URL адресите на изображението за атрибута „srcset“, браузърът ще гарантира, че ще бъде заредена оптималната разделителна способност на изображението към екрана, извличайки същите предимства при спестяване на честотна лента като отложеното зареждане.

Дяволът обаче е в детайлите. Незабавно усилията за интегриране трябва да бъдат оставени настрана, за да се създаде тръбопровод в задната част за трансформиране на качените изображения към различните разделителни способности на изображенията. Що се отнася до предния край, дизайнерите и инженерите трябва да експериментират, за да постигнат подходящия компромис между качеството на изображението и честотната лента, евентуално повтаряйки и обратната връзка от потребителите.

Прогресивното зареждане предлага различно изживяване на потребителите в сравнение с отложеното зареждане и отзивчивите изображения. Подобно на отложеното зареждане на скриптове по-горе, това подобрява възприеманото забавяне на страницата. Това става чрез попълване на страницата с версии на изображенията с по-ниска разделителна способност и след това замяна на желаното изображение, след като то бъде извлечено. Правейки това, можем да покажем, че страницата е в състояние на непрекъснато изобразяване към крайния продукт, вместо да показваме липсващи корекции в страницата, където трябва да бъде съдържанието, което води до погрешни тълкувания, че няма напредък в зареждането на страницата или че страницата е повредена.

Бонус: Една допълнителна оптимизация за изображения, макар и по-зависима от задния край, е да се използва тип изображение, което вече е оптимизирано за зареждане на уеб страници — и за това имаме webp. В случая на Soompi използвахме услуга, изградена вътрешно за обслужване на webp изображения. Когато се използва заедно с браузър, който поддържа webp изображения, успяхме да извлечем спестяванията в размерите на файловете за зареждане на изображенията, спестявайки допълнително честотна лента както от страна на сървъра, така и от страната на клиента.

Не ни вярвайте просто на думата – цитирайки „проучване на webp“, „WebP обикновено постига средно 30% повече компресия от JPEG и JPEG 2000, без загуба на качество на изображението“

Концепция №3: Разделяне на код

Трудност на интегрирането: ⅘

Подобрение на латентността: ⅘

Подобрение на честотната лента: ⅘

Ранните прототипи на SPA представят дихотомия при зареждане на уеб приложението. Това изисква всички съществуващи компоненти на маршрута да бъдат заредени предварително. Това означава повече ресурси, изразходвани за зареждане и кеширане на активи, което прави инициализацията на страницата много по-дълга от останалата част от жизнения цикъл на SPA и дори традиционния изглед, изобразен от страна на сървъра.

Тази ситуация не е оптимална за нашата система за публикуване, а също и вероятно за много сайтове там. Някои от нашите потребители може да се интересуват само от четене на статии, към които има директни връзки от платформи на социални медии, а не да се интересуват от преминаване през сайта. Следователно искахме да използваме концепцията за разделяне на кода, за да гарантираме, че потребителите консумират минималните ресурси, които са им необходими за използване на нашето уеб приложение, като същевременно поддържаме основните предимства от използването на SPA.

Внедряването на разделяне на код върху SPA с изобразяване от страна на сървъра може да бъде обезсърчително за всеки, който е нов в тези концепции. Например създаване на логика за инструментиране на конструкцията на разделени на код компоненти в модула bundler (като Webpack) и след това гарантиране, че тези компоненти са подходящо групирани с правилните маршрути. Само това е подобно на създаването на нещо подобно на плъгин, за да се гарантира, че бъдещите разработчици могат да го внедрят интуитивно.

За наше щастие има обществени библиотеки, които вече са решили този проблем.

Както се вижда на Фигура 12 по-горе, ние използваме React-Loadable за създаване на компоненти на маршрут, които се импортират динамично както от страната на сървъра, така и от страната на клиента.

Всеки компонент на маршрута се зарежда само когато е необходим и ще покаже лека анимация за зареждане, ако отнема известно време за извличане на активите на компонента на маршрута.

Подобрения на цялостната производителност

Една снимка говори повече от хиляда думи. Като такива, ние решихме да покажем показателите, които бяха измерени между приложението преди и след пренаписването, което разкрива резултатите от нашите усилия през последната година по този проект.

Позовавайки се на концепциите за подобрение — подобренията в производителността по-горе могат да бъдат разделени на три категории: Възприемано забавяне, забавяне и спестяване на честотна лента.

От горната диаграма възприеманото забавяне ще бъде свързано с времето за зареждане на DOM съдържание, индекса на скоростта и времето за стартиране на рендиране (отговор на сървъра), където видяхме подобрения, вариращи между 35% до 71% в сравнение с по-старото приложение. Индексът на скоростта, както е дефиниран от Speedcurve, инструментът, използван за горното измерване, „„е важна мярка за изживяването на потребителя, докато страницата се зарежда““. Въпреки че времето за начално изобразяване не е свързано с нашите оптимизации по-горе, то е отражение на това как подобренията на други „свързани бек-енд услуги за WordPress“, направени паралелно с този проект, могат да се вградят в потребителското изживяване на страницата.

Закъснението на страницата, от друга страна, може да бъде представено чрез времето за зареждане на страницата и времето за пълно зареждане, при което се наблюдава подобрение на времето за зареждане съответно с 56% и 42%.

За спестяване на честотна лента, той може да бъде представен от общия размер на различно заредено файлово съдържание. От тези показатели наблюдаваме 65% спестяване на честотна лента в общ размер на файла, като същевременно осигуряваме същото потребителско изживяване!

Придвижване напред

Досега сме установили нови стандарти за предни приложения чрез пренаписване на предната услуга на Soompi.

това ли е краят

Отразявайки нашето по-ранно осъзнаване, че React е по-приятелски настроен към компонентите за многократна употреба, същото осъзнаване беше направено и за сега денонсираните компоненти на CoffeeScript, всъщност само преди няколко години! Това се дължи на факта, че RoR се използва често в сървърната страна по това време. Тъй като Ruby е синтактично подобен на CoffeeScript, той направи превода на свързан код между Ruby кода на сървъра и CoffeeScript на клиента по-лесен, намалявайки превключването на контекста за разработчиците и по този начин превръщайки разработката в много по-добро изживяване.

Като се има предвид как тенденциите са паралелни в горното, изглежда, че приемането на хомогенни решения за всяка услуга до буквата е опасна идея. Това обаче не означава, че това, което сме направили, е в противоречие с това, което сме постигнали. Чрез изграждането на „базова плоча“ от решения, които могат да се използват в днешния контекст, ние полагаме основата за проучени принципи като стандарт, така че решенията, изградени за днес, да са взаимозаменяеми с тези, възникващи в бъдещето.

Друго съдържание на Soompi

Уау, това беше дълго! Надяваме се, че ви е харесало пътуването, през което преминахме досега. Другите глави от нашето обучение са описани подробно по-долу:

Потвърждение

Уеб екипът беше неразделна част от това пренаписване, като имаше както инженерите, които поддържаха наследеното приложение, за завършване на пренаписването, така и в споделянето на този опит. Те са както следва:

Айша (github) — принцеса воин от предния край, която ръководеше атаката в това пренаписване

Amiel (github) — нашият вътрешен гений на WordPress, а също и ReactJS pro

Weiyuan (github | linkedin) — Някакъв случаен човек, който също е направил back-end

Също така, признателност към следните инженери/продуктови мениджъри, които участваха в пренаписването на това приложение

Ерик(linkedin) — Инженерен мениджър на уеб екипа!

Джонатан (linkedin) — Продуктов мениджър на невероятното.