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

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

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

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

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

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

Постановка завдання
Отже, вимоги до проекту: веб-клієнт повинен робити те ж саме, що і тонкий клієнт, а саме:
  1. Відображати інтерфейс
  2. Виконувати клієнтський код, написаний на мові 1С
Користувальницький інтерфейс в 1С описується у візуальному редакторі, але декларативно, без попиксельной розстановки елементів; використовується близько трьох десятків типів елементів інтерфейсу — кнопки, поля введення (текстові, цифрові, дата/час), списки, таблиці, графіки і т. д.

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

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

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

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

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

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

Структура проекту
Всього в платформі 1С: Підприємство є 4 проекту, написаних на JavaScript:
  1. WebTools – загальні бібліотеки, використовувані іншими проектами (сюди ми включаємо Google Closure Library).
  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 Compiler. Ефект використання в цифрах – розмір фреймворку веб-клієнта після обфускации:
  • Власний обфускатор – 1556 кб
  • Google Closure Compiler – 1073 кб
Використання Google Closure Compiler допомогло нам підвищити швидкодію веб-клієнта на 30% порівняно з нашим власним обфускатором. Крім того, на 15-25% (залежно від браузера) знизився обсяг пам'яті, споживаної додатком.

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

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

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


Які завдання вирішували/вирішуємо
В ході реалізації проекту ми зіткнулися з низкою цікавих завдань, які нам довелося вирішувати.

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

Існують ситуації, коли обфускирование вихідного коду може перешкодити роботі системи. Код, зовнішній по відношенню до виконуваного коду веб-клієнта, внаслідок обфускации може мати імена функцій і параметрів, що відрізняються від тих, які наш виконуваний код чекає. Зовнішнім кодом для нас є:
  • Код, що приходить з сервера у вигляді структур даних
  • Код іншого вікна програми
Щоб уникнути обфускации при взаємодії з сервером ми використовуємо тег @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.
image

Тестування

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

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

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

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

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

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

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

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

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

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

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

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.