Üks meeldiv omadus 1C:Enterprise tehnoloogias on see, et rakenduslahendust, mis on loodud hallatud vormide tehnoloogia alusel, saab käivitada nii Windows, Linux, MacOS X keskkonnas peenes (täidesaatvas) kliendis kui ka veebikliendina viies brauseris – Chrome, Internet Explorer, Firefox, Safari, Edge, ja kõik see ilma rakenduse lähtekoodi muutmiseta. Veelgi enam – visuaalselt toimib ja näeb rakendus peenes kliendis ja brauseris välja praktiliselt identne.
Leia 10 erinevust (kaks pilti allpool):
Peene kliendi aken Linuxil:

Sama aken veebikliendis (brauseris Chrome):

Miks me tegime veebikliendi? Ütlematagi selge, et tänapäeva vajadused panid meid sellise ülesande ette. Juba ammu on Interneti kaudu töötamine muutunud äritervekottide oluline tingimus. Alguses lisasime meie peenele kliendile võimaluse töötada Internetis (mõned meie konkurendid, muide, jäid selle juurde; teised aga loobusid peenest kliendist ja piirdusid ainult veebikliendi jõudlusega). Me otsustasime anda meie kasutajatele võimaluse valida nende vajadustele paremini vastav kliendi variant.

Internetist töötamise võimaluse lisamine peene kliendi jaoks oli suur projekt, millega muutus täielikult kliendi ja serveri vahelise suhtluse arhitektuur. Veebikliendi loomine on täiesti uus projekt, mis algas nullist.
Ülesande seadmine
Nii et projekti nõuded: veebikliendi peab tegema sama, mis peen kliend, nimelt:
- Kasutajaliidese kuvamine
- Kliendi koodi täitmine, kirjutatud 1C keeles
Kasutajaliides 1C-s on kirjeldatud visuaalses redigeerijas, kuid deklaratiivselt, elementide pikslite paigutamata; kasutatakse umbes kolmkümmend eri tüüpi liidese elemente – nuppe, sisendvälju (teksti, numbrite, kuupäevade/aegade), loendeid, tabeleid, graafikuid jne.
Kliendi kood 1C keeles võib sisaldada serveri kutsungeid, tööd kohalike ressurssidega (failid jne), printimist ja palju muud.
Nii peen klient (töötades veebis) kui ka veebiklient kasutavad sama veebiteenuste komplekti, et suhelda 1C rakenduste serveriga. Klientide rakendamine on muidugi erinev – peen klient on kirjutatud C++, veebiklient aga JavaScriptis.
Enne kui liigume edasi
Veebiklientide arendusprojekt algas 2006. aastal, mille raames osales keskmiselt 5 inimest. Erinevatel etappidel kaasati arendajaid spetsiifiliste funktsioonide (nt tabelid, diagrammid jne) elluviimiseks; reeglina olid need samad arendajad, kes olid neid funktsioone loonud õhukeses kliendis. See tähendab, et arendajad kirjutavad JavaScriptis uuesti komponente, mille nad olid varem loonud C++-s.
Alates algusest juhtisime tagasi idee automaatsetest (mugavalt osalistest) üleviimist C++ koodist õhukese kliendi JavaScripti veebikliendisse, arvestades kahe keele vahelisi suuri kontseptsioonilisi erinevusi; veebiklient kirjutati JavaScriptis nullist.
Projekti esialgsetes iteratsioonides konverteeris veebiklient kliendi koodi sisseehitatud 1C keeles otse JavaScriptiks. Õhuke klient toimib teisiti - kood sisseehitatud 1C keeles kompileeritakse byte-koodiks, mida tõlgendatakse seejärel kliendis. Hiljem hakkas ka veebiklient seda tegema - esiteks parandas see jõudlust, teiseks lubas see ühtlustada õhukese ja veebiklientide arhitektuuri.
Esimene versioon platvormist 1C: Ettevõte veebiklienti toetava funktsiooniga ilmus 2009. aastal. Sel hetkel toetas veebiklient 2 brauserit - Internet Explorer ja Firefox. Algsetes plaanides oli toetada Opera, kuid seoses ületamatute probleemidega rakenduse sulgemise töötlejatega Opera brauseris (ei õnnestunud 100% kindlusega jälgida, et rakendus suletakse, ja sel hetkel 1C rakenduste serverist lahtiühendamise protseduuri läbi viia) tuli neist plaanidest loobuda.
Projekti struktuur
Platvormil 1C: Ettevõte on kokku 4 JavaScriptis kirjutatud projekti:
- WebTools – üldised raamatukogud, mida kasutavad teised projektid (siia kuuluvad ka ).
- Kasutajaliides (rakendatud nii JavaScriptis kui ka õhukeses ja veebikliendis)
- Kasutajaliides (rakendatud nii JavaScriptis kui ka õhukeses ja veebikliendis)
- Veebiklient
Iga projekti struktuur sarnaneb Java projektide (või .NET projektide - kellele mis sobib) struktuuriga; meil on nimed, kus iga nimi asub eraldi kaustas. Kaustas asuvad nime ruumi failid ja klassid. Veebiklientide projektis on umbes 1000 faili.
Struktuuriliselt jaguneb veebiklient suuremas osas järgmisteks alamsüsteemideks:
- Kliendirakenduse hallatav liides
- Rakenduse üldliides (süsteemimenüüd, paneelid)
- Haldatavate vormide liides, mis hõlmab kokku umbes 30 juhtseadet (nupud, erinevad sisestusväljade tüübid – tekstilised, numbrilised, kuupäev/aeg jne, tabelid, loendid, graafikud jms)
- Objektimudel, mis on arendajatele kättevõtted (üle 400 tüüpi: hallatava liidese objektimudel, andmete paigutuse seadistamine, tingimuslik vormindamine jne)
- 1C sisseehitatud keele interpretator
- Brauserilaiendid (kasutatakse funktsionaalsuse jaoks, mida JavaScript ei toeta)
- Töötamine krüptograafiaga
- Failidega töötamine
- Väliste komponentide tehnoloogia, mis võimaldab neid kasutada nii õhukeses kui ka veebikliendis
Arenduse eripära
Kõik ülaltoodu elluviimine JavaScriptis on keeruline ülesanne. Võib-olla on 1C veebiklient üks suurimaid JavaScriptis kirjutatud kliendi poole rakendusi – umbes 450,000 rida. Me kasutame aktiivselt objektorienteeritud lähenemist, mis lihtsustab sellise suure projekti arendust.
Kliendikoodi suuruse vähendamiseks kasutasime algul oma obfuskaatorit, alates platvormi versioonist 8.3.6 (oktoober 2014) hakkasime kasutama . Obfuskatsiooni mõju numbrites – veebikliendi raamistik pärast obfuskatsiooni:
- Meie obfuskaator – 1556 kB
- Google Closure Compiler – 1073 kB
Google Closure Compiler'i kasutamine aitas meil kiirusaruandlust tõsta 30% võrreldes meie obfuskaatoriga. Samuti vähenes rakenduse mälu kasutamine 15-25% (sõltuvalt brauserist).
Google Closure Compiler töötab väga hästi objektorienteeritud koodiga, seega on selle efektiivsus veebikliendi jaoks maksimaalne. Closure Compiler teeb meie jaoks mitu head asja:
- Statistiline tüüpide kontroll projekti kogumisel (see tagatakse sellega, et katame koodi JSDoc annotatsioonidega). Tulemuseks on staatiline tüpiseerimine, mis on lähedane C++ tüpiseerimise tasemele. See aitab sajandeid vigu kinni püüda projekti kompileerimise etapis.
- Koodi suuruse vähendamine obfuskatsiooni kaudu
- Rida optimeerimisi täidetud koodi, näiteks:
- inline-funktsioonide asendamine. Funktsiooni väljakutse JavaScriptis on piisavalt kulukas operatsioon, ja inline-harjumuste tihedam kasutamine kiirendab koodi töötlust oluliselt.
- Konstantide väljaarvutamine kompileerimise ajal. Kui väljend sõltub konstantist, asendatakse see tegeliku konstantide väärtusega.
Arenduskeskkonnana veebiklientide jaoks kasutame WebStormi.
Koodi analüüsimiseks kasutame , kuhu integreerime staatilisi koodi analüsaatoreid. Analüsaatorite abil jälgime JavaScripti lähtekoodi kvaliteedi langust ja püüame seda vältida.

Milliseid ülesandeid oleme lahendanud / lahendame
Projekti elluviimise käigus kohtasime mitmeid huvitavaid ülesandeid, mida pidime lahendama.
Andmevahetus serveri ja akende vahel
On olukordi, kus lähtekoodi obfuskeering võib süsteemi tööd segada. Kood, mis on väljaspool veebiklientide täitmist, võib obfuskeeringu tõttu sisaldada funktsioonide ja parameetrite nimesid, mis erinevad neid, mida meie täituv kood ootab. Meie jaoks on väline kood:
- Kood, mis saab serverilt struktuursete andmete kujul
- Teise rakenduse akna kood
Obfuskeeringu vältimiseks serveriga suhtlemisel kasutame sildit @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;
}Ja et vältida obfuskeeringut teise aknaga suhtlemisel, kasutame nn eksporditud liideseid (liidesed, kus kõik meetodid on eksportitavad).
/**
* Экспортируемый интерфейс контрола 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 (){}Kasutasime Virtual DOM-i enne, kui see muutus peavooluks)
Nagu kõik arendajad, kes tegelevad keerulise veebiliidese loomisega, mõistsime kiiresti, et DOM ei sobi dünaamilise kasutajaliidese jaoks. Peaaegu kohe rakendati Virtual DOM-i analooge, et optimeerida töötlust UI-ga. Ürituste töötlemise käigus salvestatakse kõik DOM-i muutused mälu, ja ainult pärast kõigi toimingute lõpetamist rakendatakse akumuleeritud muutused DOM-puule.
Veebikliendi töötluse optimeerimine
Kuna tahame, et meie veebiklient töötaks kiiremini, püüame maksimaalselt kasutada brauseri sisseehitatud võimalusi (CSS jne). Näiteks vormi käsu paneel (mis asub praktiliselt igas rakenduse vormis) joonistatakse ainult brauseri vahenditega, dünaamilise kujunduse abil, mis põhineb CSS-il.

Testimine
Funktsionaalsete testide ja jõudlustestide jaoks kasutame meie enda loodud tööriista (kirjutatud Java ja C++ keeles) ning testide komplekti, mis põhineb .
Meie tööriist on universaalne – see võimaldab testida praktiliselt kõiki aknaprogramme, seega sobib see nii õhuklientide kui ka veebiklientide testimiseks. Tööriist salvestab kasutaja tegevused, kes käivitas rakenduse "1C", skripti faili. Samal ajal salvestatakse ekraanipinna pildid – referentsid. Uute veebikliendi versioonide kontrollimisel mängitakse skripte ilma kasutaja osaluseta. Kui mõnes etapis ekraanipilt ei ühti referentsiga, loetakse test ebaõnnestunuks, mille järel kvaliteedi spetsialist uurib, kas see on viga või kavandatud süsteemi muutus. Kui see on kavandatud käitumine, asendatakse referentsid automaatselt uute vastu.
Tööriist mõõdab samuti rakenduste jõudlust täpsusega kuni 25 millisekundit. Mitmetes juhtudel me kordame skripti osi (näiteks mitu korda tellimuse sisestamist), et analüüsida täitmise aegade halvenemist aja jooksul. Kõik mõõtmiste tulemused salvestatakse logisse analüüsimiseks.

Meie testimistööriist ja testitav rakendus
Meie tööriist ja Selenium täiendavad üksteist; näiteks, kui mõni nupp ühelt ekraanilt on oma asukohta muutnud – Selenium võib seda mitte jälgida, kuid meie tööriist märkab seda, sest see teeb pixel-pixel võrdluse ekraanipildist referentsiga. Samuti suudab tööriist tuvastada probleeme klaviatuuri või hiire sisendi töötlemisel, kuna just neid ta ka taastab.
Mõlema tööriista (meie ja Seleniumi) testid käivitavad tüüpilisi tööstsenaariume meie rakenduste lahendustest. Testid käivitatakse automaatselt pärast iga päevast "1C:Enterprise" platvormi kogumist. Kui stsenaariumide täitmise aeg aeglustub (võrreldes eelmise kogumisega), viibime uurimise läbi ja likvideerime aeglustumise põhjuse. Meie kriteerium on lihtne – uus kogumine peaks töötama mitte aeglasemalt kui eelmine.
Aeglustumise intsidentide uurimiseks kasutavad arendajad erinevaid tööriistu; peamiselt kasutatakse tootja ettevõte . Probleemse operatsiooni logide salvestamine toimub nii eelmises kui ka uues versioonis, pärast mida logisid analüüsitakse. Sel juhul ei pruugi üksikute operatsioonide täitmise aeg (millisekundites) olla määrav tegur – brauseris käivitatakse aeg-ajalt teenindusprotsesse, nagu prügi koristamine, mis võivad mõjutada funktsioonide täitmise aega ja moonutada olukorda. Relevantsed parameetrid oleksid antud juhul JavaScripti täidetud käskude arv, DOM-iga seotud aatomite operatsioonide arv jne. Kui uue versiooni sama stsenaariumi käskude / operatsioonide arv on suurenenud, tähendab see peaaegu alati jõudluse langust, mida tuleb parandada.
Üks põhjusi jõudluse languseks võib olla see, et Google Closure Compiler ei suutnud mingil põhjusel funktsiooni inline-asendust teha (näiteks, kuna funktsioon on rekursiivne või virtuaalne). Sellisel juhul püüame olukorda parandada, kirjutades allika koodi ümber.
Braiuserilaiendused
Kui rakendustehnilises lahenduses on vajalik funktsionaalsus, mida JavaScript ei paku, kasutame brauserilaiendusi:
- failidega töötamiseks
- krüptograafiaga töötamiseks
- töötamine
Meie laiendused koosnevad kahest osast. Esimene osa on nn brauserilaiendus (tavaliselt JavaScriptis kirjutatud laiendused Chrome'i ja Firefoxi jaoks), mis suhtleb teise osaga – binaarse laiendusega, mis realiseerib vajaliku funktsionaalsuse. Tuleb mainida, et kirjutame 3 versiooni binaarsetest laiendustest – Windowsi, Linuxi ja MacOS-i jaoks. Binaarne laiendus on 1C:Enterprise platvormi osa ja asub 1C rakendusse serveris. Esimese veebikliendi kutsumise ajal laaditakse see kliendiarvutisse ja installitakse brauserisse.
Safari kasutamisel kasutavad meie laiendused NPAPI-d, Internet Exploreris – ActiveX-tehnoloogiat. hetkel ei toeta laiendusi, seega toimib veebiklient selles piirangutega.
Edasine areng
Üks arendusmeeskonna ülesannete rühmadest on veebikliendi funktsionaalsuse edasine arendamine. Veebikliendi funktsionaalsus peab olema identne õhukese kliendi funktsionaalsusega, kogu uus funktsionaalsus rakendatakse samaaegselt nii õhukeses kui ka veebikliendis.
Teised ülesanded hõlmavad arhitektuuri arendamist, refaktoreerimist, jõudluse ja usaldusväärsuse suurendamist. Näiteks on üks suund edasine liikumine asünkroonse töömudeli suunas. Osaliselt on veebikliendi funktsionaalsus praegu üles ehitatud sünkroonselt serveriga suhtlemiseks. Asünkroonne mudel muutub nüüd brauserites (ja mitte ainult brauserites) järjest olulisemaks, mis sunnib meid veebiklienti modifitseerima, asendades sünkroonilised kõned asünkroonsetega (ja vastava koodi refaktoreerimisega). Aeganõudev üleminek asünkroonsele mudelile on põhjendatud vajadusega toetada välja antud lahendusi ja nende järkjärgulise kohandamisega.
Allikas: habr.com
