mar-ek1
2020-02-03 11:53

"Własny framework" nigdy nie brzmi dobrze kiedy klient opowiada o swoich projektach. Dołóżmy do tego takie zwroty jak "spójny styl" i "uniwersalne komponenty" i tragedia gotowa.

Zgodnie z trendem powinienem teraz zalinkować do swojego bloga, na którym bym umieścił dalszą część tekstu, ale niestety daję od razu całość :(

Pracujemy z klientem jako część jego działu IT więc trochę rzeczy robią nasi developerzy, trochę developerzy klienta, korzystamy z tego co oni itd.
I jedną z rzeczy, która jest obecna w ich firmie to framework do frontendu, zbudowany w oparciu o jakieś gotowe rozwiązanie ale mocno zmodyfikowany. Zamysł był taki, ze każdy zespół może go po prostu wziąć i użyć gotowe komponenty angularowe/knockoutowe i bez pisania własnych styli czy zachowań mieć gotowy layout, do którego tylko pcha dane albo jakieś customowe zachowania. I za utrzymanie tego odpowiedzialny jest działa UI/UX.

No i akurat w tym momencie robię typowy korpo-projekcik czyli "excel w przeglądarce". Na początku, jakiś rok temu, sami wszystko musieliśmy naklepać, potem wróciliśmy do tego projektu z nowymi funkcjonalnościami i właśnie ten UIowy framework zaczął być portowany na Angulara, zmienił się firmowy layout i osoby z działu odpowiedzialnego za ten framework zgodziły się na przeportowanie również naszej aplikacji na nową wersję.

Pomijając jakość kodu wygenerowanego w trakcie tej migracji (nie byli częścią zespołu więc też dużego refactoru nie robili) to okazało się, że aplikacja, która działała całkiem nieźle (sporo czasu spędziliśmy na optymalizacji dużej rozwijanej tabeli) zaczęła mocno obciążać przeglądarkę.

Dla nabrania kontekstu opowiem pokrótce jak wygląda główna część aplikacji:
Na stronie głównej użytkownikowi wyświetlają się pewne pozycje zawierające ok. 10 kolumn, zebrane w grupy po kilka, kilkanaście sztuk. Grupy są albo automatycznie utworzone albo dodane przez userów. I dla grup tworzonych ręcznie można z poziomu tego ekranu dodawać albo usuwać pozycje. Gdzie usuwanie jest robione z menu kontekstowego przy każdym z wierszy.

I dla kilkunastu rekordów jest w miarę ok. Jednak jak dodaliśmy więcej funkcji dla grup i zacząłem je sobie dodawać i modyfikować to okazało się, że przy kilkudziesięciu wpisach strona staje się praktycznie nieużywalna.
No to zacząłem sprawdzanie czy na pewno wszystkie komponenty, które tylko coś wyświetlają mają ustawione ChangeDetectionStrategy.OnPush itd.
I w końcu przeszedłem do przeglądania tego co jest wyrenderowane w przeglądarce - bo większość problemów z UI jest kiedy elementów na stronie mamy za dużo. A przy takich tabelach to nie trudno o taki problem.

Spodziewałem się wielu głupich problemów z wyświetlaniem niepotrzebnych elementów. Ale to co znalazłem przerosło moje granice pojmowania.

Otóż wyszło na to, że dla każdego wiersza w tabeli dodawane jest do DOMu osobne menu kontekstowe. Ale to jeszcze można zrozumieć jakoś. Zacząłem więc sprawdzać jakie style mają te menu. I tutaj zagadka się rozwiązała. Otóż każde z tych menu miało ustawione visibility: hidden zamiast display: none. Każdy kto coś tam robił we frontendzie pewnie już wie o co chodzi.
Mianowicie kiedy zmieniamy visibility to przeglądarka nadal renderuje taki element na stronie, przydziela mu miejsce itd. Po prostu ostatecznie jest on niewidoczny. Jeżeli ustawimy display to taki element nie jest brany pod uwagę przy renderowaniu.
Każde takie menu to ok. 10 elementów HTML. Dla 100 wpisów daje nam to 1000 dodatkowych elementów, ze swoimi eventami i właściwościami, które są dodatkowo stale sprawdzane przez Angulara. Poza tym te menu mają pododawane wiele globalnych eventów w dokumencie. A niezależnie od tego ile ich jest to widoczne dla użytkownika będzie zawsze max 10 z nich. Bo można mieć tylko jedno menu otwarte w tym samym momencie.

Zadałem więc pytanie osobie odpowiedzialnej za ten korporacyjny cud techniki - "WHY?!". I okazuje się, że wszystko zostało w ten sposób zrobione.... żeby animacja otwierania ładnie wyglądała. Trwa ona 0,25sek i dopóki nie usłyszałem, że tam jest to nawet nie wiedziałem, że to się animuje.

Zacząłem dzisiaj też mocniej przeglądać stronę pod tym kątem - czy może jeszcze gdzieś się nie kryją takie cuda. I szybko odkryłem, że plan był zakrojony na szeroką skalę.
Bo mamy też na tej stronie kilka popupów (ot np. potwierdzenie czy chcesz usunąć coś albo pozwalające zmienić nazwę albo dodać nową pozycję).
Więc ogólnie jest ich powiedzmy 5-6 sztuk.
I okazuje się, że w przypadku popupów jest jeszcze weselej. Bo to już nie mamy visibility: hidden. Tutaj już wjeżdża gruby kaliber w postaci opacity: 0. Czyli wszystkie one są renderowane na stronie, po czym przeglądarka musi ustawić im przeźroczystość.
Zapytacie pewnie po co takie wynalazki? Otóż wszystko po to aby popup mógł mieć piękną, półsekundową animację pojawiania się.

Zrozumiałbym gdyby ten framework był robiony przez zewnętrzny zespół, który nie ma wizji tego jakie projekty się robi w firmie. Albo gdyby nasz projekt z dużym wolumenem danych był jedynym takim, a reszta to zwykłe appki z paroma polami i po prostu mamy "sytuację wyjątkową".
Ale nie - większość projektów w firmie klienta to są własnie takie excele w przeglądarce. To co my mamy to chyba najlżejszy z nich bo u nas nie można np. edytować danych w wierszach. I zespół UX/UI siedzi razem z resztą developerów. I przygotowuje teoretycznie komponenty dla właśnie tych projektów...

{edit}
Na szczęście po tym jak powiedziałem na standupie z czym jest problem, jaka biblioteka jest tutaj źródłem, dlaczego i co konkretnie jest z nią nie tak to zdjąłem z siebie dalszą walkę z optymalizacją. Teraz lider ma iść do odpowiednich osób i pogadać co zepsuli.
{/edit}

Jednak nadal trzeba się męczyć ze stroną, która pożera tyle zasobów co Visual Studio.
Mimo, że CSS to nie programowanie to jednak programistyczne serce krwawi.

cerrato

jak to w korpo - wystarczy w odpowiednim momencie powiedzieć "nie nasza wina" - a nie lepiej (skoro ekipa za to odpowiedzialna ma głęboko gdzieś) wysłać "życzliwe" zgłoszenie do przełożonego z opisem sytuacji?

mar-ek1

@cerrato: Faktycznie to źle ująłem. Wyjaśniłem na standupie co jest grane, jaka biblioteka i konkretnie dlaczego zawiniła i po prostu zdjąłem z siebie optymalizację i lider ma iść do odpowiednich ludzi i przekazać, że zje...zepsuli. Więc to nie tak, że po prostu powiedziałem "nie moje = nie moja sprawa"

cerrato

No teraz to brzmi lepiej. Bo wymowa pierwotnego tekstu jest w stylu "nie mój problem, mam to w tyłku" :P

czysteskarpety

Ja mam wrażenie że to jest kwestia cebulactwa firm, ma być tanio i tyle, potem się robi ulepy, byle działało, każdy kto to przejmuje to gasi pożar po poprzedniej firmie.

mar-ek1

@czysteskarpety: to bym rozumiał gdyby ktoś na zlecenie robił byle działało. Ale tutaj klient sam robi swój framework na własny użytek. Nad wszystkim pracują jego ludzie w UK, którzy pracują tam od paru lat i prawdopodobnie pipracują kolejne 10+ lat z tym kodem. Nic nie jest jakim odziedziczonym kodem po Hindusach albo po zespole, który poprawiał po zespole, który poprawiał po zespole...

czysteskarpety

@mar-ek1: Wiesz, pewnie nie tyle klient sam robi co zatrudnia zespół w którym są osoby odpowiadające za taski i wdrożenie, ocenę kodu, za określone stawki itp. pewnie tutaj jest problem.

mar-ek1

Tzn chodzi o to, że jest to zespół bezpośrednio od klienta, to są jego pracownicy, którzy normalnie siedzą razem z resztą, mają tych samych testerów, te same budżety itd. Jesteśmy tam regularnie co kilka tygodni i z nimi rozmawiamy, siedzimy. I pracują albo będą pracować tam w firmie 10+ lat bo mniej więcej tyle u klienta ludzie pracują. Więc nawet nie jest to na zasadzie "aaa i tak zaraz spadam to byle działało".

czysteskarpety

@mar-ek1 I pracują albo będą pracować tam w firmie 10+ lat bo mniej więcej - pewnie pracują za zasadzie, czy się stoi, czy sie leży pensja sie należy, jak nikt ich nie rozlicza z kodu, po co się wysilać ;)

mar-ek1

Pewnie tak ;) Tylko dziwię się, że userzy nie przychodzą do nich z narzekaniem albo od razu z widłami :P Bo mimo, że dział IT jest duży to robi tak naprawdę soft na wewnętrzny użytek całej firmy, której pozostali pracownicy siedzą na tym samym piętrze albo piętro wyżej/niżej.

mar-ek1

Budżet i czas też nie są u nich problemem bo milion albo miesiąc w tą czy w tamtą nie są niczym co by powodowało jakieś szczególne przejęcie się.
Więc mam wrażenie, że tutaj jest jedynie problem mentalności "byle nie musieć za dużo nad tym siedzieć albo za mocno nad tym myśleć".

jarekr000000

Zgodnie z trendem powinienem teraz zalinkować do swojego bloga, już za to plus się nalezy :-). Btw. CSS to jużod dawna jest programowanie, nie dość, że jest "dyskusyjnie - ale jednak" turing complete, to normalnym jest kompilator/preprocesor CSS, a w jakimś {XYZ}CSS można mieć wielowarstwową architekturę i biblioteki :-)

Miang

a ja inna teorię mam - przylazł młody, zdolny z koneksjami, chce sie wykazać żeby załatwiony przez wujka awans miał jakąś podkładkę i wymyśla pierdoły

mr_jaro

@mar-ek1: najlepsze jest to, że nic nie stoi na przeszkodzie, żeby najpierw zmienić displaya a dopiero potem odpalić animacje :D

mar-ek1

Owszem - działa, nawet testowałem dodając to jakoś naokoło, bo wolałem żeby animacja nie działała niż strona za wolno chodziła ;) Ale "frontendowiec" twierdzi, że to jest powód takiego rozwiązania :P

BraVolt

Kwiatek do kożucha = animacje na stronie (chyba, że strona ma właśnie pokazywać animacje: edukacja, Disney, memy itp). Szczyt "profesjonalizmu" to powitalna animacja pełnoekranowa której w przeglądarce na smartfonie nie da się zamknąć.

mar-ek1

@BraVolt: Tutaj chodzi o takie drobne animacje elementów, jak np. płynne rozwinięcie menu, które trwa <1sek, a nie animacje całej strony.

mr_jaro

@mar-ek1: bo to nie frontendowiec tylko designer :D Ktoś kto się szczyci byciem frontendowcem musi znać takie podstawy.

mar-ek1

Zgadzam się, chociaż designer też z niego średni, a jednocześnie to najbardziej ogarnięta osoba od frontendu u klienta :D

mr_jaro

@mar-ek1: uhhhh to ja nie chciałbym widzieć tego kodu

Bartosz Wójcik

I musiałeś zrobić felieton z 1 prostej reguły CSS? Musisz być największym krzykaczem w firmie ;), nawet nie chcę myśleć co by było jakby ktoś użył display:block zamiast inline-block!

mar-ek1

Trenuję bo jak już ta cała bańka programistyczna pęknie to będę miał wprawę w generowaniu treści na plotkarskie portale - będzie można się przebranżowić ;)
Poza tym to jest felieton o 1 regule CSS, który dostał aż 14 łapek w górę xD

Bartosz Wójcik

Na pewno wszyscy Cię lubią firmie ze swoją skromnością, niewybujałym ego i umiejętnością nierozdmuchiwania prostych spraw do skali krajowej ;)

mr_jaro

@Bartosz Wójcik: jeden z moich szefów też tak mówił gdy po przejrzeniu dokumentacji miałem momentalnie stos uwag i nieścisłości określając mnie firmowym marudą... problem taki, że wszystko co mówiłem się sprawdziło a moduł zamiast być wykonany przez max 160h (zgodnie z tym co ten szefu mówił ) pochłonął 1000h :D

mar-ek1

Cóż, w sumie to w sumie trochę zatrudnili nas do bycia właśnie takimi marudami co będą tłuc ich ludziom, że Oracle na froncie i scrumfall to nie jest szczyt możliwości człowieka w IT :P

Bartosz Wójcik

@mr_jaro jest różnica jeśli znalazłeś stos błędów, a różnica robić hałas o 1 regułę CSS którą można szybko zamienić na drugą bez większego szumu i całego felietonu na 4p @mar-ek1 gratulację, teraz idź znajdź drugi błąd :)

mr_jaro

@Bartosz Wójcik: a robiłes kiedyś coś w angularze? to nie jest takie trywialne do zmiany chyba, że pozbędą się całkowicie animacji ale i tak na każdy kolejny punkt co najmniej parę godzin pójdzie, bo trzeba przebudować akcje pod tym kątem, komponenty, animacje, napisać testy i jeszcze manualnie wszystko przeklikać.

mar-ek1

Tylko ta "jedna reguła CSS" zabija płynne działanie co najmniej kilkunastu aplikacji używanych przez 200-300 osób codziennie. Więc nawet jeżeli jest banalna to głupie decyzje projektowe mają wpływ na pracę wielu osób - o to chodzi, a nie o to, że to 1 linijka do zmiany pewnie.

Bartosz Wójcik

@mr_jaro słyszałeś - "1 linijka do zmiany pewnie", a ty już byś lody na tym chciał kręcić, żeby pracodawcę oskubać na kasę ;)

mr_jaro

@Bartosz Wójcik: tylko, że ja siedziałem w angularze dużo i często więc wiem, że to nie będzie jedna linijka

mar-ek1

O poprawianie testów bym się nie martwił - nie ma takich w ich kodzie ;) Od tego są projekty, które korzystają z biblioteki, żeby sprawdzały czy na pewno działa :P

mr_jaro

@mar-ek1: przecież testy powinny być w konkretnym komponencie... omg

Bartosz Wójcik

@mr_jaro założę się, że ty testy robisz nawet na integery i booleany czy 1 == 1 albo false == false taki nadgorliwy jesteś ;), a potem lecisz do szefa po podwyżkę bo udowodniłeś oczywiste...

mar-ek1

Temat testów to osoby wątek w ogóle :D Ale raczej mają luźne podejście do ich utrzymywania - nie działają po zmianie? To wystarczy usunąć testy.
W ogóle pracując już dla któregoś z kolei klienta z Wielkiej Brytanii zauważyłem pewną prawidłowość - większość z nich bardzo dobrze radzi sobie z formatowaniem kodu, poprawnym nazywaniem metody czy zmiennych (tabele w bazie to inna sprawa...) czy spójnością i takim porządkiem na poziomie np. konwencji w całym, nawet starszym projekcie. Jednocześnie większość z nich kompletnie nie ma pojęcia o przemyślanej architekturze, sensownych testach czy optymalnych rozwiązaniach.

mr_jaro

@Bartosz Wójcik: z takim podejściem założę się, że nie piszesz testów wcale i lecisz po podwyżkę do szefa, gdy pokażesz, ze coś co było wycenione na 200h zrobiłeś w 120h no bo testy pominąłeś :)

Bartosz Wójcik

@mr_jaro sam jestem szefem i nie robię testów na każdą głupią drobnostkę, tak jak w tym przypadku, na błąd w 1 prostej regule CSS, bo mam na tyle zdrowego rozsądku, żeby wiedzieć na co nie marnować czasu

mr_jaro

@Bartosz Wójcik: widzę, że nadal idziesz w zaparte nie wiedząc co się z czym je w angularze. Jak ja nie znam się na javie to się nie wypowiadam, polecam, mniej wstydu jeśli gadasz z kimś kto ma sporo większą wiedzę.

WeiXiao

takie rzeczy to tylko w czystym jsie ;)

czysteskarpety

że też jeszcze nie zrobili windowsa w js :]

piotrpo

Dość często się zastanawiałem, skąd się biorą pomysły pod tytułem zrobimy własny framework! i w jaki sposób się je uzasadnia.

damian-szkoladockera

Pracowałem w firmie w której był dedykowany framework do tworzenia formatek w WPF (aplikacja okienkowa w .NET). Powiedzmy, że obkułem sie tak, że trzaskałem te formatki od ręki. Gdy przyszło mi zrobić aplikację w czystym WPF-ie - zaczynałem niemal od zera...
Najczęściej własne frameworki są w firmach które pracują nad własnym produktem - po to by przyspieszyc development. Z jednej strony faktycznie development jest szybszy, z drugiej - uczysz się frameworka który nigdy Ci się nie przyda.

mar-ek1

Pracowałem dla klienta (też z UK...), który miał swój designer do formatek, ale w WinFormsach. Chociaż w sumie to było tak obudowane, że dopiero po czasie doszedłem co pod spodem jest. Widoki zapisywało się w bazie danych, a jak chciało się wrzucić do repo to trzeba było wyeksportować specjalnym narzędziem do XMLa, wrzucić do repo i powiedzieć wszystkim żeby import sobie uruchomili jak pobiorą zmiany. Wtedy pomyślałem, że jeszcze dużo świata czeka przede mną na odkrycie.

jarekr000000

@piotrpo: własny framework - ło panie trudny temat. 1. własny framework to nie zawsze zło 2. prawie ZAWSZE masz własny framework - zwykle zbudowany z klocków, ale to nie jest tak, że dwa projekty w SPringu i React bedą tak samo wyglądać - te różnice w stylu pisania dwóch firm i zespołów... to właśnie ten ukryty, często nienazwany framework 3. Te naprawdę ZŁE własne frameworki to zwykle 'INNER PLATFORM EFFECT' - bardzo ciekawe zjawisko (antypattern). Pewnie każdy widział bazę relacyjna zrobiona w bazie relacyjnej (klasyk), ale można dalej - widziałem angulara zrobionego w angularze (to ubiłem jak było małe), Springa zrobionego w Springu (tu może moje uproszczenie-złośliwoiść, ale tak można efekt końcowy opisać - platforma do wszystkiego, w zasadzie niewiele daje poza dodatkową wartstwą zagmatwania w konfiguracji (ale niewiele też przeszkadza na szczęście) )..., itd. Uzasadnienie w tym przypadku najczęściej jest takie, że firmowy zespół architektów chce mieć fajną pracę nieobciożoną wymaganiami, terminami i kontaktem z klientem.

lsikora

Tak długo jak własny framework to aktywnie rozwijany i utrzymywany projekt da się go używać a czasem nawet jest wygodnie. Strasznie się za to robi gdy cała firma używa frameworka, który został zrobiony 10 lat temu i więcej nikt go nie dotykał bo przecież projekt napisany i okrzyknięty sukcesem nie może mieć błędów :(

jarekr000000

@lsikora - dodatkowo, duży problem frameworków firmowych to założenie, że wszystkie projekty są takie same. Clean architecture pełną gębą. Wiec framowork może być nowy, ale w sytuacji kiedy nie robisz kolejnego TODO list na bazie SQL nadal może być niewypałem.

lsikora

@jarekr000000: Tak. Problem standaryzacji. 90% projektów się cieszy a 10% cierpi przez ograniczenia. Zwykle inbreed frameworki pomijają te 10% milczeniem. A to właśnie te ostatnie kilka procent powoduje, że framework nie jest kulą u nogi. Jak sobie teraz myślę to większość wewnętrznych projektów ląduje w jednym śmietniku z "nasza firma pracuje w Scrum"

piotrpo

Problem z własnymi libkami, frameworkami jest taki, że na ogół robią je ludzie, którzy się za nie nie powinni zabierać. Te z którymi się zetknąłem powstawały jako rezultat dziwnego przekonania, że skoro COŚ jest trudne w ogarnięciu, to trzeba napisać własny: serwer SQL, serwer aplikacyjny ~JEE, własnego hibernate'a, własnego J2M w Androidzie. Żaden z tych przykładów nie jest wzięty z czapy i w żadnym z tych przykładów produkt nie był na tyle wyjątkowy pod jakimkolwiek względem, żeby uzasadniać podejście typu potomkowie husarii nie podążają utartymi szlakami.

cerrato

Naprawdę ktoś pisał własnego SQL? Ja miałem taki przebłysk w okolicach liceum, na szczęście szybko mi przeszło . Ale żeby to wdrożyć na produkcję, to really ciekawa sprawa :D

piotrpo

@cerrato: Firma nazywała się Makrosoft, robiła jakies systemy księgowe, magazynowe i inne takie.

cerrato

O tym słyszałem już kiedyś. Myślałem, że masz inny przykład. A z tego co kojarzę, to oni się wycofali z tego pomysłu i przenieśli na jakieś publicznie dostępne i bardziej znane silniki.

WeiXiao

@jarekr000000: bazę relacyjna zrobiona w bazie relacyjnej? a nie np. bazę relacyjna zrobiona w nierelacyjnej?

Kamil Żabiński

Albo baza nierelacyjna w relacyjnej. Pracowałem na czymś takim. Oryginalnie pod spodem było mongo. Klient zażądał bazy relacyjnej, ale modelu logicznego trzymania danych nie zmieniliśmy

jarekr000000

@WeiXiao: chodzi o przypadek, kiedy w db lądują tabele : TABLES, COLUMNS, ROWS i VALUES. Czasem z jakimiś obocznościami, czasem zakamuflowane pod innymi nazwami.