Informazioni sul client Web 1C

Una delle caratteristiche interessanti della tecnologia 1C:Enterprise è che la soluzione applicativa, sviluppata utilizzando la tecnologia dei moduli gestiti, può essere avviata sia come thin client (eseguibile) per Windows, Linux, MacOS X, sia come client web per 5 browser - Chrome, Internet Explorer, Firefox, Safari, Edge e tutto questo senza modificare il codice sorgente dell'applicazione. Inoltre, esternamente l'applicazione nel thin client e nel browser funziona e sembra quasi identica.
Trova 10 differenze (2 immagini sotto il taglio):

Finestra thin client su Linux:

Informazioni sul client Web 1C

La stessa finestra nel client web (nel browser Chrome):

Informazioni sul client Web 1C

Perché abbiamo creato un client web? Per dirla in modo un po' patetico, il tempo ci ha assegnato un simile compito. Lavorare su Internet è da tempo un prerequisito per le applicazioni aziendali. Per prima cosa abbiamo aggiunto la possibilità di lavorare via Internet per il nostro thin client (alcuni dei nostri concorrenti, tra l'altro, si sono fermati qui; altri, al contrario, hanno abbandonato il thin client e si sono limitati a implementare un web client). Abbiamo deciso di dare ai nostri utenti l'opportunità di scegliere l'opzione client più adatta a loro.

Informazioni sul client Web 1C

L'aggiunta di funzionalità basate sul Web al thin client è stato un grande progetto con un cambiamento completo nell'architettura client-server. Creare un client web è un progetto completamente nuovo, che parte da zero.

Formulazione del problema

Quindi i requisiti del progetto: il web client deve fare la stessa cosa del thin client e cioè:

  1. Visualizza l'interfaccia utente
  2. Esegui il codice client scritto nel linguaggio 1C

L'interfaccia utente in 1C è descritta in un editor visivo, ma in modo dichiarativo, senza disposizione degli elementi pixel per pixel; Vengono utilizzati circa tre dozzine di tipi di elementi dell'interfaccia: pulsanti, campi di input (testo, numerici, data/ora), elenchi, tabelle, grafici, ecc.

Il codice client nel linguaggio 1C può contenere chiamate al server, lavorare con risorse locali (file, ecc.), Stampa e molto altro.

Sia il thin client (quando si lavora tramite web) che il client web utilizzano lo stesso set di servizi web per comunicare con il server delle applicazioni 1C. Le implementazioni client, ovviamente, sono diverse: il thin client è scritto in C++, il client Web è scritto in JavaScript.

Un po 'di storia

Il progetto web client è iniziato nel 2006, con un team di (in media) 5 persone. In alcune fasi del progetto, gli sviluppatori sono stati coinvolti per implementare funzionalità specifiche (documento foglio di calcolo, diagrammi, ecc.); di norma, questi erano gli stessi sviluppatori che eseguivano questa funzionalità nel thin client. Quelli. gli sviluppatori hanno riscritto i componenti in JavaScript che avevano precedentemente creato in C++.

Fin dall'inizio abbiamo rifiutato l'idea di una qualsiasi conversione automatica (anche parziale) del codice thin client C++ in client web JavaScript a causa delle forti differenze concettuali tra i due linguaggi; il client web è stato scritto da zero in JavaScript.

Nelle prime iterazioni del progetto, il client web ha convertito il codice client nel linguaggio 1C integrato direttamente in JavaScript. Il thin client agisce in modo diverso: il codice nel linguaggio 1C integrato viene compilato in bytecode e quindi questo bytecode viene interpretato sul client. Successivamente, il client Web ha iniziato a fare lo stesso: in primo luogo, ha fornito un aumento delle prestazioni e, in secondo luogo, ha permesso di unificare l'architettura del thin client e del web client.

La prima versione della piattaforma 1C:Enterprise con supporto client web è stata rilasciata nel 2009. Il client Web a quel tempo supportava 2 browser: Internet Explorer e Firefox. I piani originali includevano il supporto per Opera, ma a causa di problemi insormontabili all'epoca con i gestori di chiusura dell'applicazione in Opera (non era possibile monitorare con certezza al 100% che l'applicazione si stava chiudendo ed eseguire in quel momento la procedura di disconnessione da il server applicativo 1C) da questi piani dovette essere abbandonato.

Struttura del progetto

In totale, la piattaforma 1C:Enterprise ha 4 progetti scritti in JavaScript:

  1. WebTools – librerie condivise utilizzate da altri progetti (includiamo anche Libreria di chiusura di Google).
  2. Elemento di controllo Documento formattato (implementato in JavaScript sia nel thin client che nel web client)
  3. Elemento di controllo Pianificatore (implementato in JavaScript sia nel thin client che nel web client)
  4. Cliente Web

La struttura di ciascun progetto assomiglia alla struttura dei progetti Java (o dei progetti .NET, a seconda di quale sia il più vicino); Abbiamo spazi dei nomi e ogni spazio dei nomi si trova in una cartella separata. All'interno della cartella sono presenti file e classi di namespace. Sono presenti circa 1000 file nel progetto client Web.

Strutturalmente il web client è sostanzialmente suddiviso nei seguenti sottosistemi:

  • Interfaccia dell'applicazione client gestita
    • Interfaccia generale dell'applicazione (menu di sistema, pannelli)
    • Interfaccia della modulistica gestita, comprendente, tra l'altro, circa 30 controlli (pulsanti, campi di input di vario tipo - testuali, numerici, data/ora, ecc., tabelle, elenchi, grafici, ecc.)

  • Modello a oggetti disponibile per gli sviluppatori sul client (oltre 400 tipi in totale: modello a oggetti dell'interfaccia gestita, impostazioni del layout dei dati, stile condizionale, ecc.)
  • Interprete del linguaggio 1C integrato
  • Estensioni del browser (utilizzate per funzionalità non supportate in JavaScript)
    • Lavorare con la crittografia
    • Lavorare con i file
    • Tecnologia dei componenti esterni, che ne consente l'utilizzo sia nei thin client che nei web client

Caratteristiche di sviluppo

Implementare tutto quanto sopra in JavaScript non è facile. Forse il client Web 1C è una delle più grandi applicazioni lato client scritte in JavaScript: circa 450.000 righe. Utilizziamo attivamente un approccio orientato agli oggetti nel codice del client web, che semplifica il lavoro con un progetto così grande.

Per ridurre al minimo la dimensione del codice client, abbiamo prima utilizzato il nostro offuscatore e, a partire dalla versione 8.3.6 della piattaforma (ottobre 2014), abbiamo iniziato a utilizzare Compilatore di chiusura di Google. L’effetto dell’uso in numeri – la dimensione del framework del web client dopo l’offuscamento:

  • Proprio offuscatore – 1556 kb
  • Compilatore di chiusura di Google – 1073 kb

L'utilizzo di Google Closure Compiler ci ha aiutato a migliorare le prestazioni del client web del 30% rispetto al nostro offuscatore. Inoltre, la quantità di memoria consumata dall'applicazione è diminuita del 15-25% (a seconda del browser).

Google Closure Compiler funziona molto bene con il codice orientato agli oggetti, quindi la sua efficienza per il client web è la più alta possibile. Closure Compiler fa alcune cose buone per noi:

  • Controllo del tipo statico in fase di creazione del progetto (garantisce di coprire il codice con annotazioni JSDoc). Il risultato è una digitazione statica, di livello molto vicino alla digitazione in C++. Ciò aiuta a individuare una percentuale abbastanza elevata di errori nella fase di compilazione del progetto.
  • Ridurre la dimensione del codice attraverso l'offuscamento
  • Una serie di ottimizzazioni del codice eseguito, ad esempio, come:
    • sostituzioni di funzioni in linea. Chiamare una funzione in JavaScript è un'operazione piuttosto costosa e le sostituzioni in linea di piccoli metodi utilizzati di frequente accelerano notevolmente il codice.
    • Conteggio delle costanti in fase di compilazione. Se un'espressione dipende da una costante, verrà sostituito il valore effettivo della costante

Utilizziamo WebStorm come ambiente di sviluppo del client Web.

Per l'analisi del codice utilizziamo soundQube, dove integriamo analizzatori di codice statici. Utilizzando gli analizzatori, monitoriamo il degrado della qualità del codice sorgente JavaScript e cerchiamo di prevenirlo.

Informazioni sul client Web 1C

Quali problemi abbiamo/stiamo risolvendo?

Durante l'implementazione del progetto, abbiamo riscontrato una serie di problemi interessanti che abbiamo dovuto risolvere.

Scambia dati con il server e tra finestre

Esistono situazioni in cui l'offuscamento del codice sorgente può interferire con il funzionamento del sistema. Il codice esterno all'eseguibile del web client, a causa dell'offuscamento, potrebbe avere nomi di funzioni e parametri diversi da quelli previsti dal nostro codice eseguibile. Il codice esterno per noi è:

  • Codice proveniente dal server sotto forma di strutture dati
  • Codice per un'altra finestra dell'applicazione

Per evitare offuscamenti durante l'interazione con il server, utilizziamo il tag @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;
}

E per evitare offuscamenti quando si interagisce con altre finestre, utilizziamo le cosiddette interfacce esportate (interfacce in cui vengono esportati tutti i metodi).

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

Usavamo Virtual DOM prima che diventasse mainstream)

Come tutti gli sviluppatori che hanno a che fare con interfacce utente Web complesse, ci siamo subito resi conto che il DOM è poco adatto a lavorare con interfacce utente dinamiche. Quasi immediatamente è stato implementato un analogo del DOM virtuale per ottimizzare il lavoro con l'interfaccia utente. Durante l'elaborazione degli eventi, tutte le modifiche del DOM vengono archiviate in memoria e, solo quando tutte le operazioni sono completate, le modifiche accumulate vengono applicate all'albero del DOM.

Ottimizzazione del client web

Per far funzionare il nostro client web più velocemente, cerchiamo di utilizzare al massimo le funzionalità standard del browser (CSS, ecc.). Pertanto, il pannello di comando del modulo (situato su quasi tutti i moduli dell'applicazione) viene visualizzato esclusivamente utilizzando gli strumenti del browser, utilizzando un layout dinamico basato su CSS.

Informazioni sul client Web 1C

Test

Per i test funzionali e prestazionali utilizziamo uno strumento proprietario (scritto in Java e C++), nonché una suite di test costruita sulla base di Selenio.

Il nostro strumento è universale: ti consente di testare quasi tutti i programmi a finestre e quindi è adatto per testare sia un thin client che un client web. Lo strumento registra le azioni dell'utente che ha avviato la soluzione applicativa 1C in un file script. Allo stesso tempo vengono registrate le immagini dell'area di lavoro dello schermo (standard). Durante il monitoraggio delle nuove versioni del client Web, gli script vengono riprodotti senza la partecipazione dell'utente. Nei casi in cui lo screenshot non corrisponde a quello di riferimento in nessun passaggio, il test viene considerato fallito, dopodiché uno specialista della qualità conduce un'indagine per determinare se si tratta di un errore o di un cambiamento pianificato nel comportamento del sistema. In caso di comportamento pianificato, gli standard vengono automaticamente sostituiti con nuovi.

Lo strumento misura anche le prestazioni dell'applicazione con una precisione fino a 25 millisecondi. In alcuni casi, eseguiamo il loop di parti dello script (ad esempio, ripetendo più volte l'immissione dell'ordine) per analizzare il degrado del tempo di esecuzione nel tempo. I risultati di tutte le misurazioni vengono registrati in un registro per l'analisi.

Informazioni sul client Web 1C
Il nostro strumento di test e l'applicazione sotto test

Il nostro strumento e Selenium si completano a vicenda; ad esempio, se qualche pulsante su uno degli schermi ha cambiato posizione, Selenium potrebbe non tenerne traccia, ma il nostro strumento se ne accorgerà, perché effettua un confronto pixel per pixel dello screenshot con lo standard. Lo strumento è anche in grado di tenere traccia dei problemi con l'elaborazione dell'input dalla tastiera o dal mouse, poiché è esattamente ciò che riproduce.

I test su entrambi gli strumenti (il nostro e Selenium) eseguono scenari di lavoro tipici delle nostre soluzioni applicative. I test vengono avviati automaticamente dopo la creazione quotidiana della piattaforma 1C:Enterprise. Se gli script sono più lenti (rispetto alla build precedente), investighiamo e risolviamo la causa del rallentamento. Il nostro criterio è semplice: la nuova build non dovrebbe funzionare più lentamente della precedente.

Gli sviluppatori utilizzano diversi strumenti per indagare sugli incidenti di rallentamento; principalmente utilizzato Edizione Dynatrace AJAX società di produzione DynaTrace. Vengono registrati i registri dell'esecuzione dell'operazione problematica sulle build precedenti e nuove, quindi i registri vengono analizzati. Allo stesso tempo, il tempo di esecuzione delle singole operazioni (in millisecondi) potrebbe non essere un fattore decisivo: processi di servizio come la garbage collection vengono periodicamente avviati nel browser, possono sovrapporsi al tempo di esecuzione delle funzioni e distorcere l'immagine. I parametri più rilevanti in questo caso sarebbero il numero di istruzioni JavaScript eseguite, il numero di operazioni atomiche sul DOM, ecc. Se il numero di istruzioni/operazioni nello stesso script è aumentato in una nuova versione, ciò significa quasi sempre un calo di prestazioni che deve essere corretto.

Inoltre, uno dei motivi del calo delle prestazioni potrebbe essere che Google Closure Compiler per qualche motivo non è stato in grado di eseguire la sostituzione in linea della funzione (ad esempio perché la funzione è ricorsiva o virtuale). In questo caso, proviamo a correggere la situazione riscrivendo il codice sorgente.

Estensioni del browser

Quando una soluzione applicativa necessita di funzionalità non disponibili in JavaScript, utilizziamo le estensioni del browser:

  • per lavorare con i file
  • per lavorare con la crittografia
  • lavorare con componenti esterni

Le nostre estensioni sono composte da due parti. La prima parte è quella che viene chiamata estensione del browser (di solito estensioni per Chrome e Firefox scritte in JavaScript), che interagiscono con la seconda parte: un'estensione binaria che implementa la funzionalità di cui abbiamo bisogno. Va detto che scriviamo 3 versioni di estensioni binarie: per Windows, Linux e MacOS. L'estensione binaria viene fornita come parte della piattaforma 1C:Enterprise e si trova sul server delle applicazioni 1C. Quando viene richiamato per la prima volta da un client Web, viene scaricato sul computer client e installato nel browser.

Quando vengono eseguite in Safari, le nostre estensioni utilizzano NPAPI; quando vengono eseguite in Internet Explorer, utilizzano la tecnologia ActiveX. Microsoft Edge non supporta ancora le estensioni, quindi il client Web al suo interno funziona con restrizioni.

Ulteriore sviluppo

Uno dei compiti del team di sviluppo del client web è l'ulteriore sviluppo delle funzionalità. La funzionalità del web client dovrebbe essere identica alla funzionalità del thin client; tutte le nuove funzionalità vengono implementate contemporaneamente sia nel thin che nel web client.

Altre attività includono lo sviluppo dell'architettura, il refactoring, il miglioramento delle prestazioni e dell'affidabilità. Ad esempio, una delle direzioni è l’ulteriore movimento verso un modello di lavoro asincrono. Alcune funzionalità del client Web sono attualmente basate su un modello sincrono di interazione con il server. Il modello asincrono sta diventando sempre più rilevante nei browser (e non solo nei browser), e questo ci costringe a modificare il client web sostituendo le chiamate sincrone con quelle asincrone (e refactoring il codice di conseguenza). La graduale transizione verso un modello asincrono si spiega con la necessità di supportare le soluzioni rilasciate e il loro graduale adattamento.

Fonte: habr.com

Aggiungi un commento