Om 1C-webklienten

En af de gode egenskaber ved 1C:Enterprise-teknologi er, at applikationsløsningen, udviklet ved hjælp af managed forms-teknologi, kan lanceres både i en tynd (eksekverbar) klient til Windows, Linux, MacOS X og som en webklient til 5 browsere - Chrome, Internet Explorer, Firefox, Safari, Edge og alt dette uden at ændre applikationens kildekode. Ydermere fungerer applikationen eksternt i den tynde klient og i browseren og ser næsten identisk ud.
Find 10 forskelle (2 billeder under snittet):

Tyndt klientvindue på Linux:

Om 1C-webklienten

Det samme vindue i webklienten (i Chrome-browseren):

Om 1C-webklienten

Hvorfor lavede vi en webklient? For at sige det lidt patetisk, så har tiden stillet os sådan en opgave. At arbejde over internettet har længe været en forudsætning for forretningsapplikationer. For det første tilføjede vi muligheden for at arbejde via internettet for vores tynde klient (nogle af vores konkurrenter stoppede i øvrigt ved dette; andre, tværtimod, opgav den tynde klient og begrænsede sig til at implementere en webklient). Vi besluttede at give vores brugere mulighed for at vælge den kundemulighed, der passer dem bedst.

Om 1C-webklienten

Tilføjelse af webbaserede funktioner til den tynde klient var et stort projekt med en fuldstændig ændring i klient-server-arkitekturen. Oprettelse af en webklient er et helt nyt projekt, der starter fra bunden.

Formulering af problemet

Så projektkravene: webklienten skal gøre det samme som den tynde klient, nemlig:

  1. Vis brugergrænseflade
  2. Udfør klientkode skrevet i 1C sprog

Brugergrænsefladen i 1C er beskrevet i en visuel editor, men deklarativt, uden pixel-for-pixel arrangement af elementer; Der bruges omkring tre dusin typer interfaceelementer - knapper, inputfelter (tekst, numerisk, dato/klokkeslæt), lister, tabeller, grafer osv.

Klientkode på 1C-sproget kan indeholde serverkald, arbejde med lokale ressourcer (filer osv.), udskrivning og meget mere.

Både den tynde klient (når du arbejder via nettet) og webklienten bruger det samme sæt webtjenester til at kommunikere med 1C-applikationsserveren. Klientimplementeringer er selvfølgelig forskellige - den tynde klient er skrevet i C++, webklienten er skrevet i JavaScript.

Lidt historie

Webklientprojektet startede i 2006 med et team på (i gennemsnit) 5 personer. På visse stadier af projektet blev udviklere involveret for at implementere specifik funktionalitet (regnearksdokument, diagrammer osv.); som regel var det de samme udviklere, der lavede denne funktionalitet i den tynde klient. De der. udviklere omskrev komponenter i JavaScript, som de tidligere havde oprettet i C++.

Helt fra begyndelsen afviste vi ideen om enhver automatisk (selv delvis) konvertering af C++ tynd klientkode til JavaScript webklient på grund af de stærke konceptuelle forskelle mellem de to sprog; webklienten blev skrevet i JavaScript fra bunden.

I de første iterationer af projektet konverterede webklienten klientkode i det indbyggede 1C-sprog direkte til JavaScript. Den tynde klient opfører sig anderledes - koden i det indbyggede 1C-sprog kompileres til bytekode, og så tolkes denne bytekode på klienten. Efterfølgende begyndte webklienten at gøre det samme – for det første gav det en præstationsgevinst, og for det andet gjorde det det muligt at ensrette arkitekturen af ​​tynde og webklienter.

Den første version af 1C:Enterprise-platformen med webklientsupport blev udgivet i 2009. Webklienten på det tidspunkt understøttede 2 browsere - Internet Explorer og Firefox. De oprindelige planer omfattede support til Opera, men på grund af uoverstigelige problemer på det tidspunkt med applikationslukningshandlerne i Opera (det var ikke muligt at spore med 100 % sikkerhed, at applikationen lukkede, og på det tidspunkt udføre afbrydelsesproceduren fra 1C-applikationsserveren) fra disse planer måtte opgives.

Projektets struktur

I alt har 1C:Enterprise platformen 4 projekter skrevet i JavaScript:

  1. WebTools – delte biblioteker, der bruges af andre projekter (vi inkluderer også Google Lukningsbibliotek).
  2. Kontrolelement Formateret Dokument (implementeret i JavaScript i både den tynde klient og webklienten)
  3. Kontrolelement Planlægger (implementeret i JavaScript i både den tynde klient og webklienten)
  4. Web klient

Strukturen af ​​hvert projekt ligner strukturen af ​​Java-projekter (eller .NET-projekter - alt efter hvad der er tættest på); Vi har navneområder, og hvert navneområde er i en separat mappe. Inde i mappen er der filer og navneområdeklasser. Der er omkring 1000 filer i webklientprojektet.

Strukturelt er webklienten stort set opdelt i følgende undersystemer:

  • Administreret klientapplikationsgrænseflade
    • Generel applikationsgrænseflade (systemmenuer, paneler)
    • Grænseflade af administrerede formularer, herunder blandt andet omkring 30 kontroller (knapper, forskellige typer inputfelter - tekst, numerisk, dato/tid osv., tabeller, lister, grafer osv.)

  • Objektmodel tilgængelig for udviklere på klienten (over 400 typer i alt: styret interface objektmodel, datalayoutindstillinger, betinget styling osv.)
  • Tolk af det indbyggede 1C-sprog
  • Browserudvidelser (bruges til funktionalitet, der ikke understøttes i JavaScript)
    • Arbejder med kryptografi
    • Arbejde med filer
    • Teknologi af eksterne komponenter, så de kan bruges i både tynde klienter og webklienter

Udviklingsfunktioner

Det er ikke let at implementere alt ovenstående i JavaScript. Måske er 1C-webklienten en af ​​de største klientsideapplikationer skrevet i JavaScript - omkring 450.000 linjer. Vi bruger aktivt en objektorienteret tilgang i webklientkoden, hvilket letter arbejdet med så stort et projekt.

For at minimere størrelsen af ​​klientkoden brugte vi først vores egen obfuscator, og fra og med platformversion 8.3.6 (oktober 2014) begyndte vi at bruge Google Closure Compiler. Effekten af ​​brug i tal – størrelsen af ​​webklientrammerne efter sløring:

  • Egen obfuscator – 1556 kb
  • Google Closure Compiler – 1073 kb

Brug af Google Closure Compiler hjalp os med at forbedre ydeevnen af ​​webklienten med 30 % sammenlignet med vores egen obfuscator. Derudover er mængden af ​​hukommelse, der forbruges af applikationen, faldet med 15-25% (afhængigt af browseren).

Google Closure Compiler fungerer meget godt med objektorienteret kode, så dens effektivitet for webklienten er så høj som muligt. Closure Compiler gør et par gode ting for os:

  • Statisk typekontrol på projektopbygningsstadiet (sikker på, at vi dækker koden med JSDoc-annoteringer). Resultatet er statisk skrivning, meget tæt på at skrive i C++ i niveau. Dette hjælper med at fange en ret stor procentdel af fejl på projektkompileringsstadiet.
  • Reduktion af kodestørrelse gennem sløring
  • En række optimeringer af den udførte kode, for eksempel, såsom:
    • inline funktion substitutioner. At kalde en funktion i JavaScript er en ret dyr operation, og inline-erstatninger af ofte brugte små metoder fremskynder koden markant.
    • Tællekonstanter på kompileringstidspunktet. Hvis et udtryk afhænger af en konstant, vil den faktiske værdi af konstanten blive erstattet af den

Vi bruger WebStorm som vores webklientudviklingsmiljø.

Til kodeanalyse bruger vi SonarQube, hvor vi integrerer statiske kodeanalysatorer. Ved hjælp af analysatorer overvåger vi forringelsen af ​​kvaliteten af ​​JavaScript-kildekoden og forsøger at forhindre det.

Om 1C-webklienten

Hvilke problemer løste/løste vi?

Under gennemførelsen af ​​projektet stødte vi på en række interessante problemer, som vi skulle løse.

Udveksle data med serveren og mellem vinduer

Der er situationer, hvor sløring af kildekoden kan forstyrre driften af ​​systemet. Kode eksternt til webklientens eksekverbare kode kan på grund af sløring have funktions- og parameternavne, der adskiller sig fra dem, som vores eksekverbare kode forventer. Den eksterne kode for os er:

  • Kode, der kommer fra serveren i form af datastrukturer
  • Kode til et andet programvindue

For at undgå sløring, når vi interagerer med serveren, bruger vi @expose-tagget:

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

Og for at undgå sløring, når vi interagerer med andre vinduer, bruger vi såkaldte eksporterede grænseflader (grænseflader, hvor alle metoder eksporteres).

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

Vi brugte Virtual DOM, før det blev mainstream)

Som alle udviklere, der beskæftiger sig med komplekse web-UI'er, indså vi hurtigt, at DOM er dårligt egnet til at arbejde med dynamiske brugergrænseflader. Næsten øjeblikkeligt blev en analog af Virtual DOM implementeret for at optimere arbejdet med brugergrænsefladen. Under hændelsesbehandling gemmes alle DOM-ændringer i hukommelsen, og kun når alle operationer er fuldført, anvendes de akkumulerede ændringer på DOM-træet.

Optimering af webklienten

For at få vores webklient til at fungere hurtigere, forsøger vi at bruge standardbrowserfunktionerne (CSS osv.) maksimalt. Således gengives formularkommandopanelet (placeret på næsten enhver form af applikationen) udelukkende ved hjælp af browserværktøjer, ved hjælp af dynamisk layout baseret på CSS.

Om 1C-webklienten

Test

Til funktions- og ydeevnetestning bruger vi et proprietært værktøj (skrevet i Java og C++), samt en række tests bygget oven på Selen.

Vores værktøj er universelt - det giver dig mulighed for at teste næsten ethvert vinduesprogram, og er derfor velegnet til at teste både en tynd klient og en webklient. Værktøjet registrerer handlingerne fra den bruger, der lancerede 1C-applikationsløsningen, i en scriptfil. Samtidig optages billeder af arbejdsområdet på skærmen - standarder -. Ved overvågning af nye versioner af webklienten afspilles scripts uden brugerdeltagelse. I tilfælde, hvor skærmbilledet ikke matcher referencen på noget trin, betragtes testen som mislykket, hvorefter en kvalitetsspecialist foretager en undersøgelse for at fastslå, om der er tale om en fejl eller en planlagt ændring i systemets adfærd. I tilfælde af planlagt adfærd erstattes standarderne automatisk med nye.

Værktøjet måler også applikationsydelse med en nøjagtighed på op til 25 millisekunder. I nogle tilfælde sløjfer vi dele af scriptet (for eksempel ved at gentage ordreindtastningen flere gange) for at analysere forringelsen af ​​eksekveringstiden over tid. Resultaterne af alle målinger registreres i en log til analyse.

Om 1C-webklienten
Vores testværktøj og applikation under test

Vores værktøj og Selen supplerer hinanden; for eksempel, hvis en knap på en af ​​skærmene har ændret sin placering, sporer Selen muligvis ikke dette, men vores værktøj vil bemærke det, fordi foretager en pixel-for-pixel sammenligning af skærmbilledet med standarden. Værktøjet er også i stand til at spore problemer med at behandle input fra tastaturet eller musen, da det er præcis, hvad det gengiver.

Test på begge værktøjer (vores og Selenium) kører typiske arbejdsscenarier fra vores applikationsløsninger. Tests lanceres automatisk efter den daglige opbygning af 1C:Enterprise-platformen. Hvis scripts er langsommere (sammenlignet med den tidligere build), undersøger og løser vi årsagen til opbremsningen. Vores kriterium er enkelt - den nye konstruktion bør ikke fungere langsommere end den forrige.

Udviklere bruger forskellige værktøjer til at undersøge opbremsningshændelser; hovedsagelig brugt Dynatrace AJAX Edition produktionsselskab DynaTrace. Logfiler over udførelsen af ​​den problematiske operation på de tidligere og nye builds registreres, derefter analyseres logfilerne. Samtidig er udførelsestiden for enkeltoperationer (i millisekunder) muligvis ikke en afgørende faktor - serviceprocesser såsom affaldsindsamling startes med jævne mellemrum i browseren, de kan overlappe med udførelsen af ​​funktioner og forvrænge billedet. Mere relevante parametre i dette tilfælde ville være antallet af udførte JavaScript-instruktioner, antallet af atomariske operationer på DOM osv. Hvis antallet af instruktioner/operationer i samme script er steget i en ny version, betyder det næsten altid et fald i ydeevnen, som skal rettes.

En af årsagerne til faldet i ydeevne kan også være, at Google Closure Compiler af en eller anden grund ikke var i stand til at udføre inline substitution af funktionen (for eksempel fordi funktionen er rekursiv eller virtuel). I dette tilfælde forsøger vi at rette op på situationen ved at omskrive kildekoden.

Browserudvidelser

Når en applikationsløsning har brug for funktionalitet, der ikke er tilgængelig i JavaScript, bruger vi browserudvidelser:

Vores tilbygninger består af to dele. Den første del er det, der kaldes en browserudvidelse (normalt udvidelser til Chrome og Firefox skrevet i JavaScript), som interagerer med den anden del – en binær udvidelse, der implementerer den funktionalitet, vi har brug for. Det skal nævnes, at vi skriver 3 versioner af binære udvidelser - til Windows, Linux og MacOS. Den binære udvidelse leveres som en del af 1C:Enterprise-platformen og er placeret på 1C-applikationsserveren. Første gang den kaldes fra en webklient, downloades den til klientcomputeren og installeres i browseren.

Når de kører i Safari, bruger vores udvidelser NPAPI; når de kører i Internet Explorer, bruger de ActiveX-teknologi. Microsoft Edge understøtter endnu ikke udvidelser, så webklienten i den arbejder med begrænsninger.

Yderligere udvikling

En af opgaverne for webklientudviklingsteamet er videreudvikling af funktionalitet. Funktionaliteten af ​​webklienten skal være identisk med funktionaliteten af ​​den tynde klient; al ny funktionalitet implementeres samtidigt i både den tynde klient og webklienten.

Andre opgaver omfatter udvikling af arkitekturen, refactoring, forbedring af ydeevne og pålidelighed. For eksempel er en af ​​retningerne yderligere bevægelse mod en asynkron arbejdsmodel. Nogle af funktionaliteten i webklienten er i øjeblikket bygget på en synkron model for interaktion med serveren. Den asynkrone model bliver nu mere relevant i browsere (og ikke kun i browsere), og det tvinger os til at ændre webklienten ved at erstatte synkrone opkald med asynkrone (og omstrukturere koden i overensstemmelse hermed). Den gradvise overgang til en asynkron model forklares med behovet for at understøtte frigivne løsninger og deres gradvise tilpasning.

Kilde: www.habr.com

Tilføj en kommentar