Një nga karakteristikat e këndshme të teknologjisë 1C: Ndërmarrja është se zgjidhja aplikative, e zhvilluar mbi teknologjinë e formave të kontrolluara, mund të ekzekutohet si në klientin e hollë (ekzekutiv) në Windows, Linux, MacOS X, ashtu edhe si klient web në 5 shfletues – Chrome, Internet Explorer, Firefox, Safari, Edge, dhe gjithçka – pa ndryshuar kodin burimor të aplikacionit. Për më tepër, aplikacioni duket dhe funksionon praktikisht identik si në klientin e hollë, ashtu edhe në shfletues.
Gjeni 10 ndryshime (në vijim 2 imazhe):
Dritarja e klientit të hollë në Linux:

E njëjta dritare në klientin web (në shfletuesin Chrome):

Pse e kemi krijuar klientin web? Duke folur disi me patos, një detyrë e tillë na është caktuar nga koha. Prej kohësh, puna në internet është bërë një kusht i nevojshëm për aplikacionet biznesore. Fillimisht, ne shtuam mundësinë e punës përmes internetit për klientin tonë të hollë (disa nga konkurentët tanë, për fat të keq, ndalën këtu; të tjerë, përkundrazi, e braktisën klientin e hollë dhe u përqendruan në realizimin e klientit web). Ne vendosëm t'u japim përdoruesve tanë mundësinë të zgjedhin atë variant kliente që u përshtatet më shumë.

Shtimi i mundësisë për të punuar përmes Internetit për klientin e hollë ishte një projekt i madh me një ndryshim të plotë të arkitekturës së ndërveprimit klient-server. Ndërsa krijimi i klientit të web-it ishte një projekt krejtësisht i ri, duke filluar nga zero.
Vendosja e detyrës
Kështu, kërkesat për projektin: klienti web duhet të bëjë të njëjtën gjë si klienti i hollë, pra:
- Të shfaqë ndërfaqen e përdoruesit
- Të ekzekutojë kodin e klientit të shkruar në gjuhën 1C
Ndërfaqja e përdoruesit në 1C përshkruhet në redaktorin vizual, por në mënyrë deklarative, pa vendosjen e elementeve pixel për pixel; përdoren rreth tridhjetë lloje elementesh ndërfaqe - butona, fusha inputi (tekst, numra, datë/kohë), lista, tabela, grafikë etj.
Kodi i klientit në gjuhën 1C mund të përmbajë thirrje serverësh, punë me burime lokale (skedare etj.), printim dhe shumë të tjera.
Si klienti i hollë (kur punon përmes web-it), ashtu edhe klienti web përdorin të njëjtin grup shërbimesh web për të komunikuar me serverin e aplikacioneve 1C. Implementimi në klientë, natyrisht, është ndryshe - klienti i hollë është shkruar në C++, ndërsa klienti web është në JavaScript.
Pak histori
Projekti për krijimin e klientit web filloi në vitin 2006, me një ekip mesatarisht prej 5 personash. Në etapa të veçanta të projektit, ishin angazhuar zhvillues për të realizuar funksionalitete specifike (dokumenti tabelar, grafikët etj.); zakonisht, këta ishin të njëjtët zhvillues që kishin realizuar këtë funksionalitet në klientin e hollë. Pra, zhvilluesit rikodifikonin komponentët në JavaScript, të cilët më parë i kishin krijuar në C++.
Që nga fillimi ne e hodhëm poshtë idenë e ndonjë konvertimi automatike (edhe pjesor) të kodit C++ të klientit të hollë në JavaScript për klientin web për shkak të ndryshimeve të forta konceptuale midis këtyre dy gjuhëve; klienti web është shkruar në JavaScript nga fillimi.
Në iteraimet fillestare të projektit, klienti web e konvertonte kodin klientit në gjuhën e integruar 1C direkt në JavaScript. Klienti i hollë vepron ndryshe – kodi në gjuhën e integruar 1C kompilohen në kod bajt, dhe pastaj ky kod bajt interpretohet në klient. Më vonë, gjithashtu e filloi dhe klienti web – së pari, kjo ofroi përfitim në performancë, së dyti – lehtësoi unifikimin e arkitekturës së klientëve të hollë dhe web.
Versioni e parë e platformës 1C: Ndërmarrja me mbështetje për klientin web doli në vitin 2009. Klienti web në atë kohë mbështeste 2 shfletues – Internet Explorer dhe Firefox. Në planet fillestare ishte parashikuar mbështetje për Opera, por për shkak të problemeve të pakapërcyeshme me trajtuesit e mbylljes së aplikacionit në Opera (nuk ishte e mundur të ndiqeshin me 100% siguri se aplikacioni po mbyllej, dhe në atë moment të kryhej procedura e shkëputjes nga serveri i aplikacioneve 1C) këto plane duhej të braktisnin.
Struktura e projektit
Në total, platforma 1C: Ndërmarrja ka 4 projekte, të shkruara në JavaScript:
- WebTools – biblioteka të përgjithshme, të përdorura nga projektet e tjera (këtu përfshijmë ).
- Element kontrolli (implementuar në JavaScript si në klientin e hollë ashtu edhe në klientin web)
- Element kontrolli (implementuar në JavaScript si në klientin e hollë ashtu edhe në klientin web)
- Klienti web
Struktura e çdo projekti i ngjan strukturës së projekteve Java (ose projekteve .NET – për kë të duket më afër); kemi hapësira emërore, dhe çdo hapësirë emërore ndodhet në një dosje të veçantë. Brenda dosjes ndodhen skedarë dhe klasa të hapësirës emërore. Në projektin e klientit web ka rreth 1000 skedarë.
Struktura e klientit web ndahen në mënyrë të madhe në sistemet e mëposhtme:
- Ndërfaqja e menaxhuar e aplikacionit të klientit
- Ndërfaqja e përgjithshme e aplikacionit (menutë sistemike, panellet)
- Ndërfaqja e formave të menaxhuara, e cila përfshin rreth 30 elemente kontrolli (butona, lloje të ndryshme fushe hyrëse – tekst, numra, datë/koha etj., tabela, lista, grafikë etj.)
- Modeli i objektit të disponueshëm për zhvilluesit në klient (më shumë se 400 lloje: modeli i objektit të ndërfaqes së menaxhuar, cilësimet e kompozimit të të dhënave, stilizimi i kushteve etj.)
- Interpretuesi i gjuhës së integruar 1C
- Zgjerimet e shfletuesve (përdoren për funksionalitet që nuk mbështetet në JavaScript)
- Puna me kriptografinë
- Puna me skedarët
- Teknologjia e komponenteve të jashtme, e cila lejon përdorimin e tyre si në klientin e hollë, ashtu edhe në atë web
Karakteristikat e zhvillimit
Realizimi i gjithçkaje të përshkruar më sipër në JavaScript nuk është një detyrë e lehtë. Mundësisht, klienti web 1C – është një nga aplikacionet më të mëdha anës klientit të shkruara në JavaScript – rreth 450,000 rreshta. Ne aktivisht përdorim në kodin e klientit web një qasje objektive, duke e lehtësuar punën me një projekt kaq të madh.
Për të minimizuar madhësinë e kodit të klientit, në fillim përdorëm një obfuskator të vetin, dhe që nga versioni i platformës 8.3.6 (tetor 2014) filluam të përdorim . Efekti i përdorimit në numra – madhësia e kornizës së web-klientit pas obfuskimit:
- Obfuskatori ynë – 1556 kB
- Google Closure Compiler – 1073 kB
Përdorimi i Google Closure Compiler na ndihmoi të rrisim performancën e web-klientit me 30% krahasuar me obfuskatorin tonë. Për më tepër, konsumimi i memories nga aplikacioni u ul me 15-25% (në varësi të shfletuesit).
Google Closure Compiler funksionon shumë mirë me kodin orientuar në objekte, prandaj efikasiteti i tij për web-klientin është maksimal. Closure Compiler bën disa gjëra të mira për ne:
- Kontrolli statik i tipeve në fazën e ndërtimit të projektit (e siguruar duke mbuluar kodin me annotacione JSDoc). Në përfundim, rezulton një tipizim statik që është shumë afër nivelit të tipizimit në C++. Kjo ndihmon në kapjen e një përqindjeje të madhe të gabimeve në fazën e kompilimit të projektit.
- Reducimi i madhësisë së kodit përmes obfuskimit
- Seri optimizimesh të kodit të ekzekutimit, si p.sh.:
- zëvendësime inline të funksioneve. Thirrja e një funksioni në JavaScript është një operacion mjaft i kushtueshëm, dhe zëvendësimet inline të metodave të vogla që përdoren shpesh e përshpejtojnë ndjeshëm punën e kodit.
- Llogaritja e konstantave në fazën e kompilimit. Nëse shprehja varet nga një konstantë, do të vendoset vlera e saktë e konstantës.
Si ambient zhvillimi për klientin web përdorim WebStorm.
Për analizën e kodit ne përdorim , ku integrojmë analizatorët statikë të kodit. Me ndihmën e analizatorëve, ne ndjekim degradimin e cilësisë së kodit burimor në JavaScript dhe përpiqemi ta parandalojmë atë.

Cilat probleme kemi zgjidhur/zgjidhim
Gjatë zbatimit të projektit, u përballëm me një sërë çështjesh interesante që duhej të zgjidheshin.
Shkëmbimi i të dhënave me serverin dhe midis dritareve
Ekzistojnë situata, kur obfuscimi i kodit burimor mund të pengojë funksionimin e sistemit. Kodi, i jashtëm në lidhje me kodin ekzekutues të klientit web, si rezultat i obfuscimit mund të ketë emra funksionesh dhe parametrash që ndryshojnë nga ato që kodit ynë ekzekutues pret. Kodi i jashtëm për ne përfshin:
- Kodi që vjen nga serveri në formën e strukturave të dhënash
- Kodi i dritares tjetër të aplikacionit
Për të shmangur obfuscimin gjatë ndërveprimit me serverin ne përdorim tags @expose:
/**
* @constructor
* @extends {Base.SrvObject}
*/
Srv.Core.GenericException = function ()
{
/**
* @type {string}
* @expose
*/
this.descr;
/**
* @type {Srv.Core.GenericException}
* @expose
*/
this.inner;
/**
* @type {string}
* @expose
*/
this.clsid;
/**
* @type {boolean}
* @expose
*/
this.encoded;
}Dhe për të shmangur obfuscimin gjatë ndërveprimit me dritare të tjera, ne përdorim ato që quhen interfaca të eksportuara (interfaca ku të gjitha metodat janë të eksportuara).
/**
* Экспортируемый интерфейс контрола DropDownWindow
*
* @interface
* @struct
*/
WebUI.IDropDownWindowExp = function(){}
/**
* Перемещает выделение на 1 вперед или назад
*
* @param {boolean} isForward
* @param {boolean} checkOnly
* @return {boolean}
* @expose
*/
WebUI.IDropDownWindowExp.prototype.moveMarker = function (isForward, checkOnly){}
/**
* Перемещает выделение в начало или конец
*
* @param {boolean} isFirst
* @param {boolean} checkOnly
* @return {boolean}
* @expose
*/
WebUI.IDropDownWindowExp.prototype.moveMarkerTo = function (isFirst, checkOnly){}
/**
* @return {boolean}
* @expose
*/
WebUI.IDropDownWindowExp.prototype.selectValue = function (){}Kemi përdorur Virtual DOM para se të bëhej mainstream)
Si të gjithë zhvilluesit që merren me UI komplekse të Uebit, ne kuptuam shpejt se DOM-i nuk është i përshtatshëm për të punuar me një ndërfaqe dinamike përdoruesi. Praktikisht menjëherë, një analog i Virtual DOM u realizua për optimizimin e punës me UI. Gjatë procesit të përpunimit të ngjarjeve, të gjitha ndryshimet në DOM mbahen në kujtesë dhe, vetëm përfundimisht, pas përfundimit të të gjitha operacioneve, ndryshimet e akumuluara aplikohen në pemën DOM.
Optimizimi i performancës së klientit të uebit
Për të bërë që klienti ynë i uebit të funksionojë më shpejt, ne përpiqemi maksimalisht të shfrytëzojmë mundësitë e integruara të shfletuesit (CSS etj.). Kështu, paneli i komandave të formularit (i vendosur pothuajse në çdo formular të aplikacionit) vizatohet ekskluzivisht me mjete të shfletuesit, duke përdorur markup dinamik të bazuar në CSS.

Testimi
Për testimin funksional dhe performues, ne përdorim një mjet të zhvilluar nga ne (i shkruar në Java dhe C++), si dhe një grup testesh të bazuara në .
Mjeti ynë është universal – ai lejon testimin e pothuajse çdo programi dritare, dhe kështu, është i përshtatshëm për testimin e klientëve të hollë dhe të uebit. Mjeti regjistron veprimet e përdoruesit që ka nisur zgjidhjen aplikative '1C' në një skenar skenari. Po ashtu, regjistrohen imazhe të zonës së punës në ekran—etalonet. Kur kontrollohen versionet e reja të klientit të uebit, skenarët ekzekutohen pa pjesëmarrjen e përdoruesit. Në rast se ekrani i kapur nuk përputhet me etalonin në ndonjë hap, testi konsiderohet si i dështuar, pas të cilit një specialist i cilësisë kryen një hetim – nëse është një gabim ose një ndryshim i planifikuar i sjelljes së sistemit. Në rast të sjelljes së planifikuar, etalonet automatizohen për t'u zëvendësuar me të reja.
Instrumenti gjithashtu mat performancën e aplikacioneve me saktësi deri në 25 milisekonda. Në disa raste, ne rrethojmë pjesë të skenarit (p.sh., variasionin e porosisë disa herë) për të analizuar degradimin e kohës së ekzekutimit me kalimin e kohës. Rezultatet e të gjitha matjeve regjistrohen në log për analizë.

Instrumenti ynë i testimit dhe aplikacioni i testuar
Instrumenti ynë dhe Selenium përplotësojnë njëri-tjetrin; për shembull, nëse ndonjë buton në një nga ekranet ka ndryshuar vendndodhjen - Selenium nuk mund ta ndjekë këtë, por instrumenti ynë e vëren, pasi bëjmë një krahasim pikë për pikë të screenshot-it me standartin. Gjithashtu, instrumenti është në gjendje të ndjekë problemet me përpunimin e inputeve nga tastiera ose miu, pasi ato janë pikërisht ato që ai riprodhon.
Të dy instrumentet (tonin dhe Selenium) ekzekutojnë skenarë tipikë pune nga zgjidhjet tona aplikative. Testet fillojnë automatikisht pas ndërtimit të përditshëm të platformës "1C:Enterprise". Në rast të ngadaltësimit të ekzekutimit të skenarëve (krahasuar me ndërtimin e mëparshëm), ne kryejmë një hetim dhe eliminojmë shkakun e ngadaltësimit. Kriteri ynë është i thjeshtë – ndërtimi i ri duhet të funksionojë jo më ngadalë se ai i mëparshmi.
Për hetimin e incidenteve të ngadaltësisë, zhvilluesit përdorin mjete të ndryshme; kryesisht përdoret prodhim i kompanisë . Проводится запись логов выполнения проблемной операции на предыдущей и на новой сборке, затем логи анализируются. При этом время выполнения единичных операций (в миллисекундах) может не быть решающим фактором – в браузере периодически запускаются служебные процессы типа уборки мусора, они могут наложиться на время выполнения функций и исказить картину. Более релевантными параметрами в этом случае будет количество выполненных инструкций JavaScript, количество атомарных операций над DOM и т.п. Если количество инструкций/операций в одном и том же сценарии в новой версии увеличилось – это почти всегда означает падение быстродействия, которое нужно исправлять.
Также одной из причин падения производительности может быть то, что Google Closure Compiler по какой-то причине не смог сделать inline-подстановку функции (например, потому что функция рекурсивная или виртуальная). В этом случае мы стараемся исправить ситуацию, переписав исходный код.
Расширения браузеров
В случае, когда прикладному решению нужна функциональность, которой нет в JavaScript, мы используем расширения браузеров:
- për punën me skedarët
- për punën me kriptografinë
- punë me
Zgjerimet tona përbuhen nga dy pjesë. Pjesa e parë është ajo që quhet zgjerimi i shfletuesit (zakonisht, zgjerime të shkruara në JavaScript për Chrome dhe Firefox), të cilat ndërveprojnë me pjesën e dytë — zgjerimin binar, i cili realizon funksionalitetin tonë të nevojshëm. Duhet të përmendet se ne shkruajmë 3 versione të zgjerimeve binare – për Windows, Linux dhe MacOS. Zgjerimi binar shpërndahet si pjesë e platformës 1C:Enterprise dhe ndodhet në serverin e aplikacioneve 1C. Në Thirrjen e parë nga klienti i uebit, ai shkarkohet në kompjuterin e klientit dhe instalohet në shfletues.
Kur punojmë në Safari, zgjerimet tona përdorin NPAPI, në Internet Explorer përdoret teknologjia ActiveX. endé nuk mbështet zgjerimet, prandaj klienti i uebit në të funksionon me kufizime.
Zhvillimi i mëtejshëm
Një nga grupet e detyrave për ekipin e zhvillimit të klientit të uebit është zhvillimi i mëtejshëm i funksionalitetit. Funksionaliteti i klientit të uebit duhet të jetë identik me funksionalitetin e klientit të hollë, të gjitha funksionalitetet e reja realizohen njëherazi në të dy klientët, si në të hollin ashtu edhe në atë të uebit.
Detyra të tjera janë zhvillimi i arkitekturës, refaktorizimi, rritja e performancës dhe besueshmërisë. Për shembull, një nga drejtimet është lëvizja drejt një modeli asinkron të punës. Një pjesë e funksionalitetit të klientit web aktualisht është ndërtuar mbi një model sinkron të bashkëpunimit me serverin. Modeli asinkron tani po bëhet më aktual në shfletues (dhe jo vetëm në shfletues) dhe kjo na detyron të modifikojmë klientin web duke zëvendësuar thirrjet sinkrone me ato asinkrone (dhe duke bërë refaktorizimin përkatës të kodit). Kalimi gradual në modelin asinkron shpjegohet me nevojën për të mbështetur zgjidhjet e lëshuara dhe adaptimin e tyre gradual.
Burimi: habr.com
