Acerca do cliente web 1C

Unha das boas características da tecnoloxía 1C:Enterprise é que a solución de aplicacións, desenvolvida mediante a tecnoloxía de formularios xestionados, pódese lanzar tanto nun cliente fino (executábel) para Windows, Linux, MacOS X como como cliente web para 5 navegadores. Chrome, Internet Explorer, Firefox, Safari, Edge, e todo isto sen cambiar o código fonte da aplicación. Ademais, externamente a aplicación no cliente lixeiro e no navegador funciona e parece case idéntica.
Busca 10 diferenzas (2 imaxes baixo o corte):

Ventá de cliente lixeiro en Linux:

Acerca do cliente web 1C

A mesma fiestra no cliente web (no navegador Chrome):

Acerca do cliente web 1C

Por que fixemos un cliente web? Por dicilo un tanto patético, o tempo púxonos unha tarefa así. Traballar a través de Internet foi durante moito tempo un requisito previo para as aplicacións empresariais. En primeiro lugar, engadimos a posibilidade de traballar a través de Internet para o noso cliente ligero (algúns dos nosos competidores, por certo, detivéronse aí; outros, pola contra, abandonaron o cliente lixeiro e limitáronse a implementar un cliente web). Decidimos darlles aos nosos usuarios a oportunidade de escoller a opción de cliente que máis lles conveña.

Acerca do cliente web 1C

Engadir capacidades baseadas na web ao cliente lixeiro foi un gran proxecto cun cambio completo na arquitectura cliente-servidor. Crear un cliente web é un proxecto completamente novo, comezando desde cero.

Declaración de problemas

Polo tanto, os requisitos do proxecto: o cliente web debe facer o mesmo que o cliente lixeiro, a saber:

  1. Mostrar a interface de usuario
  2. Executar código de cliente escrito en linguaxe 1C

A interface de usuario en 1C descríbese nun editor visual, pero de forma declarativa, sen disposición de elementos píxel por píxel; Utilízanse preto de tres ducias de tipos de elementos da interface: botóns, campos de entrada (texto, numérico, data/hora), listas, táboas, gráficos, etc.

O código de cliente na linguaxe 1C pode conter chamadas ao servidor, traballar con recursos locais (ficheiros, etc.), imprimir e moito máis.

Tanto o cliente fino (cando traballa a través da web) como o cliente web usan o mesmo conxunto de servizos web para comunicarse co servidor de aplicacións 1C. As implementacións do cliente, por suposto, son diferentes: o cliente lixeiro está escrito en C++, o cliente web está escrito en JavaScript.

Un pouco de historia

O proxecto de cliente web comezou en 2006, cun equipo de (de media) 5 persoas. En determinadas fases do proxecto, os desenvolvedores foron implicados para implementar unha funcionalidade específica (documento de folla de cálculo, diagramas, etc.); por regra xeral, estes foron os mesmos desenvolvedores que fixeron esta funcionalidade no cliente lixeiro. Eses. os desenvolvedores volveron escribir compoñentes en JavaScript que crearan previamente en C++.

Desde o primeiro momento, rexeitamos a idea de calquera conversión automática (mesmo parcial) do código de cliente lixeiro C++ en cliente web JavaScript debido ás fortes diferenzas conceptuais entre as dúas linguaxes; o cliente web foi escrito en JavaScript desde cero.

Nas primeiras iteracións do proxecto, o cliente web converteu o código do cliente na linguaxe 1C integrada directamente en JavaScript. O thin client actúa de forma diferente: o código na linguaxe 1C incorporada compílase en bytecode e, a continuación, este bytecode interprétase no cliente. Posteriormente, o cliente web comezou a facer o mesmo: en primeiro lugar, deu unha ganancia de rendemento e, en segundo lugar, permitiu unificar a arquitectura dos clientes lixeiros e web.

A primeira versión da plataforma 1C:Enterprise con soporte para clientes web publicouse en 2009. O cliente web nese momento admitía 2 navegadores: Internet Explorer e Firefox. Os plans orixinais incluían soporte para Opera, pero debido a problemas insalvables naquel momento cos controladores de peche da aplicación en Opera (non era posible rastrexar cun 100% de certeza de que a aplicación se estaba pechando, e nese momento realizar o procedemento de desconexión de o servidor de aplicacións 1C) destes plans tivo que ser abandonado.

Estrutura do proxecto

En total, a plataforma 1C:Enterprise conta con 4 proxectos escritos en JavaScript:

  1. WebTools: bibliotecas compartidas utilizadas por outros proxectos (tamén incluímos Biblioteca de Google Closure).
  2. Elemento de control Documento formateado (implementado en JavaScript tanto no cliente lixeiro como no cliente web)
  3. Elemento de control Programador (implementado en JavaScript tanto no cliente lixeiro como no cliente web)
  4. Cliente web

A estrutura de cada proxecto aseméllase á estrutura dos proxectos Java (ou proxectos .NET - o que estea máis próximo); Temos espazos de nomes e cada espazo de nomes está nun cartafol separado. Dentro do cartafol hai ficheiros e clases de espazo de nomes. Hai uns 1000 ficheiros no proxecto do cliente web.

Estruturalmente, o cliente web divídese en gran parte nos seguintes subsistemas:

  • Interface de aplicación cliente xestionada
    • Interface xeral da aplicación (menús do sistema, paneis)
    • Interface de formularios xestionados, incluíndo, entre outras cousas, uns 30 controis (botóns, varios tipos de campos de entrada: texto, numéricos, data/hora, etc., táboas, listas, gráficos, etc.)

  • Modelo de obxectos dispoñible para desenvolvedores no cliente (máis de 400 tipos en total: modelo de obxectos de interface xestionada, configuración de deseño de datos, estilo condicional, etc.)
  • Intérprete da linguaxe 1C incorporada
  • Extensións do navegador (utilizadas para funcións non admitidas en JavaScript)
    • Traballar coa criptografía
    • Traballar con ficheiros
    • Tecnoloxía de compoñentes externos, que permiten o seu uso tanto en clientes lixeiros como web

Características de desenvolvemento

Implementar todo o anterior en JavaScript non é sinxelo. Quizais o cliente web 1C sexa unha das maiores aplicacións do lado do cliente escritas en JavaScript: unhas 450.000 liñas. Usamos activamente un enfoque orientado a obxectos no código do cliente web, o que simplifica o traballo cun proxecto tan grande.

Para minimizar o tamaño do código do cliente, primeiro usamos o noso propio ofuscador, e comezando coa versión da plataforma 8.3.6 (outubro de 2014) comezamos a usar Compilador de peche de Google. O efecto do uso en números: o tamaño do cadro de cliente web despois da ofuscación:

  • Ofuscador propio – 1556 kb
  • Compilador de peche de Google - 1073 kb

Usar Google Closure Compiler axudounos a mellorar o rendemento do cliente web nun 30 % en comparación co noso propio ofuscador. Ademais, a cantidade de memoria consumida pola aplicación diminuíu nun 15-25% (dependendo do navegador).

Google Closure Compiler funciona moi ben co código orientado a obxectos, polo que a súa eficiencia para o cliente web é o máis alta posible. Closure Compiler fai algunhas cousas boas por nós:

  • Comprobación de tipo estático na fase de construción do proxecto (garantiza que cubrimos o código con anotacións JSDoc). O resultado é a dixitación estática, moi próximo en nivel ao escribir en C++. Isto axuda a detectar unha porcentaxe bastante grande de erros na fase de compilación do proxecto.
  • Reducir o tamaño do código a través da ofuscación
  • Unha serie de optimizacións do código executado, por exemplo, como:
    • substitucións de funcións en liña. Chamar unha función en JavaScript é unha operación bastante cara, e as substitucións en liña de pequenos métodos de uso frecuente aceleran significativamente o código.
    • Conta constantes en tempo de compilación. Se unha expresión depende dunha constante, substituirase o valor real da constante

Usamos WebStorm como o noso contorno de desenvolvemento de clientes web.

Para a análise do código usamos soundQube, onde integramos analizadores de código estático. Usando analizadores, monitorizamos a degradación da calidade do código fonte de JavaScript e tratamos de evitalo.

Acerca do cliente web 1C

Que problemas resolvemos/estamos solucionando?

Durante a posta en marcha do proxecto, atopamos unha serie de problemas interesantes que tivemos que resolver.

Intercambia datos co servidor e entre Windows

Hai situacións nas que a ofuscación do código fonte pode interferir co funcionamento do sistema. O código externo ao código executable do cliente web, debido á ofuscación, pode ter nomes de función e parámetro que difiran dos que espera o noso código executable. O código externo para nós é:

  • Código procedente do servidor en forma de estruturas de datos
  • Código para outra xanela da aplicación

Para evitar ofuscamentos ao interactuar co servidor, usamos a etiqueta @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 para evitar ofuscamentos ao interactuar con outras fiestras, utilizamos as chamadas interfaces exportadas (interfaces nas que se exportan todos os métodos).

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

Usamos Virtual DOM antes de que se convertese en mainstream)

Como todos os desenvolvedores que tratan con interfaces de usuario web complexas, axiña decatámonos de que o DOM non é adecuado para traballar con interfaces de usuario dinámicas. Case inmediatamente, implementouse un análogo de Virtual DOM para optimizar o traballo coa IU. Durante o procesamento de eventos, todos os cambios DOM almacénanse na memoria e, só cando se completan todas as operacións, os cambios acumulados aplícanse á árbore DOM.

Optimización do cliente web

Para que o noso cliente web funcione máis rápido, intentamos utilizar ao máximo as capacidades estándar do navegador (CSS, etc.). Así, o panel de comandos do formulario (situado en case todas as formas da aplicación) represéntase exclusivamente mediante ferramentas do navegador, utilizando un deseño dinámico baseado en CSS.

Acerca do cliente web 1C

Probas

Para probas funcionais e de rendemento, usamos unha ferramenta propietaria (escrita en Java e C++), así como unha serie de probas construídas enriba de Selenio.

A nosa ferramenta é universal: permítelle probar case calquera programa con fiestras e, polo tanto, é adecuada para probar tanto un cliente lixeiro como un cliente web. A ferramenta rexistra as accións do usuario que lanzou a solución da aplicación 1C nun ficheiro de script. Ao mesmo tempo, grávanse imaxes da área de traballo da pantalla (estándares). Ao supervisar novas versións do cliente web, os guións reprodúcense sen a participación do usuario. Nos casos en que a captura de pantalla non coincide coa de referencia en calquera paso, a proba considérase fallida, tras o cal un especialista en calidade realiza unha investigación para determinar se se trata dun erro ou dun cambio planificado no comportamento do sistema. En caso de comportamento planificado, as normas substitúense automaticamente por outras novas.

A ferramenta tamén mide o rendemento da aplicación cunha precisión de ata 25 milisegundos. Nalgúns casos, realizamos un bucle de partes do script (por exemplo, repetindo a entrada da orde varias veces) para analizar a degradación do tempo de execución ao longo do tempo. Os resultados de todas as medicións rexístranse nun rexistro para a súa análise.

Acerca do cliente web 1C
A nosa ferramenta de proba e aplicación en proba

A nosa ferramenta e Selenium complétanse mutuamente; por exemplo, se algún botón dunha das pantallas cambiou a súa localización, Selenium pode non rastrexar isto, pero a nosa ferramenta notarao, porque fai unha comparación píxel por píxel da captura de pantalla co estándar. A ferramenta tamén é capaz de rastrexar problemas ao procesar a entrada desde o teclado ou o rato, xa que isto é exactamente o que reproduce.

As probas de ambas ferramentas (a nosa e Selenium) executan escenarios de traballo típicos das nosas solucións de aplicacións. As probas lánzanse automaticamente despois da compilación diaria da plataforma 1C:Enterprise. Se os scripts son máis lentos (en comparación coa compilación anterior), investigamos e resolvemos a causa da desaceleración. O noso criterio é sinxelo: a nova construción non debería funcionar máis lenta que a anterior.

Os desenvolvedores usan diferentes ferramentas para investigar incidentes de desaceleración; utilizado principalmente Dynatrace Edición AJAX empresa de produción DynaTrace. Rexístranse rexistros da execución da operación problemática nas construcións anteriores e novas, despois analízanse os rexistros. Ao mesmo tempo, o tempo de execución de operacións individuais (en milisegundos) pode non ser un factor decisivo: procesos de servizo como a recollida de lixo lánzanse periodicamente no navegador, poden superpoñerse co tempo de execución das funcións e distorsionar a imaxe. Os parámetros máis relevantes neste caso serían o número de instrucións JavaScript executadas, o número de operacións atómicas no DOM, etc. Se o número de instrucións/operacións nun mesmo script aumentou nunha nova versión, isto case sempre significa unha caída no rendemento que hai que corrixir.

Ademais, un dos motivos da caída do rendemento pode ser que Google Closure Compiler por algún motivo non puido realizar a substitución en liña da función (por exemplo, porque a función é recursiva ou virtual). Neste caso, tentamos corrixir a situación reescribindo o código fonte.

Extensións do navegador

Cando unha solución de aplicación necesita unha funcionalidade que non está dispoñible en JavaScript, usamos extensións do navegador:

As nosas extensións constan de dúas partes. A primeira parte é o que se chama extensión do navegador (xeralmente extensións para Chrome e Firefox escritas en JavaScript), que interactúan coa segunda parte: unha extensión binaria que implementa a funcionalidade que necesitamos. Hai que mencionar que escribimos 3 versións de extensións binarias: para Windows, Linux e MacOS. A extensión binaria ofrécese como parte da plataforma 1C:Enterprise e está situada no servidor de aplicacións 1C. Cando se chama por primeira vez desde un cliente web, descárgase no ordenador cliente e instálase no navegador.

Cando se executan en Safari, as nosas extensións usan NPAPI; cando se executan en Internet Explorer, usan tecnoloxía ActiveX. Microsoft Borde aínda non admite extensións, polo que o cliente web nel traballa con restricións.

Desenvolvemento posterior

Unha das tarefas do equipo de desenvolvemento do cliente web é o desenvolvemento da funcionalidade. A funcionalidade do cliente web debe ser idéntica á funcionalidade do cliente lixeiro; todas as novas funcionalidades impléntanse simultáneamente tanto no cliente lixeiro como no cliente web.

Outras tarefas inclúen desenvolver a arquitectura, refactorizar, mellorar o rendemento e a fiabilidade. Por exemplo, unha das direccións é o avance cara a un modelo de traballo asíncrono. Algunhas das funcionalidades do cliente web están construídas actualmente nun modelo de interacción sincrónica co servidor. O modelo asincrónico é agora cada vez máis relevante nos navegadores (e non só nos navegadores), e isto obríganos a modificar o cliente web substituíndo as chamadas síncronas por outras asíncronas (e refactorizando o código en consecuencia). A transición gradual a un modelo asíncrono explícase pola necesidade de soportar as solucións lanzadas e a súa adaptación gradual.

Fonte: www.habr.com

Engadir un comentario