Pri la TTT-kliento 1C

Unu el la belaj funkcioj de 1C:Enterprise-teknologio estas, ke la aplikaĵa solvo, evoluigita per administritaj formoj-teknologio, povas esti lanĉita kaj en maldika (efektivebla) kliento por Vindozo, Linukso, MacOS X, kaj kiel TTT-kliento por 5 retumiloj - Chrome, Internet Explorer, Firefox, Safari, Edge, kaj ĉio ĉi sen ŝanĝi la fontkodon de la aplikaĵo. Krome, ekstere la aplikaĵo en la maldika kliento kaj en la retumilo funkcias kaj aspektas preskaŭ identa.
Trovu 10 diferencojn (2 bildoj sub la tranĉo):

Fenestro de maldika kliento en Linukso:

Pri la TTT-kliento 1C

La sama fenestro en la TTT-kliento (en la retumilo Chrome):

Pri la TTT-kliento 1C

Kial ni faris TTT-klienton? Por diri iom kortuŝe, la tempo starigis tian taskon por ni. Labori per Interreto longe estas antaŭkondiĉo por komercaj aplikoj. Unue, ni aldonis la kapablon labori per la interreto por nia maldika kliento (kelkaj el niaj konkurantoj, cetere, ĉesis ĉe tio; aliaj, male, forlasis la maldikan klienton kaj limigis sin al efektivigo de retkliento). Ni decidis doni al niaj uzantoj la ŝancon elekti la klientan opcion, kiu plej konvenas al ili.

Pri la TTT-kliento 1C

Aldoni ret-bazitajn kapablojn al la maldika kliento estis granda projekto kun kompleta ŝanĝo en klient-servila arkitekturo. Krei retklienton estas tute nova projekto, komencante de nulo.

Formulado de la problemo

Do, la projektaj postuloj: la retkliento devas fari la samon kiel la maldika kliento, nome:

  1. Montru uzantinterfacon
  2. Efektivigu klientkodon skribitan en 1C lingvo

La uzantinterfaco en 1C estas priskribita en vida redaktilo, sed deklara, sen piksel-post-piksela aranĝo de elementoj; Ĉirkaŭ tri dekduaj specoj de interfacaj elementoj estas uzataj - butonoj, enigkampoj (teksto, nombra, dato/tempo), listoj, tabeloj, grafikaĵoj ktp.

Klientokodo en la lingvo 1C povas enhavi servilvokojn, laborante kun lokaj rimedoj (dosieroj, ktp.), presado, kaj multe pli.

Kaj la maldika kliento (kiam laboras per la reto) kaj la retkliento uzas la saman aron de retservoj por komuniki kun la aplikaĵoservilo 1C. Klienta efektivigoj, kompreneble, estas malsamaj - la maldika kliento estas skribita en C++, la TTT-kliento estas skribita en JavaScript.

Iom da historio

La projekto de retkliento komenciĝis en 2006, kun teamo de (averaĝe) 5 homoj. En certaj stadioj de la projekto, programistoj estis implikitaj por efektivigi specifan funkciecon (kalkultabeldokumento, diagramoj, ktp.); kiel regulo, ĉi tiuj estis la samaj programistoj, kiuj faris ĉi tiun funkcion en la maldika kliento. Tiuj. programistoj reverkis komponantojn en JavaScript, kiujn ili antaŭe kreis en C++.

De la komenco, ni malakceptis la ideon de ajna aŭtomata (eĉ parta) konvertiĝo de C++ maldika kliento-kodo en JavaScript-retklienton pro la fortaj koncipaj diferencoj inter la du lingvoj; la TTT-kliento estis skribita per JavaScript de nulo.

En la unuaj ripetoj de la projekto, la retkliento konvertis klientkodon en la enkonstruita 1C lingvo rekte en JavaScript. La maldika kliento agas malsame - la kodo en la enkonstruita 1C lingvo estas kompilita en bajtokodon, kaj tiam ĉi tiu bajtokodo estas interpretita sur la kliento. Poste, la retkliento komencis fari la samon - unue, ĝi donis rendimentan gajnon, kaj due, ĝi ebligis unuigi la arkitekturon de la maldikaj kaj retklientoj.

La unua versio de la 1C:Enterprise-platformo kun retklientsubteno estis publikigita en 2009. La retkliento tiutempe subtenis 2 retumiloj - Internet Explorer kaj Fajrovulpo. La originaj planoj inkluzivis subtenon por Opera, sed pro nesupereblaj problemoj tiutempe kun aplikaĵo-fermaj prizorgantoj en Opera (ne eblis spuri kun 100% certeco ke la aplikaĵo fermiĝas, kaj en tiu momento efektivigi la malkonektiproceduron de la 1C aplikaĵservilo) de tiuj planoj devis esti prirezignita.

Projekta strukturo

Entute, la platformo 1C:Enterprise havas 4 projektojn skribitajn en JavaScript:

  1. WebTools - komunaj bibliotekoj uzataj de aliaj projektoj (ni ankaŭ inkluzivas Google Fermo-Biblioteko).
  2. Kontrolelemento FormatitaDokumento (efektivigite en JavaScript en kaj la maldika kliento kaj la retkliento)
  3. Kontrolelemento Planilo (efektivigite en JavaScript en kaj la maldika kliento kaj la retkliento)
  4. Reta kliento

La strukturo de ĉiu projekto similas la strukturon de Java-projektoj (aŭ .NET-projektoj - kiu ajn estas pli proksima); Ni havas nomspacojn, kaj ĉiu nomspaco estas en aparta dosierujo. Ene de la dosierujo estas dosieroj kaj nomspacaj klasoj. Estas ĉirkaŭ 1000 dosieroj en la retklienta projekto.

Strukture, la retkliento estas plejparte dividita en la sekvajn subsistemojn:

  • Administrita klienta aplika interfaco
    • Ĝenerala aplika interfaco (sistemaj menuoj, paneloj)
    • Interfaco de administritaj formoj, inkluzive de, interalie, ĉirkaŭ 30 kontroloj (butonoj, diversaj specoj de enigkampoj - teksto, nombra, dato/tempo, ktp., tabeloj, listoj, grafikaĵoj, ktp.)

  • Objektmodelo havebla al programistoj sur la kliento (pli ol 400 tipoj entute: administrita interfaca objektomodelo, datenenpaĝigvaloroj, kondiĉa stilo, ktp.)
  • Interpretisto de la enkonstruita 1C lingvo
  • Retumilo-etendaĵoj (uzitaj por funkcieco ne subtenata en JavaScript)
    • Laborante kun kriptografio
    • Laborante kun dosieroj
    • Teknologio de eksteraj komponentoj, permesante ilin esti uzataj en maldikaj kaj retklientoj

Evoluaj Trajtoj

Efektivigi ĉion supre en JavaScript ne estas facila. Eble la TTT-kliento 1C estas unu el la plej grandaj klientflankaj aplikaĵoj skribitaj en JavaScript - ĉirkaŭ 450.000 XNUMX linioj. Ni aktive uzas objekt-orientitan aliron en la retklienta kodo, kiu simpligas labori kun tia granda projekto.

Por minimumigi la grandecon de la klientokodo, ni unue uzis nian propran malklarigilon, kaj ekde platforma versio 8.3.6 (oktobro 2014) ni komencis uzi Gugla Ferma Kompililo. La efiko de uzo en nombroj - la grandeco de la retklienta kadro post malklariĝo:

  • Propra malklarigaĵo – 1556 kb
  • Gugla Ferma Kompililo - 1073 kb

Uzado de Google Closure Compiler helpis nin plibonigi la agadon de la TTT-kliento je 30% kompare kun nia propra malklarigado. Krome, la kvanto de memoro konsumita de la aplikaĵo malpliiĝis je 15-25% (depende de la retumilo).

Google Closure Compiler funkcias tre bone kun objekto-orientita kodo, do ĝia efikeco por la retkliento estas kiel eble plej alta. Ferma Kompililo faras kelkajn bonajn aferojn por ni:

  • Senmova tipo-kontrolado ĉe la projekta konstrustadio (certas, ke ni kovras la kodon per JSDoc-anotadoj). La rezulto estas senmova tajpado, tre proksima en nivelo al tajpado en C++. Ĉi tio helpas kapti sufiĉe grandan procenton de eraroj ĉe la projekta kompila stadio.
  • Reduktante kodgrandecon per malklarigado
  • Kelkaj optimumigoj de la ekzekutita kodo, ekzemple, kiel:
    • enliniaj funkcioj anstataŭoj. Voki funkcion en JavaScript estas sufiĉe multekosta operacio, kaj enliniaj anstataŭoj de ofte uzataj malgrandaj metodoj signife plirapidigas la kodon.
    • Nombrante konstantojn je kompiltempo. Se esprimo dependas de konstanto, la reala valoro de la konstanto estos anstataŭigita en ĝi

Ni uzas WebStorm kiel nia retejo-klienta evolumedio.

Por koda analizo ni uzas soundQube, kie ni integras statikajn kodanalizilojn. Uzante analizilojn, ni kontrolas la degeneron de la kvalito de JavaScript fontkodo kaj provas malhelpi ĝin.

Pri la TTT-kliento 1C

Kiajn problemojn ni solvis?

Dum la efektivigo de la projekto, ni renkontis kelkajn interesajn problemojn, kiujn ni devis solvi.

Interŝanĝu datumojn kun la servilo kaj inter fenestroj

Estas situacioj kie malklarigado de la fontkodo povas malhelpi la funkciadon de la sistemo. Kodo ekstera al la plenumebla kodo de la retkliento, pro malklariĝo, povas havi funkciojn kaj parametrajn nomojn kiuj diferencas de tiuj, kiujn nia plenumebla kodo atendas. La ekstera kodo por ni estas:

  • Kodo venanta de la servilo en formo de datumstrukturoj
  • Kodo por alia aplika fenestro

Por eviti malklariĝon dum interagado kun la servilo, ni uzas la @expose-etikedon:

/**
 * @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;
}

Kaj por eviti malklariĝon dum interagado kun aliaj fenestroj, ni uzas tiel nomatajn eksportitajn interfacojn (interfacoj en kiuj ĉiuj metodoj estas eksportitaj).

/**
 * Экспортируемый интерфейс контрола 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 (){}

Ni uzis Virtualan DOM antaŭ ol ĝi iĝis ĉefa)

Kiel ĉiuj programistoj traktantaj kompleksajn Retajn UI-ojn, ni rapide rimarkis, ke la DOM ne taŭgas por labori kun dinamikaj uzantinterfacoj. Preskaŭ tuj, analogo de Virtuala DOM estis efektivigita por optimumigi laboron kun la UI. Dum okazaĵa prilaborado, ĉiuj DOM-ŝanĝoj estas konservitaj en memoro kaj, nur kiam ĉiuj operacioj estas finitaj, la akumulitaj ŝanĝoj estas aplikitaj al la DOM-arbo.

Optimumigo de la TTT-kliento

Por ke nia retkliento funkcii pli rapide, ni provas uzi la normajn retumeblajn kapablojn (CSS, ktp.) al la maksimumo. Tiel, la formulara komandpanelo (situanta sur preskaŭ ĉiu formo de la aplikaĵo) estas prezentita ekskluzive uzante retumilon, uzante dinamikan aranĝon bazitan sur CSS.

Pri la TTT-kliento 1C

Testado

Por funkciaj kaj agado-testoj, ni uzas proprietan ilon (skribitan en Java kaj C++), same kiel aron da testoj konstruitaj sur Seleno.

Nia ilo estas universala - ĝi ebligas al vi testi preskaŭ ajnan fenestran programon, kaj tial taŭgas por testi kaj maldikan klienton kaj retklienton. La ilo registras la agojn de la uzanto, kiu lanĉis la aplikaĵan solvon 1C en skriptodosieron. Samtempe, bildoj de la laborareo de la ekrano - normoj - estas registritaj. Kiam vi kontrolas novajn versiojn de la TTT-kliento, skriptoj ludas sen partopreno de uzantoj. En kazoj kie la ekrankopio ne kongruas kun la referenco unu ĉe iu paŝo, la testo estas konsiderata malsukcesa, post kio kvalita specialisto faras esploron por determini ĉu tio estas eraro aŭ planita ŝanĝo en la konduto de la sistemo. En kazo de planita konduto, la normoj estas aŭtomate anstataŭigitaj per novaj.

La ilo ankaŭ mezuras aplikan rendimenton kun precizeco de ĝis 25 milisekundoj. En iuj kazoj, ni buklas partojn de la skripto (ekzemple, ripetante la mendon plurfoje) por analizi la degeneron de ekzekuttempo laŭlonge de la tempo. La rezultoj de ĉiuj mezuradoj estas registritaj en protokolo por analizo.

Pri la TTT-kliento 1C
Nia testa ilo kaj aplikaĵo sub testo

Nia ilo kaj Seleno kompletigas unu la alian; ekzemple, se iu butono sur unu el la ekranoj ŝanĝis sian lokon, Selenium eble ne spuros ĉi tion, sed nia ilo rimarkos, ĉar faras piksel-post-pikselan komparon de la ekrankopio kun la normo. La ilo ankaŭ kapablas spuri problemojn pri prilaborado de enigo de la klavaro aŭ muso, ĉar ĉi tio estas ĝuste tio, kion ĝi reproduktas.

Testoj pri ambaŭ iloj (niaj kaj Selenio) funkcias tipajn laborscenarojn de niaj aplikaĵsolvoj. Testoj estas aŭtomate lanĉitaj post la ĉiutaga konstruo de la platformo 1C:Enterprise. Se skriptoj estas pli malrapidaj (kompare kun la antaŭa konstruo), ni esploras kaj solvas la kaŭzon de la malrapidiĝo. Nia kriterio estas simpla - la nova konstruo devus funkcii ne pli malrapide ol la antaŭa.

Programistoj uzas malsamajn ilojn por esplori malrapidajn okazaĵojn; ĉefe uzata Dynatrace AJAX Eldono produktentrepreno DynaTrace. Protokoloj de la ekzekuto de la problema operacio sur la antaŭaj kaj novaj konstruoj estas registritaj, tiam la protokoloj estas analizitaj. Samtempe, la ekzekuttempo de unuopaj operacioj (en milisekundoj) eble ne estas decida faktoro - servaj procezoj kiel rubokolektado estas periode lanĉitaj en la retumilo, ili povas interkovri kun la ekzekuttempo de funkcioj kaj distordi la bildon. Pli gravaj parametroj en ĉi tiu kazo estus la nombro da JavaScript-instrukcioj ekzekutitaj, la nombro da atomoperacioj sur la DOM, ktp. Se la nombro da instrukcioj/operacioj en la sama skripto pliiĝis en nova versio, ĉi tio preskaŭ ĉiam signifas malpliigon de rendimento, kiu devas esti korektita.

Ankaŭ, unu el la kialoj de la malpliiĝo de rendimento povas esti, ke Google Closure Compiler ial ne povis fari enlinian anstataŭigon de la funkcio (ekzemple ĉar la funkcio estas rekursiva aŭ virtuala). En ĉi tiu kazo, ni provas korekti la situacion reverkante la fontkodon.

Retumilo-etendaĵoj

Kiam aplika solvo bezonas funkciojn ne disponeblajn en JavaScript, ni uzas retumilajn etendojn:

Niaj etendaĵoj konsistas el du partoj. La unua parto estas tio, kio nomiĝas retumila etendaĵo (kutime etendaĵoj por Chrome kaj Fajrovulpo skribitaj en JavaScript), kiuj interagas kun la dua parto - binara etendaĵo kiu efektivigas la funkciojn, kiujn ni bezonas. Menciindas, ke ni skribas 3 versiojn de binaraj etendaĵoj - por Vindozo, Linukso kaj MacOS. La binara etendaĵo estas liverita kiel parto de la platformo 1C:Enterprise kaj situas sur la aplikaĵoservilo 1C. Kiam oni vokas por la unua fojo de retkliento, ĝi estas elŝutita al la klienta komputilo kaj instalita en la retumilo.

Dum funkciado en Safaro, niaj etendaĵoj uzas NPAPI; kiam ili funkcias en Internet Explorer, ili uzas ActiveX-teknologion. Microsoft Edge ankoraŭ ne subtenas etendaĵojn, do la retkliento en ĝi funkcias kun limigoj.

Pluevoluigo

Unu el la taskoj por la teamo de disvolvado de TTT-kliento estas la plua evoluo de funkcieco. La funkcieco de la retkliento devus esti identa al la funkcieco de la maldika kliento; ĉiu nova funkcieco estas efektivigita samtempe en kaj la maldika kaj retkliento.

Aliaj taskoj inkluzivas evoluigi la arkitekturon, refactoring, plibonigi rendimenton kaj fidindecon. Ekzemple, unu el la indikoj estas plia movado al nesinkrona labormodelo. Iuj el la funkcieco de la retkliento estas nuntempe konstruitaj sur sinkrona modelo de interago kun la servilo. La nesinkrona modelo nun fariĝas pli grava en retumiloj (kaj ne nur en retumiloj), kaj tio devigas nin modifi la TTT-klienton anstataŭigante sinkronajn alvokojn per nesinkronaj (kaj refactorigante la kodon laŭe). La laŭpaŝa transiro al nesinkrona modelo estas klarigita per la bezono subteni liberigitajn solvojn kaj ilian laŭpaŝan adaptadon.

fonto: www.habr.com

Aldoni komenton