{"id":32465,"date":"2019-10-31T21:47:12","date_gmt":"2019-10-31T18:47:12","guid":{"rendered":"https:\/\/prohoster.info\/blog\/pro-veb-klient-1s\/"},"modified":"2026-05-20T19:17:21","modified_gmt":"2026-05-20T17:17:21","slug":"pro-veb-klient-1s__trashed","status":"publish","type":"post","link":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/pro-veb-klient-1s__trashed","title":{"rendered":"O kliencie internetowym 1C","gt_translate_keys":[{"key":"rendered","format":"text"}]},"content":{"rendered":"<p>Jedn\u0105 z przyjemnych cech technologii 1C:Enterprise jest to, \u017ce aplikacja stworzona przy u\u017cyciu technologii form zarz\u0105dzanych mo\u017ce dzia\u0142a\u0107 zar\u00f3wno w cienkim (wykonawczym) kliencie na Windows, Linux, MacOS X, jak i jako klient internetowy w 5 przegl\u0105darkach \u2013 Chrome, Internet Explorer, Firefox, Safari, Edge, i to wszystko \u2013 bez zmiany oryginalnego kodu aplikacji. Co wi\u0119cej \u2013 zewn\u0119trznie aplikacja w cienkim kliencie i w przegl\u0105darce dzia\u0142a i wygl\u0105da praktycznie identycznie.<br \/>\nZnajd\u017a 10 r\u00f3\u017cnic (pod katem 2 obrazki):<br \/>\n<noindex><a rel=\"nofollow\" name=\"habracut\"><\/a><\/noindex><br \/>\nOkno cienkiego klienta na Linuxie:<\/p>\n<p><img decoding=\"async\" alt=\"O kliencie internetowym 1C\" src=\"\/wp-content\/uploads\/2019\/04\/6a836d01f80f447302e04d1827d5eebb.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nTo samo okno w kliencie internetowym (w przegl\u0105darce Chrome):<\/p>\n<p><img decoding=\"async\" alt=\"O kliencie internetowym 1C\" src=\"\/wp-content\/uploads\/2019\/04\/1cab8bdf0d9d1c9d6601219c3ae6018c.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDlaczego stworzyli\u015bmy klienta internetowego? M\u00f3wi\u0105c nieco patetycznie, takie zadanie postawi\u0142 przed nami czas. Od dawna praca przez Internet sta\u0142a si\u0119 niezb\u0119dnym warunkiem dla aplikacji biznesowych. Na pocz\u0105tku dodali\u015bmy mo\u017cliwo\u015b\u0107 pracy przez Internet dla naszego cienkiego klienta (niekt\u00f3rzy nasi konkurenci, nawiasem m\u00f3wi\u0105c, na tym si\u0119 zatrzymali; inni, wr\u0119cz przeciwnie, zrezygnowali z cienkiego klienta i ograniczyli si\u0119 do realizacji klienta internetowego). My postanowili\u015bmy da\u0107 naszym u\u017cytkownikom mo\u017cliwo\u015b\u0107 wyboru tego wariantu klienta, kt\u00f3ry bardziej im odpowiada.<\/p>\n<p><img decoding=\"async\" alt=\"O kliencie internetowym 1C\" src=\"\/wp-content\/uploads\/2019\/04\/345d070d695cfc4854c485148d22d24c.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<br \/>\nDodanie mo\u017cliwo\u015bci pracy przez Internet dla cienkiego klienta by\u0142o du\u017cym projektem, kt\u00f3ry wymaga\u0142 pe\u0142nej zmiany architektury interakcji klient-serwer. Tworzenie klienta internetowego to zupe\u0142nie nowy projekt, kt\u00f3ry zacz\u0105\u0142 si\u0119 od zera.<\/p>\n<h3>Sformu\u0142owanie zadania<\/h3>\n<p>\nZatem wymagania do projektu: klient internetowy powinien robi\u0107 to samo, co cienki klient, a mianowicie:<\/p>\n<ol>\n<li>Wy\u015bwietla\u0107 interfejs u\u017cytkownika<\/li>\n<li>Wykonywa\u0107 kod kliencki, napisany w j\u0119zyku 1C<\/li>\n<\/ol>\n<p>\nInterfejs u\u017cytkownika w 1C jest opisany w wizualnym edytorze, ale deklaratywnie, bez pikselowego rozmieszczania element\u00f3w; u\u017cywa si\u0119 oko\u0142o trzydziestu typ\u00f3w element\u00f3w interfejsu \u2013 przycisk\u00f3w, p\u00f3l wprowadzania (tekstowych, liczbowych, daty\/czasu), list, tabel, wykres\u00f3w itd. <\/p>\n<p>Kod kliencki w j\u0119zyku 1C mo\u017ce zawiera\u0107 wywo\u0142ania serwerowe, prac\u0119 z lokalnymi zasobami (plikami itp.), drukowanie i wiele wi\u0119cej.<\/p>\n<p>Zar\u00f3wno cienki klient (podczas pracy przez sie\u0107), jak i klient internetowy korzystaj\u0105 z tego samego zestawu us\u0142ug internetowych do komunikacji z serwerem aplikacji 1C. Implementacja u klient\u00f3w jest oczywi\u015bcie r\u00f3\u017cna \u2013 cienki klient napisany jest w C++, klient internetowy \u2013 w JavaScript.<\/p>\n<h3>Historia<\/h3>\n<p>\nProjekt stworzenia klienta internetowego rozpocz\u0105\u0142 si\u0119 w 2006 roku, w kt\u00f3rym (\u015brednio) uczestniczy\u0142a ekipa pi\u0119ciu os\u00f3b. Na poszczeg\u00f3lnych etapach projektu anga\u017cowano programist\u00f3w do realizacji specyficznych funkcji (dokument\u00f3w tabelarycznych, diagram\u00f3w itp.); zazwyczaj byli to ci sami programi\u015bci, kt\u00f3rzy tworzyli t\u0119 funkcjonalno\u015b\u0107 w kliencie stacjonarnym. To znaczy, \u017ce programi\u015bci pisali na nowo w JavaScript komponenty, kt\u00f3re wcze\u015bniej stworzyli w C++.<\/p>\n<p>Od samego pocz\u0105tku odrzucili\u015bmy pomys\u0142 jakiejkolwiek automatycznej (cho\u0107by cz\u0119\u015bciowej) konwersji kodu C++ z klienta stacjonarnego na JavaScript klienta internetowego z powodu du\u017cych r\u00f3\u017cnic koncepcyjnych mi\u0119dzy tymi dwoma j\u0119zykami; klient internetowy by\u0142 pisany w JavaScript od podstaw.<\/p>\n<p>W pierwszych iteracjach projektu klient internetowy konwertowa\u0142 kod klienta napisany w wbudowanym j\u0119zyku 1C bezpo\u015brednio na JavaScript. Klient stacjonarny dzia\u0142a inaczej \u2014 kod wbudowany w j\u0119zyku 1C kompilowany jest do kodu bajtowego, kt\u00f3ry nast\u0119pnie jest interpretowany po stronie klienta. P\u00f3\u017aniej r\u00f3wnie\u017c klient internetowy zacz\u0105\u0142 dzia\u0142a\u0107 w ten spos\u00f3b \u2013 po pierwsze, zapewni\u0142o to wzrost wydajno\u015bci, po drugie \u2013 umo\u017cliwi\u0142o ujednolicenie architektury klienta stacjonarnego i internetowego.<\/p>\n<p>Pierwsza wersja platformy 1C:Przedsi\u0119biorstwo z obs\u0142ug\u0105 klienta internetowego zosta\u0142a wydana w 2009 roku. Klient internetowy w tamtym czasie obs\u0142ugiwa\u0142 2 przegl\u0105darki \u2013 Internet Explorer i Firefox. W pierwotnych planach by\u0142a r\u00f3wnie\u017c obs\u0142uga Opery, ale z powodu nie do pokonania w\u00f3wczas problem\u00f3w z obs\u0142ug\u0105 zamykania aplikacji w Operze (nie uda\u0142o si\u0119 z 100% pewno\u015bci\u0105 \u015bledzi\u0107, kiedy aplikacja si\u0119 zamyka i w tym momencie przeprowadza\u0107 procedur\u0119 roz\u0142\u0105czenia z serwerem aplikacji 1C) musieli\u015bmy z tych plan\u00f3w zrezygnowa\u0107.<\/p>\n<h3>Struktura projektu<\/h3>\n<p>\nW platformie 1C:Przedsi\u0119biorstwo istniej\u0105 4 projekty, napisane w JavaScript:<\/p>\n<ol>\n<li>WebTools \u2013 og\u00f3lne biblioteki u\u017cywane w pozosta\u0142ych projektach (tutaj uwzgl\u0119dniamy <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Google_Closure_Tools#Closure_Library\">Google Closure Library<\/a><\/noindex>).<\/li>\n<li>Element steruj\u0105cy <noindex><a rel=\"nofollow\" href=\"http:\/\/v8.1c.ru\/overview\/Term_000000785.htm\">FormatowanyDokument<\/a><\/noindex> (zrealizowany w JavaScript zar\u00f3wno w kliencie stacjonarnym, jak i w kliencie internetowym)<\/li>\n<li>Element steruj\u0105cy <noindex><a rel=\"nofollow\" href=\"https:\/\/wonderland.v8.1c.ru\/blog\/planirovshchik\/\">Harmonogram<\/a><\/noindex> (zrealizowany w JavaScript zar\u00f3wno w kliencie stacjonarnym, jak i w kliencie internetowym)<\/li>\n<li>Klient internetowy<\/li>\n<\/ol>\n<p>\nStruktura ka\u017cdego projektu przypomina struktur\u0119 projekt\u00f3w Java (lub projekt\u00f3w .NET \u2013 w zale\u017cno\u015bci od bli\u017cszych preferencji); mamy przestrzenie nazw, a ka\u017cda przestrze\u0144 nazw znajduje si\u0119 w oddzielnym folderze. Wewn\u0105trz folderu znajduj\u0105 si\u0119 pliki i klasy przestrzeni nazw. W projekcie klienta internetowego jest oko\u0142o 1000 plik\u00f3w.<\/p>\n<p>Strukturalnie klient internetowy dzieli si\u0119 na nast\u0119puj\u0105ce podsystemy:<\/p>\n<ul>\n<li>Zarz\u0105dzany interfejs aplikacji klienckiej\n<ul>\n<li>Og\u00f3lny interfejs aplikacji (menu systemowe, panele)<\/li>\n<li>Interfejs formularzy, obejmuj\u0105cy oko\u0142o 30 element\u00f3w steruj\u0105cych (przyciski, r\u00f3\u017cne typy p\u00f3l wej\u015bciowych \u2013 tekstowe, numeryczne, data\/czas itp., tabele, listy, wykresy itp.)<\/li>\n<\/ul>\n<p>\n<\/li>\n<li>Model obiektowy dost\u0119pny dla programist\u00f3w na kliencie (\u0142\u0105cznie ponad 400 typ\u00f3w: model obiektowy interfejsu zarz\u0105dzanego, ustawienia uk\u0142ad\u00f3w danych, formatowanie warunkowe itp.)<\/li>\n<li>Interpreter wbudowanego j\u0119zyka 1C<\/li>\n<li>Rozszerzenia przegl\u0105darek (s\u0142u\u017c\u0105 do funkcjonalno\u015bci, kt\u00f3ra nie jest wspierana w JavaScript)\n<ul>\n<li>Praca z kryptografi\u0105<\/li>\n<li>Praca z plikami<\/li>\n<li>Technologia zewn\u0119trznych komponent\u00f3w, umo\u017cliwiaj\u0105ca ich u\u017cycie zar\u00f3wno w cienkim, jak i webowym kliencie<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p><\/p>\n<h3>Cechy rozwoju<\/h3>\n<p>\nImplementacja wszystkiego powy\u017cej opisanego w JavaScript \u2013 nie jest to proste zadanie. By\u0107 mo\u017ce webowy klient 1C to jedna z najwi\u0119kszych aplikacji po stronie klienta napisanych w JavaScript \u2013 oko\u0142o 450.000 linii. Aktywnie stosujemy w kodzie webowego klienta podej\u015bcie obiektowe, co u\u0142atwia prac\u0119 z tak du\u017cym projektem.<\/p>\n<p>Aby zminimalizowa\u0107 rozmiar kodu klienta, pocz\u0105tkowo u\u017cywali\u015bmy naszego w\u0142asnego obfuscatora, a zaczynaj\u0105c od wersji platformy 8.3.6 (pa\u017adziernik 2014) zacz\u0119li\u015bmy stosowa\u0107 <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Google_Closure_Tools#Closure_Compiler\">Google Closure Compiler<\/a><\/noindex>. Efekt u\u017cycia w liczbach \u2013 rozmiar frameworka webowego klienta po obfuskacji:<\/p>\n<ul>\n<li>W\u0142asny obfuscator \u2013 1556 kB<\/li>\n<li>Google Closure Compiler \u2013 1073 kB<\/li>\n<\/ul>\n<p>\nU\u017cycie Google Closure Compiler pomog\u0142o nam zwi\u0119kszy\u0107 wydajno\u015b\u0107 webowego klienta o 30% w por\u00f3wnaniu do naszego w\u0142asnego obfuscatora. Ponadto, ilo\u015b\u0107 pami\u0119ci konsumowanej przez aplikacj\u0119 zmniejszy\u0142a si\u0119 o 15-25% (w zale\u017cno\u015bci od przegl\u0105darki).<\/p>\n<p>Google Closure Compiler bardzo dobrze dzia\u0142a z kodem obiektowym, dlatego jego skuteczno\u015b\u0107 dla webowego klienta jest maksymalnie wysoka. Closure Compiler robi dla nas kilka dobrych rzeczy:<\/p>\n<ul>\n<li>Statyczne sprawdzenie typ\u00f3w na etapie budowy projektu (zapewnia to pokrycie kodu adnotacjami JSDoc). W efekcie otrzymujemy typizacj\u0119 statyczn\u0105, bardzo blisk\u0105 poziomowi typizacji w C++. Pomaga to wychwyci\u0107 do\u015b\u0107 du\u017c\u0105 ilo\u015b\u0107 b\u0142\u0119d\u00f3w na etapie kompilacji projektu.<\/li>\n<li>Zmniejszenie rozmiaru kodu poprzez obfuskacj\u0119<\/li>\n<li>Szereg optymalizacji wykonywanego kodu, takich jak:\n<ul>\n<li>podstawowe podstawienie funkcji. Wywo\u0142anie funkcji w JavaScript to do\u015b\u0107 kosztowna operacja, a podstawienia inline cz\u0119sto u\u017cywanych ma\u0142ych metod znacznie przyspieszaj\u0105 dzia\u0142anie kodu.<\/li>\n<li>Liczenie sta\u0142ych na etapie kompilacji. Je\u015bli wyra\u017cenie zale\u017cy od sta\u0142ej, wstawiane jest faktyczne jej warto\u015bci.<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>\nJako \u015brodowisko do tworzenia aplikacji klienckich u\u017cywamy WebStorm.<\/p>\n<p>Do analizy kodu u\u017cywamy <noindex><a rel=\"nofollow\" href=\"http:\/\/www.sonarqube.org\/\">SonarQube<\/a><\/noindex>, gdzie integrujemy statyczne analizatory kodu. Dzi\u0119ki analizatorom \u015bledzimy degradacj\u0119 jako\u015bci kodu \u017ar\u00f3d\u0142owego w JavaScript i staramy si\u0119 jej unika\u0107.<\/p>\n<p><img decoding=\"async\" alt=\"O kliencie internetowym 1C\" src=\"\/wp-content\/uploads\/2019\/04\/886fe89a8c12d29d940b6b59316ea627.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h3>Jakie problemy rozwi\u0105zywali\u015bmy\/rozwi\u0105zujemy<\/h3>\n<p>\nW trakcie realizacji projektu napotkali\u015bmy szereg interesuj\u0105cych zada\u0144, kt\u00f3re musieli\u015bmy rozwi\u0105za\u0107.<\/p>\n<h4>Wymiana danych z serwerem i pomi\u0119dzy oknami<\/h4>\n<p>\nIstniej\u0105 sytuacje, w kt\u00f3rych obfuskacja kodu \u017ar\u00f3d\u0142owego mo\u017ce przeszkodzi\u0107 w dzia\u0142aniu systemu. Kod zewn\u0119trzny w stosunku do wykonywanego kodu aplikacji klienckiej, z powodu obfuskacji, mo\u017ce mie\u0107 nazwy funkcji i parametr\u00f3w r\u00f3\u017cni\u0105ce si\u0119 od tych, kt\u00f3rych oczekuje nasz wykonywany kod. Kod zewn\u0119trzny dla nas to:<\/p>\n<ul>\n<li>Kod przychodz\u0105cy z serwera w postaci struktur danych<\/li>\n<li>Kod innego okna aplikacji<\/li>\n<\/ul>\n<p>\nAby unikn\u0105\u0107 obfuskacji podczas interakcji z serwerem, u\u017cywamy tagu @expose:<\/p>\n<pre><code class=\"javascript\">\/**\n * @constructor\n * @extends {Base.SrvObject}\n *\/\nSrv.Core.GenericException = function ()\n{\n    \/**\n     * @type {string}\n     * @expose\n     *\/\n    this.descr;\n\n    \/**\n     * @type {Srv.Core.GenericException}\n     * @expose\n     *\/\n    this.inner;\n\n    \/**\n     * @type {string}\n     * @expose\n     *\/\n    this.clsid;\n\n    \/**\n     * @type {boolean}\n     * @expose\n     *\/\n    this.encoded;\n}<\/code><\/pre>\n<p>\nAby unikn\u0105\u0107 obfuskacji podczas interakcji z innymi oknami, u\u017cywamy tak zwanych interfejs\u00f3w eksportowanych (interfejs\u00f3w, w kt\u00f3rych wszystkie metody s\u0105 eksportowane).<\/p>\n<pre><code class=\"javascript\">\/**\n * \u042d\u043a\u0441\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c\u044b\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u043a\u043e\u043d\u0442\u0440\u043e\u043b\u0430 DropDownWindow\n *\n * @interface\n * @struct\n *\/\nWebUI.IDropDownWindowExp = function(){}\n\n\/**\n * \u041f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u0442 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043d\u0430 1 \u0432\u043f\u0435\u0440\u0435\u0434 \u0438\u043b\u0438 \u043d\u0430\u0437\u0430\u0434\n *\n * @param {boolean} isForward\n * @param {boolean} checkOnly\n * @return {boolean}\n * @expose\n *\/\nWebUI.IDropDownWindowExp.prototype.moveMarker = function (isForward, checkOnly){}\n\n\/**\n * \u041f\u0435\u0440\u0435\u043c\u0435\u0449\u0430\u0435\u0442 \u0432\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0432 \u043d\u0430\u0447\u0430\u043b\u043e \u0438\u043b\u0438 \u043a\u043e\u043d\u0435\u0446\n *\n * @param {boolean} isFirst\n * @param {boolean} checkOnly\n * @return {boolean}\n * @expose\n *\/\nWebUI.IDropDownWindowExp.prototype.moveMarkerTo = function (isFirst, checkOnly){}\n\n\/**\n * @return {boolean}\n * @expose\n *\/\nWebUI.IDropDownWindowExp.prototype.selectValue = function (){}<\/code><\/pre>\n<h4>U\u017cywali\u015bmy Virtual DOM zanim sta\u0142 si\u0119 popularny)<\/h4>\n<p>\nJak wszyscy deweloperzy zajmuj\u0105cy si\u0119 z\u0142o\u017conym interfejsem UI w sieci, szybko zrozumieli\u015bmy, \u017ce DOM \u017ale nadaje si\u0119 do pracy z dynamicznym interfejsem u\u017cytkownika. Praktycznie od razu stworzono analog Virtual DOM w celu optymalizacji pracy z UI. W procesie obs\u0142ugi zdarzenia wszystkie zmiany DOM s\u0105 zapami\u0119tywane w pami\u0119ci i dopiero po zako\u0144czeniu wszystkich operacji, gromadzone zmiany s\u0105 stosowane do drzewa DOM.<\/p>\n<h4>Optymalizacja dzia\u0142ania aplikacji klienckiej<\/h4>\n<p>\nAby nasza aplikacja kliencka dzia\u0142a\u0142a szybciej, maksymalnie staramy si\u0119 wykorzysta\u0107 domy\u015blne mo\u017cliwo\u015bci przegl\u0105darki (CSS itp.). Tak wi\u0119c, pasek narz\u0119dzi formularza (umiejscowiony praktycznie w ka\u017cdym formularzu aplikacji) jest rysowany wy\u0142\u0105cznie za pomoc\u0105 narz\u0119dzi przegl\u0105darki, dynamicznym uk\u0142adem opartym na CSS.<\/p>\n<p><img decoding=\"async\" alt=\"O kliencie internetowym 1C\" src=\"\/wp-content\/uploads\/2019\/04\/116261ca79218eaa2bee9a4f5104092b.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<\/p>\n<h4>Testowanie<\/h4>\n<p>\nDo test\u00f3w funkcjonalnych i wydajno\u015bciowych u\u017cywamy narz\u0119dzia stworzonego we w\u0142asnym zakresie (napisanego w Javie i C++), a tak\u017ce zestawu test\u00f3w opartych na <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/Selenium\">Selenium<\/a><\/noindex>.<\/p>\n<p>Nasze narz\u0119dzie jest uniwersalne \u2013 pozwala testowa\u0107 praktycznie wszystkie programy okienkowe, dlatego nadaje si\u0119 do testowania zar\u00f3wno klienta cienkiego, jak i klienta webowego. Narz\u0119dzie rejestruje dzia\u0142ania u\u017cytkownika, kt\u00f3ry uruchomi\u0142 aplikacj\u0119 \"1C\", w pliku skryptowym. W tym samym czasie rejestrowane s\u0105 obrazy obszaru roboczego ekranu \u2013 wzorc\u00f3w. Podczas kontroli nowych wersji klienta webowego skrypty s\u0105 odtwarzane bez udzia\u0142u u\u017cytkownika. W przypadku niezgodno\u015bci zrzutu ekranu z wzorcem na kt\u00f3rymkolwiek kroku, test uznawany jest za nieudany, po czym specjalista ds. jako\u015bci prowadzi dochodzenie \u2013 czy to b\u0142\u0105d, czy zaplanowana zmiana zachowania systemu. W przypadku zaplanowanego zachowania wzorce automatycznie zast\u0119powane s\u0105 nowymi.<\/p>\n<p>Narz\u0119dzie dokonuje r\u00f3wnie\u017c pomiar\u00f3w wydajno\u015bci aplikacji z dok\u0142adno\u015bci\u0105 do 25 milisekund. W niekt\u00f3rych przypadkach p\u0119tlamy cz\u0119\u015bci skryptu (na przyk\u0142ad kilkakrotnie powtarzamy wprowadzenie zam\u00f3wienia) w celu analizy degradacji czasu wykonania w czasie. Wyniki wszystkich pomiar\u00f3w s\u0105 zapisywane w logu do analizy.<\/p>\n<p><img decoding=\"async\" alt=\"O kliencie internetowym 1C\" src=\"\/wp-content\/uploads\/2019\/04\/058bab976becf6fd38b2ec668492043b.jpeg\" style=\"display:block;margin: 0 auto;\" \/><br \/>\n<b>Nasze narz\u0119dzie testowe i testowana aplikacja<\/b><\/p>\n<p>Nasze narz\u0119dzie i Selenium uzupe\u0142niaj\u0105 si\u0119 nawzajem; na przyk\u0142ad, je\u015bli jaki\u015b przycisk na jednym z ekran\u00f3w zmieni\u0142 swoje po\u0142o\u017cenie \u2013 Selenium mo\u017ce tego nie zauwa\u017cy\u0107, ale nasze narz\u0119dzie to dostrze\u017ce, poniewa\u017c wykonuje por\u00f3wnanie piksel po pikselu z wzorcem. Narz\u0119dzie jest r\u00f3wnie\u017c w stanie wykry\u0107 problemy z przetwarzaniem wej\u015bcia z klawiatury lub myszy, poniewa\u017c to w\u0142a\u015bnie je reprodukuje.<\/p>\n<p>Testy na obu narz\u0119dziach (naszym i Selenium) uruchamiaj\u0105 typowe scenariusze pracy z naszych aplikacji. Testy s\u0105 automatycznie uruchamiane po codziennej kompilacji platformy \"1C:Enterprise\". W przypadku spowolnienia dzia\u0142ania skrypt\u00f3w (w por\u00f3wnaniu do poprzedniej wersji) przeprowadzamy dochodzenie i usuwamy przyczyn\u0119 spowolnienia. Kryterium jest proste \u2013 nowa wersja musi dzia\u0142a\u0107 nie wolniej od poprzedniej.<\/p>\n<p>Do dochodzenia w sprawie incydent\u00f3w spowolnienia dzia\u0142ania programi\u015bci u\u017cywaj\u0105 r\u00f3\u017cnych narz\u0119dzi; w wi\u0119kszo\u015bci przypadk\u00f3w korzysta si\u0119 z <noindex><a rel=\"nofollow\" href=\"http:\/\/apmblog.dynatrace.com\/2014\/12\/11\/dynatrace-ajax-edition-4-5-last-page-chapter-yet-story-continues\/\">Dynatrace AJAX Edition<\/a><\/noindex> produkcji firmy <noindex><a rel=\"nofollow\" href=\"https:\/\/en.wikipedia.org\/wiki\/Dynatrace\">DynaTrace<\/a><\/noindex>. Rejestrowane s\u0105 logi wykonywania problematycznej operacji w poprzedniej i nowej wersji, a nast\u0119pnie logi s\u0105 analizowane. Czas wykonania pojedynczych operacji (w milisekundach) mo\u017ce nie by\u0107 decyduj\u0105cym czynnikiem \u2013 w przegl\u0105darkach regularnie uruchamiane s\u0105 procesy serwisowe, takie jak sprz\u0105tanie pami\u0119ci, kt\u00f3re mog\u0105 wp\u0142yn\u0105\u0107 na czas wykonania funkcji i zniekszta\u0142ci\u0107 obraz. W takim przypadku bardziej istotnymi parametrami b\u0119d\u0105 liczba wykonanych instrukcji JavaScript, liczba atomowych operacji na DOM itp. Je\u015bli liczba instrukcji\/operacji w tym samym scenariuszu w nowej wersji wzros\u0142a \u2013 prawie zawsze oznacza to spadek wydajno\u015bci, kt\u00f3ry nale\u017cy poprawi\u0107.<\/p>\n<p>Jedn\u0105 z przyczyn spadku wydajno\u015bci mo\u017ce by\u0107 r\u00f3wnie\u017c to, \u017ce Google Closure Compiler z jakiego\u015b powodu nie m\u00f3g\u0142 przeczyta\u0107 funkcji jako inline (na przyk\u0142ad dlatego, \u017ce funkcja jest rekurencyjna lub wirtualna). W takim przypadku staramy si\u0119 poprawi\u0107 sytuacj\u0119, przepisuj\u0105c kod \u017ar\u00f3d\u0142owy.<\/p>\n<h3>Rozszerzenia przegl\u0105darek<\/h3>\n<p>\nW przypadku, gdy aplikacja potrzebuje funkcjonalno\u015bci, kt\u00f3rej nie ma w JavaScript, u\u017cywamy rozszerze\u0144 przegl\u0105darek:<\/p>\n<ul>\n<li>do pracy z plikami<\/li>\n<li>do pracy z kryptografi\u0105<\/li>\n<li>praca z <noindex><a rel=\"nofollow\" href=\"http:\/\/v8.1c.ru\/overview\/Term_000000545.htm\">zewn\u0119trznymi komponentami<\/a><\/noindex><\/li>\n<\/ul>\n<p>\nNasze rozszerzenia sk\u0142adaj\u0105 si\u0119 z dw\u00f3ch cz\u0119\u015bci. Pierwsza cz\u0119\u015b\u0107 to tak zwane rozszerzenie przegl\u0105darki (zwykle rozszerzenia napisane w JavaScript dla Chrome i Firefox), kt\u00f3re wsp\u00f3\u0142dzia\u0142a z drug\u0105 cz\u0119\u015bci\u0105 \u2014 binarnym rozszerzeniem, realizuj\u0105cym potrzebn\u0105 nam funkcjonalno\u015b\u0107. Nale\u017cy wspomnie\u0107, \u017ce piszemy 3 wersje binarnych rozszerze\u0144 \u2013 na Windows, Linux i MacOS. Binarne rozszerzenie dostarczane jest w ramach platformy 1C:Enterprise i znajduje si\u0119 na serwerze aplikacji 1C. Przy pierwszym wywo\u0142aniu z klienta webowego jest \u0142adowane na komputer kliencki i instalowane w przegl\u0105darce.<\/p>\n<p>Podczas pracy w Safari nasze rozszerzenia korzystaj\u0105 z NPAPI, natomiast w Internet Explorerze \u2013 z technologii ActiveX. <noindex><a rel=\"nofollow\" href=\"https:\/\/ru.wikipedia.org\/wiki\/Microsoft_Edge\">Microsoft Edge<\/a><\/noindex> jak na razie nie obs\u0142uguje rozszerze\u0144, wi\u0119c klient webowy w nim dzia\u0142a z ograniczeniami.<\/p>\n<h3>Dalszy rozw\u00f3j<\/h3>\n<p>\nJednym z zada\u0144 dla zespo\u0142u odpowiedzialnego za rozw\u00f3j aplikacji webowej jest dalszy rozw\u00f3j funkcjonalno\u015bci. Funkcjonalno\u015b\u0107 aplikacji webowej powinna by\u0107 identyczna z funkcjonalno\u015bci\u0105 klienta lekkiego, a wszystkie nowe funkcjonalno\u015bci s\u0105 wprowadzane jednocze\u015bnie zar\u00f3wno w kliencie lekkim, jak i w webowym.<\/p>\n<p>Inne zadania to rozw\u00f3j architektury, refaktoryzacja, zwi\u0119kszenie wydajno\u015bci i niezawodno\u015bci. Na przyk\u0142ad, jednym z kierunk\u00f3w jest dalsze przej\u015bcie w stron\u0119 modelu pracy asynchronicznej. Cz\u0119\u015b\u0107 funkcjonalno\u015bci aplikacji webowej jest obecnie zbudowana na synchronizowanym modelu interakcji z serwerem. Model asynchroniczny staje si\u0119 teraz coraz bardziej aktualny w przegl\u0105darkach (i nie tylko w przegl\u0105darkach), co sk\u0142ania nas do modyfikacji aplikacji webowej poprzez zast\u0105pienie synchronicznych wywo\u0142a\u0144 wywo\u0142aniami asynchronicznymi (wraz z odpowiedni\u0105 refaktoryzacj\u0105 kodu). Stopniowe przej\u015bcie do modelu asynchronicznego jest podyktowane konieczno\u015bci\u0105 wsparcia wydanych rozwi\u0105za\u0144 oraz ich stopniow\u0105 adaptacj\u0105.<br \/>\n<br \/>\u0179r\u00f3d\u0142o: <a content=\"nofollow\" rel=\"nofollow\" href=\"https:\/\/habr.com\/ru\/company\/1c\/blog\/315414\/\">habr.com<\/a><\/p>","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"excerpt":{"rendered":"<p>\u041e\u0434\u043d\u043e\u0439 \u0438\u0437 \u043f\u0440\u0438\u044f\u0442\u043d\u044b\u0445 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0435\u0439 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 1\u0421:\u041f\u0440\u0435\u0434\u043f\u0440\u0438\u044f\u0442\u0438\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e, \u0447\u0442\u043e \u043f\u0440\u0438\u043a\u043b\u0430\u0434\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u043e\u0435 \u043f\u043e \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0445 \u0444\u043e\u0440\u043c, \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c\u0441\u044f \u043a\u0430\u043a \u0432 \u0442\u043e\u043d\u043a\u043e\u043c (\u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u043e\u043c) \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u043f\u043e\u0434 Windows, Linux, MacOS X, \u0442\u0430\u043a \u0438 \u043a\u0430\u043a \u0432\u0435\u0431-\u043a\u043b\u0438\u0435\u043d\u0442 \u043f\u043e\u0434 5 \u0431\u0440\u0430\u0443\u0437\u0435\u0440\u043e\u0432 \u2013 Chrome, Internet Explorer, Firefox, Safari, Edge, \u0438 \u0432\u0441\u0435 \u044d\u0442\u043e \u2013 \u0431\u0435\u0437 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043a\u043e\u0434\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0411\u043e\u043b\u0435\u0435 \u0442\u043e\u0433\u043e \u2013 \u0432\u043d\u0435\u0448\u043d\u0435 [&hellip;]<\/p>\n","protected":false,"gt_translate_keys":[{"key":"rendered","format":"html"}]},"author":1,"featured_media":24269,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[688],"tags":[],"class_list":["post-32465","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-administrirovanie"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.1.1 - aioseo.com -->\n\t<meta name=\"description\" content=\"\u041e\u0434\u043d\u043e\u0439 \u0438\u0437 \u043f\u0440\u0438\u044f\u0442\u043d\u044b\u0445 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0435\u0439 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 1\u0421:\u041f\u0440\u0435\u0434\u043f\u0440\u0438\u044f\u0442\u0438\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e, \u0447\u0442\u043e \u043f\u0440\u0438\u043a\u043b\u0430\u0434\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u043e\u0435 \u043f\u043e \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0445 \u0444\u043e\u0440\u043c, \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c\u0441\u044f \u043a\u0430\u043a \u0432 \u0442\u043e\u043d\u043a\u043e\u043c (\u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u043e\u043c) \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u043f\u043e\u0434 Windows, Linux, MacOS.\" \/>\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Yuri Gagarin\"\/>\n\t<link rel=\"canonical\" href=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/pro-veb-klient-1s__trashed\" \/>\n\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.1.1\" \/>\n\t\t<meta property=\"og:locale\" content=\"pl_PL\" \/>\n\t\t<meta property=\"og:site_name\" content=\"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"\ud83e\udd47\u041f\u0440\u043e \u0432\u0435\u0431-\u043a\u043b\u0438\u0435\u043d\u0442 1\u0421 | ProHoster\" \/>\n\t\t<meta property=\"og:description\" content=\"\u041e\u0434\u043d\u043e\u0439 \u0438\u0437 \u043f\u0440\u0438\u044f\u0442\u043d\u044b\u0445 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0435\u0439 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 1\u0421:\u041f\u0440\u0435\u0434\u043f\u0440\u0438\u044f\u0442\u0438\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e, \u0447\u0442\u043e \u043f\u0440\u0438\u043a\u043b\u0430\u0434\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u043e\u0435 \u043f\u043e \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0445 \u0444\u043e\u0440\u043c, \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c\u0441\u044f \u043a\u0430\u043a \u0432 \u0442\u043e\u043d\u043a\u043e\u043c (\u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u043e\u043c) \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u043f\u043e\u0434 Windows, Linux, MacOS.\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/pro-veb-klient-1s__trashed\" \/>\n\t\t<meta property=\"og:image\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:secure_url\" content=\"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg\" \/>\n\t\t<meta property=\"og:image:width\" content=\"350\" \/>\n\t\t<meta property=\"og:image:height\" content=\"350\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2019-10-31T18:47:12+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2026-05-20T17:17:21+00:00\" \/>\n\t\t<meta property=\"article:publisher\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<meta property=\"article:author\" content=\"https:\/\/www.facebook.com\/prohoster\" \/>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"\ud83e\udd47O aplikacji webowej 1C | ProHoster","description":"Jedn\u0105 z przyjemnych cech technologii 1C:Enterprise jest to, \u017ce aplikacja zbudowana w oparciu o technologi\u0119 form zarz\u0105dzanych mo\u017ce dzia\u0142a\u0107 zar\u00f3wno w kliencie lekkim (uruchamialnym) na systemy Windows, Linux, MacOS.","canonical_url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/pro-veb-klient-1s__trashed","robots":"max-image-preview:large","keywords":"","webmasterTools":{"miscellaneous":""},"schema":null,"og:locale":"pl_PL","og:site_name":"ProHoster | \u041a\u0443\u043f\u0438\u0442\u044c \u043d\u0430\u0434\u0435\u0436\u043d\u044b\u0439 \u0445\u043e\u0441\u0442\u0438\u043d\u0433 \u0434\u043b\u044f \u0441\u0430\u0439\u0442\u043e\u0432 \u0441 \u0437\u0430\u0449\u0438\u0442\u043e\u0439 \u043e\u0442 DDoS, VPS VDS \u0441\u0435\u0440\u0432\u0435\u0440\u044b","og:type":"article","og:title":"\ud83e\udd47\u041f\u0440\u043e \u0432\u0435\u0431-\u043a\u043b\u0438\u0435\u043d\u0442 1\u0421 | ProHoster","og:description":"\u041e\u0434\u043d\u043e\u0439 \u0438\u0437 \u043f\u0440\u0438\u044f\u0442\u043d\u044b\u0445 \u043e\u0441\u043e\u0431\u0435\u043d\u043d\u043e\u0441\u0442\u0435\u0439 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 1\u0421:\u041f\u0440\u0435\u0434\u043f\u0440\u0438\u044f\u0442\u0438\u0435 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u043e, \u0447\u0442\u043e \u043f\u0440\u0438\u043a\u043b\u0430\u0434\u043d\u043e\u0435 \u0440\u0435\u0448\u0435\u043d\u0438\u0435, \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043d\u043d\u043e\u0435 \u043f\u043e \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c\u044b\u0445 \u0444\u043e\u0440\u043c, \u043c\u043e\u0436\u0435\u0442 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0442\u044c\u0441\u044f \u043a\u0430\u043a \u0432 \u0442\u043e\u043d\u043a\u043e\u043c (\u0438\u0441\u043f\u043e\u043b\u043d\u044f\u0435\u043c\u043e\u043c) \u043a\u043b\u0438\u0435\u043d\u0442\u0435 \u043f\u043e\u0434 Windows, Linux, MacOS.","og:url":"https:\/\/prohoster.info\/pl\/blog\/administrirovanie\/pro-veb-klient-1s__trashed","og:image":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:secure_url":"https:\/\/prohoster.info\/wp-content\/uploads\/2021\/11\/logo-350.jpg","og:image:width":350,"og:image:height":350,"article:published_time":"2019-10-31T18:47:12+00:00","article:modified_time":"2026-05-20T17:17:21+00:00","article:publisher":"https:\/\/www.facebook.com\/prohoster","article:author":"https:\/\/www.facebook.com\/prohoster"},"aioseo_meta_data":{"post_id":"32465","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"local_seo":null,"seo_analyzer_scan_date":"2026-01-21 11:00:20","breadcrumb_settings":null,"limit_modified_date":false,"reviewed_by":null,"ai":null,"created":"2021-03-01 02:58:23","updated":"2026-01-21 11:00:20","focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"gt_translate_keys":[{"key":"link","format":"url"}],"_links":{"self":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/32465","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/comments?post=32465"}],"version-history":[{"count":1,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/32465\/revisions"}],"predecessor-version":[{"id":173305,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/posts\/32465\/revisions\/173305"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media\/24269"}],"wp:attachment":[{"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/media?parent=32465"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/categories?post=32465"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/prohoster.info\/pl\/wp-json\/wp\/v2\/tags?post=32465"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}