Sobre o cliente web 1C

Uma das características agradáveis da tecnologia 1C:Enterprise é que a solução de aplicação desenvolvida com tecnologia de formulários gerenciados pode ser executada tanto no cliente leve (executável) em Windows, Linux, MacOS X, quanto como cliente web em 5 navegadores – Chrome, Internet Explorer, Firefox, Safari, Edge, tudo isso sem alteração do código-fonte do aplicativo. Além disso, visualmente, o aplicativo no cliente leve e no navegador funciona e se parece praticamente idêntico.
Encontre 10 diferenças (abaixo, 2 imagens):

Janela do cliente leve no Linux:

Sobre o cliente web 1C

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

Sobre o cliente web 1C

Por que fizemos o cliente web? Falando um pouco de forma grandiosa, essa tarefa foi imposta pelo tempo. Há muito tempo, o trabalho pela Internet se tornou um pré-requisito para aplicações empresariais. No início, adicionamos a capacidade de trabalhar pela Internet ao nosso cliente leve (alguns de nossos concorrentes, diga-se de passagem, pararam nisso; outros, por outro lado, abandonaram o cliente leve e se limitaram à implementação do cliente web). Nós decidimos dar aos nossos usuários a possibilidade de escolher a opção de cliente que mais se adequa a eles.

Sobre o cliente web 1C

Adicionar a capacidade de trabalhar pela Internet para o cliente leve foi um grande projeto com uma mudança completa na arquitetura de interação cliente-servidor. A criação do cliente web, por outro lado, é um projeto totalmente novo, começando do zero.

Formulação do problema

Então, os requisitos para o projeto: o cliente web deve fazer o mesmo que o cliente leve, ou seja:

  1. Exibir a interface do usuário
  2. Executar código do cliente, escrito na linguagem 1C

A interface do usuário em 1C é descrita em um editor visual, mas de forma declarativa, sem organização pixel a pixel dos elementos; são utilizados cerca de trinta tipos de elementos de interface – botões, campos de entrada (textuais, numéricos, data/hora), listas, tabelas, gráficos etc.

O código do cliente na linguagem 1C pode conter chamadas de servidor, manipulação de recursos locais (arquivos etc.), impressão e muito mais.

Tanto o cliente leve (ao trabalhar pela web) quanto o cliente web utilizam o mesmo conjunto de serviços web para comunicação com o servidor de aplicações 1C. A implementação nos clientes, claro, é diferente – o cliente leve é escrito em C++, o cliente web – em JavaScript.

Um pouco de história

O projeto de criação do cliente web começou em 2006, com uma equipe média de 5 pessoas. Em algumas etapas do projeto, desenvolvedores foram envolvidos para implementar funcionalidades específicas (documentos tabulares, gráficos etc.); como regra, eram os mesmos desenvolvedores que haviam feito essa funcionalidade no cliente fino. Ou seja, os desenvolvedores reescreviam em JavaScript componentes que haviam sido criados anteriormente em C++.

Desde o início, rejeitamos a ideia de qualquer conversão automática (mesmo que parcial) de código C++ do cliente fino para JavaScript do cliente web, devido às fortes diferenças conceituais entre essas duas linguagens; o cliente web foi escrito em JavaScript do zero.

Nas primeiras iterações do projeto, o cliente web convertia o código do cliente na linguagem embutida 1C diretamente em JavaScript. O cliente fino opera de forma diferente — o código na linguagem embutida 1C é compilado em bytecode, que é então interpretado no cliente. Posteriormente, o cliente web também começou a fazer isso – primeiro, isso melhorou o desempenho e, em segundo lugar, permitiu unificar a arquitetura dos clientes fino e web.

A primeira versão da plataforma 1C:Enterprise com suporte ao cliente web foi lançada em 2009. Naquele momento, o cliente web suportava 2 navegadores – Internet Explorer e Firefox. Nos planos iniciais, havia suporte para Opera, mas devido a problemas insuperáveis na época com os manipuladores de fechamento do aplicativo no Opera (não era possível detectar com 100% de certeza que o aplicativo estava sendo fechado, e nesse momento realizar o procedimento de desconexão do servidor de aplicativos 1C), esses planos tiveram que ser abandonados.

Estrutura do projeto

No total, a plataforma 1C:Enterprise possui 4 projetos escritos em JavaScript:

  1. WebTools – bibliotecas gerais utilizadas pelos outros projetos (neste grupo, incluímos Google Closure Library).
  2. Elemento de controle DocumentoFormatado (implementado em JavaScript tanto no cliente fino quanto no cliente web)
  3. Elemento de controle Agendador (implementado em JavaScript tanto no cliente fino quanto no cliente web)
  4. Cliente web

A estrutura de cada projeto se assemelha à estrutura de projetos Java (ou projetos .NET – conforme o que for mais familiar); temos namespaces, e cada namespace reside em uma pasta separada. Dentro da pasta, estão os arquivos e classes do namespace. No projeto do cliente web, há cerca de 1000 arquivos.

Estruturalmente, o cliente web é amplamente dividido nas seguintes subsistemas:

  • Interface gerenciada do aplicativo cliente
    • Interface geral do aplicativo (menus do sistema, painéis)
    • Interface de formulários gerenciados, que inclui cerca de 30 elementos de controle (botões, diferentes tipos de campos de entrada – texto, numérico, data/hora e outros, tabelas, listas, gráficos etc.)

  • Modelo de objeto disponível para desenvolvedores no cliente (mais de 400 tipos: modelo de objeto da interface gerenciada, configurações de layout de dados, formatação condicional, etc.)
  • Interpretador de linguagem embutida 1C
  • Extensões de navegador (usadas para funcionalidades não suportadas no JavaScript)
    • Trabalho com criptografia
    • Trabalhando com arquivos
    • Tecnologia de componentes externos, permitindo seu uso tanto no cliente leve quanto no web-client

Características do desenvolvimento

Implementar tudo o que foi descrito acima em JavaScript é uma tarefa complexa. O web-client 1C pode ser um dos maiores aplicativos client-side escritos em JavaScript – cerca de 450.000 linhas. Utilizamos ativamente na codificação do web-client a abordagem orientada a objetos, que facilita o trabalho com um projeto tão grande.

Para minimizar o tamanho do código do cliente, inicialmente utilizamos nosso próprio ofuscador, e a partir da versão da plataforma 8.3.6 (outubro de 2014) começamos a usar Google Closure Compiler. O efeito do uso em números – tamanho do framework do web-client após ofuscação:

  • Nosso próprio ofuscador – 1556 kB
  • Google Closure Compiler – 1073 kB

O uso do Google Closure Compiler nos ajudou a aumentar a performance do web-client em 30% em comparação com nosso próprio ofuscador. Além disso, houve uma redução de 15-25% (dependendo do navegador) no volume de memória consumido pelo aplicativo.

O Google Closure Compiler trabalha muito bem com código orientado a objetos, portanto sua eficiência para o web-client é máxima. O Closure Compiler faz várias coisas boas para nós:

  • Verificação estática de tipos na fase de construção do projeto (assegurada pelo fato de cobrirmos o código com anotações JSDoc). O resultado é uma tipagem estática muito próxima da tipagem em C++. Isso ajuda a capturar uma porcentagem considerável de erros na fase de compilação do projeto.
  • Redução do tamanho do código através da ofuscação
  • Uma série de otimizações de código executado, como:
    • substituições inline de funções. Chamar uma função em JavaScript é uma operação bastante cara, e as substituições inline de pequenos métodos que são frequentemente usados aceleram significativamente o código.
    • Contagem de constantes na fase de compilação. Se uma expressão depende de uma constante, o valor real da constante será inserido nela.

Como ambiente de desenvolvimento do cliente da web, usamos o WebStorm.

Para a análise de código, usamos SonarQube, onde integramos analisadores de código estáticos. Com a ajuda dos analisadores, monitoramos a degradação da qualidade do código-fonte em JavaScript e nos esforçamos para evitar isso.

Sobre o cliente web 1C

Quais problemas resolvemos

Durante a implementação do projeto, encontramos uma série de tarefas interessantes que tivemos que resolver.

Troca de dados com o servidor e entre janelas

Existem situações em que a ofuscação do código-fonte pode prejudicar o funcionamento do sistema. O código externo em relação ao código executável do cliente da web, devido à ofuscação, pode ter nomes de funções e parâmetros que diferem daqueles que nosso código executável espera. O código externo para nós é:

  • O código vindo do servidor na forma de estruturas de dados
  • O código de outra janela do aplicativo

Para evitar ofuscação ao interagir com o servidor, usamos a 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 para evitar ofuscação ao interagir com outras janelas, usamos os chamados interfaces exportáveis (interfaces cujos todos os métodos são exportáveis).

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

Assim como todos os desenvolvedores que lidam com uma complexa UI da Web, percebemos rapidamente que o DOM não é adequado para trabalhar com interfaces de usuário dinâmicas. Praticamente imediatamente, um análogo do Virtual DOM foi implementado para otimizar o trabalho com a UI. Durante o processamento de eventos, todas as mudanças no DOM são armazenadas na memória e, somente após a conclusão de todas as operações, as mudanças acumuladas são aplicadas à árvore DOM.

Otimização do funcionamento do cliente da web

Para que nosso cliente da web funcione mais rápido, tentamos ao máximo usar os recursos nativos do navegador (CSS, etc.). Assim, a barra de comando do formulário (localizada praticamente em cada formulário do aplicativo) é renderizada exclusivamente com os recursos do navegador, com uma formatação dinâmica baseada em CSS.

Sobre o cliente web 1C

Testes

Para testes funcionais e de desempenho, usamos uma ferramenta desenvolvida internamente (escrita em Java e C++), além de um conjunto de testes baseados em Selenium.

Nossa ferramenta é versátil - ela permite testar praticamente qualquer programa de janela, portanto é adequada para testar tanto clientes leves quanto clientes web. A ferramenta grava as ações do usuário que iniciou a solução aplicada '1C' em um arquivo de script. Ao mesmo tempo, as imagens da área de trabalho da tela são gravadas - padrões. Ao controlar novas versões do cliente web, os scripts são executados sem a participação do usuário. Nos casos de discrepância entre a captura de tela e o padrão em qualquer etapa, o teste é considerado falhado, após o que um especialista em qualidade realiza uma investigação - se é um erro ou uma mudança planejada no comportamento do sistema. Em caso de comportamento planejado, os padrões são automaticamente substituídos por novos.

A ferramenta também mede o desempenho dos aplicativos com precisão de 25 milissegundos. Em alguns casos, fazemos um loop em partes do script (por exemplo, repetindo várias vezes a entrada do pedido) para analisar a degradação do tempo de execução ao longo do tempo. Os resultados de todas as medições são registrados em um log para análise.

Sobre o cliente web 1C
Nossa ferramenta de teste e o aplicativo testado

Nossa ferramenta e o Selenium se complementam; por exemplo, se algum botão em uma das telas mudou de posição - o Selenium pode não rastrear isso, mas nossa ferramenta notará, pois realiza uma comparação pixel a pixel da captura de tela com o padrão. Além disso, a ferramenta é capaz de detectar problemas com o manuseio de entradas do teclado ou mouse, já que é isso que ela reproduz.

Os testes em ambas as ferramentas (a nossa e o Selenium) executam cenários típicos de trabalho de nossas soluções aplicadas. Os testes são executados automaticamente após a compilação diária da plataforma '1C:Enterprise'. Em caso de lentidão nos scripts (em comparação com a compilação anterior), realizamos uma investigação e removemos a causa da lentidão. Nosso critério é simples - a nova compilação deve funcionar não mais devagar que a anterior.

Para investigar incidentes de lentidão, os desenvolvedores usam diferentes ferramentas; predominantemente é utilizado Edição AJAX do Dynatrace da empresa DynaTrace. É feito o registro dos logs da execução da operação problemática nas versões anterior e nova, e então os logs são analisados. O tempo de execução de operações individuais (em milissegundos) pode não ser um fator decisivo – no navegador, processos de serviço como a limpeza de memória são periodicamente iniciados e podem interferir no tempo de execução das funções, distorcendo a imagem. Parâmetros mais relevantes nesse caso serão a quantidade de instruções JavaScript executadas, o número de operações atômicas no DOM, etc. Se a quantidade de instruções/operações no mesmo cenário na nova versão aumentou – isso quase sempre significa uma queda no desempenho, que precisa ser corrigida.

Além disso, uma das razões para a queda no desempenho pode ser que o Google Closure Compiler não conseguiu, por algum motivo, realizar a substituição inline da função (por exemplo, porque a função é recursiva ou virtual). Nesse caso, tentamos corrigir a situação reescrevendo o código-fonte.

Extensões de navegador

Quando a solução de aplicativo necessita de funcionalidades que não estão disponíveis em JavaScript, usamos extensões de navegador:

Nossas extensões consistem em duas partes. A primeira parte é o que chamamos de extensão do navegador (geralmente, extensões escritas em JavaScript para Chrome e Firefox), que interage com a segunda parte – uma extensão binária, que implementa a funcionalidade necessária. Vale mencionar que escrevemos 3 versões de extensões binárias – para Windows, Linux e MacOS. A extensão binária é fornecida como parte da plataforma 1C:Enterprise e está localizada no servidor de aplicativos 1C. Na primeira chamada do cliente web, ela é carregada no computador do cliente e instalada no navegador.

Ao trabalhar no Safari, nossas extensões utilizam NPAPI; ao trabalhar no Internet Explorer, utilizam a tecnologia ActiveX. Microsoft Edge ainda não suporta extensões, portanto, o cliente web nele funciona com limitações.

Desenvolvimento futuro

Um dos grupos de tarefas para a equipe de desenvolvimento do cliente web é a continuidade do desenvolvimento das funcionalidades. As funcionalidades do cliente web devem ser idênticas às do cliente leve, e toda nova funcionalidade é implementada simultaneamente tanto no cliente leve quanto no cliente web.

Outras tarefas incluem o desenvolvimento da arquitetura, refatoração, aumento de desempenho e confiabilidade. Por exemplo, uma das direções é seguir em direção a um modelo de trabalho assíncrono. Atualmente, parte das funcionalidades do cliente web é construída com um modelo de interação síncrona com o servidor. O modelo assíncrono está se tornando mais relevante nos navegadores (e não apenas nos navegadores), o que nos leva a modificar o cliente web substituindo chamadas síncronas por assíncronas (e fazendo as correspondentes refatorações no código). A transição gradual para o modelo assíncrono é explicada pela necessidade de suporte às soluções lançadas e a sua adaptação gradual.

Fonte: habr.com

Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS 🔥 Compre hospedagem confiável para sites com proteção contra DDoS, servidores VPS VDS | ProHoster