Про веб-клієнт 1С

Однією з приємних особливостей технології 1С: Підприємство є те, що прикладне рішення, розроблене за технологією керованих форм, може запускатися як у тонкому (виконуваному) клієнті під Windows, Linux, MacOS X, так і як веб-клієнт під 5 браузерів - Chrome, Internet Explorer, Firefox, Safari, Edge, і все це без зміни вихідного коду програми. Більше того – зовні додаток у тонкому клієнті та у браузері функціонує та виглядає практично ідентично.
Знайдіть 10 відмінностей (під катом 2 картинки):

Вікно тонкого клієнта на Linux:

Про веб-клієнт 1С

Те ж саме вікно в веб клієнті (в браузері Chrome):

Про веб-клієнт 1С

Навіщо ми зробили веб-клієнт? Говорячи дещо пафосно, таке завдання нам поставило час. Вже давно робота через Інтернет стала необхідною умовою для бізнес-додатків. Спочатку ми додали можливість роботи через Інтернет для нашого тонкого клієнта (деякі наші конкуренти, до речі, на цьому зупинилися; інші, навпаки, відмовилися від тонкого клієнта і обмежилися реалізацією веб-клієнта). Ми ж вирішили дати нашим користувачам можливість вибрати варіант клієнта, який їм підходить більше.

Про веб-клієнт 1С

Додавання можливості роботи через Інтернет для тонкого клієнта було великим проектом із повною зміною архітектури клієнт-серверної взаємодії. Створення веб-клієнта - і зовсім новий проект, що починався з нуля.

Постановка завдання

Отже, вимоги до проекту: веб-клієнт повинен робити те саме, що і тонкий клієнт, а саме:

  1. Відображати інтерфейс користувача
  2. Виконувати клієнтський код, написаний мовою 1С

Інтерфейс користувача в 1С описується у візуальному редакторі, але декларативно, без попіксельної розстановки елементів; використовується близько трьох десятків типів елементів інтерфейсу – кнопки, поля введення (текстові, цифрові, дата/час), списки, таблиці, графіки тощо.

Клієнтський код на мові 1С може містити серверні виклики, роботу з локальними ресурсами (файлами і т.п.), друк і багато іншого.

І тонкий клієнт (при роботі через інтернет), і веб-клієнт користуються одним і тим же набором веб-сервісів для спілкування з сервером додатків 1С. Реалізація клієнтів, звичайно, різна – тонкий клієнт написаний на С++, веб-клієнт – на JavaScript.

Трохи історії

Проект створення веб-клієнта стартував у 2006 році, в ньому (в середньому) брала участь команда із 5 осіб. На окремих етапах проекту залучалися розробники для реалізації специфічної функціональності (табличного документа, діаграм тощо); як правило, це ті самі розробники, що робили цю функціональність у тонкому клієнті. Тобто. розробники заново писали JavaScript компоненти, раніше створені ними на C++.

З самого початку ми відкинули ідею будь-якої автоматичної (хоча б часткової) конверсії C++ коду тонкого клієнта в JavaScript веб-клієнта через сильні концептуальні відмінності цих двох мов; веб-клієнт писав JavaScript з чистого листа.

У перших ітераціях проекту веб-клієнт конвертував клієнтський код вбудованою мовою 1С безпосередньо в JavaScript. Тонкий клієнт надходить інакше - код вбудованою мовою 1С компілюється в байт-код, а потім цей байт-код інтерпретується на клієнті. Згодом так само став робити і веб-клієнт – по-перше, це дало виграш у продуктивності, по-друге – дозволило уніфікувати архітектуру тонкого та веб-клієнтів.

Перша версія платформи 1С:Підприємство з підтримкою веб-клієнта вийшла у 2009 році. Веб-клієнт на той момент підтримував два браузери - Internet Explorer і Firefox. У початкових планах була підтримка Opera, але через непереборні на той момент проблеми з обробниками закриття програми в Opera (не вдавалося зі 2% впевненістю відстежити, що програма закривається, і в цей момент зробити процедуру відключення від сервера додатків 100С) від цих планів довелося відмовитись.

структура проекту

Всього у платформі 1С:Підприємство є 4 проекти, написані на JavaScript:

  1. WebTools – спільні бібліотеки, які використовуються іншими проектами (сюди ж ми включаємо Бібліотека закриття Google).
  2. Елемент управління Форматований документ (реалізований на JavaScript і в тонкому клієнті, і веб-клієнті)
  3. Елемент управління Планувальник (реалізований на JavaScript і в тонкому клієнті, і веб-клієнті)
  4. Веб-клієнт

Структура кожного проекту нагадує структуру Java-проектів (або .NET проектів – кому що ближче); ми маємо неймспейси, і кожен неймспейс лежить в окремій папці. Усередині папки лежать файли та класи неймспейсу. У проекті веб-клієнта близько 1000 файлів.

Структурно веб-клієнт по-великому поділяється на такі підсистеми:

  • Керований інтерфейс клієнтської програми
    • Загальний інтерфейс програми (системні меню, панелі)
    • Інтерфейс керованих форм, що включає, зокрема, близько 30 елементів управління (кнопки, різні типи полів введення – текстові, цифрові, дата/час тощо., таблиці, списки, графіки тощо.)

  • Об'єктна модель, доступна розробникам на клієнті (загалом понад 400 типів: об'єктна модель керованого інтерфейсу, налаштування компонування даних, умовного оформлення тощо)
  • Інтерпретатор вбудованої мови 1С
  • Розширення браузерів (використовуються для функціональності, що не підтримується JavaScript)
    • Робота з криптографією
    • Робота з файлами
    • Технологія зовнішніх компонент, що дозволяє їх використовувати як тонкому, так і веб-клієнті

особливості розробки

Реалізація всього вищеописаного на JavaScript – справа непроста. Можливо, веб-клієнт 1С – один із найбільших client-side додатків, написаних на JavaScript – близько 450.000 рядків. Ми активно використовуємо в коді веб-клієнта об'єктно-орієнтований підхід, який спрощує роботу з таким великим проектом.

Для мінімізації розміру клієнтського коду ми спочатку використовували власний обфускатор, а починаючи з версії платформи 8.3.6 (жовтень 2014) стали використовувати Компілятор Google Closure. Ефект використання у цифрах – розмір фреймворку веб-клієнта після обфускування:

  • Власний обфускатор – 1556 кб
  • Google Closure Compiler – 1073 кб

Використання Google Closure Compiler допомогло нам підвищити швидкість веб-клієнта на 30% порівняно з нашим власним обфускатором. Крім того, на 15-25% (залежно від браузера) знизився обсяг пам'яті, що споживається програмою.

Google Closure Compiler дуже добре працює з об'єктно-орієнтованим кодом, тому його ефективність для веб-клієнта максимально висока. Closure Compiler робить для нас кілька гарних речей:

  • Статична перевірка типів на етапі складання проекту (забезпечується тим, що ми покриваємо код анотаціями JSDoc). У результаті виходить статична типізація, дуже близька за рівнем до типізації С++. Це допомагає виловити досить великий відсоток помилок на стадії компіляції проекту.
  • Зменшення розміру коду через обфускацію
  • Ряд оптимізації виконуваного коду, наприклад, такі як:
    • inline-підстановки функцій. Виклик функції JavaScript - досить дорога операція, і inline-підстановки невеликих методів, що часто використовуються, істотно прискорюють роботу коду.
    • Підрахунок констант на етапі компіляції. Якщо вираз залежить від константи, у нього буде підставлено фактичне значення константи

Як середовище розробки веб-клієнта ми використовуємо WebStorm.

Для аналізу коду ми використовуємо SonarQube, куди інтегруємо статичні аналізатори коду За допомогою аналізаторів ми відстежуємо деградацію якості вихідного коду JavaScript і намагаємося її не допускати.

Про веб-клієнт 1С

Які завдання вирішували/вирішуємо

У ході реалізації проекту ми зіткнулися з багатьма цікавими завданнями, які нам довелося вирішувати.

Обмін даними з сервером та між вікнами

Існують ситуації, коли обфускування вихідного коду може стати на заваді роботі системи. Код, зовнішній по відношенню до виконуваного коду веб-клієнта, внаслідок обфускації може мати імена функцій і параметрів, які відрізняються від тих, які чекає наш виконуваний код. Зовнішнім кодом для нас є:

  • Код, що надходить із сервера у вигляді структур даних
  • Код іншого вікна програми

Щоб уникнути обфускації при взаємодії з сервером, ми використовуємо тег @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;
}

А щоб уникнути обфускації при взаємодії з іншими вікнами ми використовуємо так звані інтерфейси, що експортуються (інтерфейси, у яких всі методи є експортованими).

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

We used Virtual DOM before it became mainstream)

Як і всі розробники, що мають справу зі складним Веб UI, ми швидко зрозуміли, що DOM погано підходить для роботи з динамічним інтерфейсом користувача. Практично відразу було реалізовано аналог Virtual DOM для оптимізації роботи з UI. У процесі обробки події всі зміни DOM запам'ятовуються в пам'яті і, тільки після завершення всіх операцій, накопичені зміни застосовуються до дерева DOM.

Оптимізація роботи веб-клієнта

Щоб наш веб-клієнт працював швидше, ми максимально намагаємося задіяти штатні можливості браузера (CSS і т.п.). Так, командна панель форми (розташована практично на кожній формі програми) малюється виключно засобами браузера, динамічною версткою на базі CSS.

Про веб-клієнт 1С

Тестування

Для функціонального тестування та тестування продуктивності ми використовуємо інструмент власного виробництва (написаний на Java та C++), а також набір тестів, побудованих на базі Селен.

Наш інструмент універсальний - він дозволяє тестувати практично будь-які віконні програми, тому підходить для тестування як тонкого клієнта, так і веб-клієнта. Інструмент записує дії користувача, який запустив прикладне рішення "1С", у файл-сценарій. У цей час відбувається запис зображень робочої області екрана — стандартів. При контролі нових версій веб-клієнта сценарії програються без участі користувача. У випадках розбіжності скріншота з еталонним на якомусь кроці тест вважається таким, що провалився, після чого фахівець з якості проводить розслідування – помилка це або запланована зміна поведінки системи. У разі запланованої поведінки зразки автоматично підміняються на нові.

Інструмент також проводить вимірювання продуктивності додатків з точністю до 25 мілісекунд. У ряді випадків ми закільцюємо частини сценарію (наприклад, кілька разів повторюємо введення замовлення) для аналізу деградації часу виконання з часом. Результати всіх вимірів записуються в балку для аналізу.

Про веб-клієнт 1С
Наш інструмент тестування та тестований додаток

Наш інструмент та Selenium доповнюють один одного; наприклад, якщо якась кнопка на одному з екранів змінила своє місцезнаходження – Selenium це може не відстежити, але наш інструмент помітить, тому що. робить попіксельне порівняння скріншоту з еталоном. Також інструмент може відстежити проблеми з обробкою введення з клавіатури або миші, оскільки саме їх він і відтворює.

Тести на обох інструментах (нашим та Selenium) запускають типові сценарії роботи з наших прикладних рішень. Тести автоматично запускаються після щоденного складання платформи «1С:Підприємство». У разі уповільнення роботи сценаріїв (порівняно з попереднім складанням) ми проводимо розслідування та усуваємо причину уповільнення. Критерій у нас простий – нова збірка має працювати не повільніше за попередню.

Для розслідування інцидентів уповільнення роботи розробники використовують різні інструменти; в основному використовується Видання Dynatrace AJAX виробництва компанії DynaTrace. Проводиться запис логів виконання проблемної операції на попередній і новій збірці, потім логи аналізуються. При цьому час виконання одиничних операцій (у мілісекундах) може не бути вирішальним фактором – у браузері періодично запускаються службові процеси типу прибирання сміття, вони можуть накластися на час виконання функцій та спотворити картину. Релевантнішими параметрами в цьому випадку буде кількість виконаних інструкцій JavaScript, кількість атомарних операцій над DOM тощо. Якщо кількість інструкцій/операцій в тому самому сценарії в новій версії збільшилася - це майже завжди означає падіння швидкодії, яке потрібно виправляти.

Також однією з причин падіння продуктивності може бути те, що Google Closure Compiler з якоїсь причини не зміг зробити inline-підстановку функції (наприклад, тому що функція рекурсивна або віртуальна). І тут ми намагаємося виправити ситуацію, переписавши вихідний код.

Розширення браузерів

У випадку, коли прикладному рішенню потрібна функціональність, якої немає в JavaScript, ми використовуємо розширення браузерів:

Наші розширення складаються із двох частин. Перша частина – те, що називається розширенням браузера (зазвичай написані на JavaScript розширення для Chrome і Firefox), які взаємодіють з другою частиною — бінарним розширенням, що реалізує потрібну нам функціональність. Треба згадати, що ми пишемо три версії бінарних розширень – під Windows, Linux та MacOS. Бінарне розширення поставляється у складі платформи 3С:Підприємство та знаходиться на сервері додатків 1С. При першому дзвінку з веб-клієнта воно завантажується на клієнтський комп'ютер і встановлюється у браузері.

При роботі в Safari наші розширення використовують NPAPI, під час роботи в Internet Explorer – технологію ActiveX. Microsoft Край поки не підтримує розширення, тому веб-клієнт у ньому працює з обмеженнями.

Подальший розвиток

Одна з груп завдань для розробки веб-клієнта – це подальший розвиток функціональності. Функціональність веб-клієнта має бути ідентична функціональності тонкого клієнта, вся нова функціональність реалізується одночасно і тонкому, і веб-клієнті.

Інші завдання - розвиток архітектури, рефакторинг, підвищення продуктивності та надійності. Наприклад, один із напрямків – подальший рух у бік асинхронної моделі роботи. Частина функціональності веб-клієнта зараз побудована на синхронній моделі взаємодії із сервером. Асинхронна модель зараз стає в браузерах (і не тільки в браузерах) більш актуальною, і це змушує нас модифікувати веб-клієнт шляхом заміни синхронних викликів на асинхронні (і відповідний код рефакторингу). Поступовий перехід до асинхронної моделі пояснюється необхідністю підтримки випущених рішень та поступової їх адаптації.

Джерело: habr.com

Додати коментар або відгук