Back to Home

Javascript frameworks: only one should be left / Oleg Bunin (Ontiko) Conference Blog Company

Sergey Averin Ā· javascript framework Ā· highload ++

Javascript frameworks: there should be only one

    Sergey Averin ( XEK )


    Sergey Averin

    Initially, I wanted to make a report about comparing frameworks, but then I thought that they would throw tomatoes, so the report is just hellish trolling, as usual with me. And he, rather, is not about HighLoad, but about the managerial task that is above all this business, including the front-end.

    About what, nevertheless, did you get a report? A report on how to choose a new framework, why they chose, and what tasks they solved.



    First, a little about the company, then the problem area, the task, as we looked, what the company now has; how to choose, in general, from which to choose; how options were evaluated; how they finally decided to redo one of the suitable options for themselves, then they compared the pilot projects on two competing technologies; what the results were, and how, in the end, they decided to move on.

    And now the time has come for revealing stories.

    A little about the company:



    Acronis is a very large Russian business that serves 5 million users, of which about 10 percent are corporate clients, to whom their work is licensed. Accordingly, the company itself is also very large, we have 17 different offices, R&D are in three different countries, and the largest R&D is in Moscow. But at the same time, our development is distributed, and there are remote managers whom I did not count here.

    The scale of the software under development is very different: we have boxed software for Windows, we have boxed software with a web interface that we sell to enterprises, there is software that we sell and implement ourselves, and this is a mixture of both boxed and cloud-based software. There is cloud-based software that we sell by subscription to both home users and corporate users. There is even software that we sell first to large hosting companies, which on their own behalf sell it under their own brand to their final users. And all this business has a huge number of web interfaces. This is about web products, not web sites, per se.



    When I came to the company, I began to figure out what we had, how everything was happening, it turned out that there were various kinds of web admins inside the company, which we did immediately on a bunch of different technologies, starting from a true front-end such as Ext JS or AngularJS, ending with sites that are written in Ruby on Rails and in which jQuery simply switches pages or graphics.

    The team faced such problems.



    Firstly, there are a lot of technologies, they are all different, developers cannot be dragged from one department to another, they cannot help some project, because Ruby on Rails developers who write in jQuery know nothing about AngularJS. Secondly, it turned out that a significant number of people work part-time, either as backend developers or front-end developers. For example, we have guys who write in PHP, and they also make a site on AngularJS that works with it as a backend. There are not very many of them, they have a small project, and there is no sense in starting up a separate front-end developer.

    As a result, I calculated that we have java people, ruby ​​people, python people and php people who all do front-end. And at the same time, the company does not have a layout designer, not a single one. Those. There are a few people who know this area expertly, but they usually work as encoders on AngularJS. As a result, these projects have completely different styles of code, completely different styles of comments, they are deployed in different ways, in some place, using Ruby on Rails we build AngularJS applications using a ruby'sh collector. And in the end - everywhere a different zoo. Each department has its own zoo. And in short, it turns out that our flagship product, which Ext JS is written in, is a huge admin panel, there are hundreds of screens, it is now built on the basis of version 4, and in 2015, most recently, version 6 has already been released of this framework and, like, we are 5 years behind the version of the framework that we use. Perhaps you also need to do something about it.

    Of course, the authorities came and set the task. The task was given from above:



    We need a thick client on front-end technologies that will communicate with the stateless backend API as much as possible where we can implement it. We need a single library of UI components, a single look and feel for the whole company, because we suffer a little from the fact that our fonts are somewhere different, somewhere in pixels the layout has floated, and in the end it turns out that we have two the neighboring departments draw some common elements for all our admin areas, which the designers painted the same way, a little differently - somewhere HTML layout, somewhere the layout is crammed into JS code in some kind of native template engine. And the CSS layer is also fundamentally different, somewhere it is superimposed from three or four files on top of each other, throwing the existing framework over.

    I really want us to finally be able to connect a normal layout designer and hire a developer with a lower salary, who would be responsible, on the one hand, for communicating with designers, preparing designs, and on the other hand, would bring and say to java-scripters: ā€œHere , they want it, here you need to animate this interface ... ". And at the same time, we could hire JS-encoders in projects not top-level. Now we have a lot of guys who have gone through fire and water, they know Java, they know .Net, and in this regard any javascript framework is not a problem for them, because they are, in principle, very experienced. Therefore, I want to somehow be able to hire not one out of a hundred, but at least two out of fifty.

    And there is such a separate pqrity. We have most of the people who make the front-end, it’s either the former or the current back-end, so I really want all of this to be understood by the back-end developers. Management, when it sees the code in JS, it starts saying, ā€œDamn, we don’t understand anything, everything is bad, let's rewrite it,ā€ and often it’s not so.



    We looked at what we actually have in the company. It turned out that we have an affiliate product that is written in Dojo. For him, we write plugins for Dojo, it is a very ancient framework, very special, it works as a component model. This is not entirely MVC, but we decided to do nothing with it, because we cannot use any other framework, otherwise we will not be able to work with this affiliate program.

    For the site, in fact, we have almost no dynamics. It is important for us that search engines index it, and it is important for us that it works quickly. We do not really need Javascript there. Therefore, some kind of superframework for him, in general, did not rest. This is a task that we should not solve.

    From the rest, from which the admins are actually made, this is Angular JS of the first version, this is Ruby on Rails, plus generating pages on the backend, plus some jQuery supplements that make some kind of dynamics. And most of the products are written in ExtJS 4. These are very high-level frameworks that most resemble .Net or QT, on which most of the company's products - serious and adult - are written.



    I got to understand what this ExtJS is. It turned out to be a huge colossus, a locomotive of code. On the main page, 395 classes of this framework are described.



    Each class has a very deep inheritance tree, i.e. in this regard, it is very much licked from how QT, .Net and other MVC frameworks are built, which work somewhere in Windows or in Linux for desktop. As a result, it turns out that often the code you debase is somewhere three levels higher than what you now need. This is really hard to figure out.

    Ext.panel Class:



    These are only methods from it. There are still as many events, as many different properties. It is clear that no developer can remember all these methods. Therefore, you constantly have to work with the documentation to understand how to make even the simplest thing, because the size of a component ... There are already three different methods, and they return three different sizes - each in its own way.



    In the end, I was sad, very. At first I didn’t understand anything at all, looked at the whole thing and asked myself the following question: ā€œLord, why did you write all this?ā€

    The index page of the flagship application was printed by me on sheets A0 and occupied 51 sheets in font 6.



    Here is an enlarged case:



    This is a DOM tree, there were 32 thousand nodes in it. This is just an index page generated by the framework, i.e. we haven’t pressed a button yet. It just loaded the page and rendered everything. It became obvious that, damn it, something strange is happening here, obviously there is some garbage with this.



    They climbed to see how the UI is done in this framework. It turned out that the user immediately receives a library of UI components, which will be thrown off by CSS. You have to add CSS on top, then you get your custom skin. And many components that were not there, they had to be implemented from scratch. As a result, often, not everywhere, but very often, I came across something like that. This is a javascript class, which is on the one hand the UI component, but on the other, it is often seen that it mixes three different entities in it - it is javascript code, html code and these are some very strange directives of the local template engine, these xindex, xcount or this tipeof values ​​string stuffed in curly, square brackets ...

    Of course, it’s very difficult to understand this all and it’s very difficult to maintain it, and it turned out that often, when components are inherited from each other, they can cut out pieces of this template and cut them into pieces. Those. there is a table, it has a cell template, there is a header template, and there are components that are inherited two to three times from each other. In one, something changes, and everything breaks. Or a new version of the framework comes out, and the components that are made on top of it stop working.



    Then it turned out that this is the only framework I see that has such a joke as layouting. They climbed to see what, how, why, where did these tags come from? It turned out that when resizing a window, when resizing some component, the framework, just like on a desktop, calculates the size of the blocks themselves and inserts them inline with CSS. Type left, right, width, height. Not only that, there is a very tricky algorithm that takes text and estimates its size, stuffs it into an invisible div, and looks at what size this div turned out for a given width. And so he mimics, under the function of estimating the size of the text, how much this text will occupy in this block, and calculates these blocks. And then it turned out that this algorithm is also tree-like, i.e. he does 6-7 passes, because he, like a browser, also stumbles on some component, which does not interfere, begins to increase it and the parent component also counts. As a result, you start moving the right page of the browser and clearly see its blunts about changing the size of this framework. But, on the other hand, it gives you a benefit type, that in all browsers it works exactly the same, and you don’t worry about compatibility issues between browsers, because you have closed this question to the maximum.



    Along the way, it turned out that the components are very up to a fig. And all these components, each of them, is an instance of a javascript class that has three to five levels of inheritance, or even seven to eight. For each of them sizes are estimated by this magic layout'er, they are calculated and set. Parents then calculate the sizes, and as a result, the whole thing generates such funny little things - inline csss that are inserted directly into the divs of these components, directly into the tags. Therefore, it turns out such a huge DOM tree, strange.



    In an attempt to understand how this layouting works, I came across such a very strange place.



    At that moment I felt very bad, and I realized that I would never understand how this happens.



    Do you still remember that it is about performance?



    The whole thing takes up almost 2 MB already in the squeezed form, so it is not surprising that some tests like ā€œhow will it work on the mobile?ā€ Give funny load times. But, nevertheless, this is not such a big problem for us, because most clients are corporate, and they go to the admin panel when they need to configure something, i.e. in the first week after the purchase of the product, or when the infernal pipets, i.e. You need to get a backup. And the person who has the infernal pipets is ready to wait 16 seconds until finally the admin panel loads. Moreover, here we are talking about a fairly thin channel.



    With the framework it’s clear, very complicated and confusing. And the application itself? We climbed into the application code.



    It turns out that there are few comments in the code. Some difficult places are not explained. All applications are tightly coupled. Instead of one class - a long one, with 2.5 thousand lines, we usually deal with three or four classes of 1000 lines each, which very rigidly know each other and so, communicating, forwarding events to themselves, changing states within themselves. And inside, we have very big problems with the boundaries between the model and business logic, and between business logic and view. It turns out that we have view classes that are called something like ā€œa magic panel that implements a certain functional panelā€, which at the same time draws itself and draws child components, and it also has a lot of business logic that can switch some then the panels inside, and which can send notifications, even often they climb from the view-classes to the server.



    Therefore (very conditionally) it turned out so that we have this not mvc, but M + CV. Those. the border between control and view is very undefined. It turned out that the models have business logic, and the controllers have business logic, and the view has business logic, UI logic, and the state of the application is also spread over all three types of classes. Therefore, it is difficult, for example, to understand where this data came from, or who is the authoritative point, where this data came from, and who stores the most reliable copy of this data at the moment, because it is in several parts of the application.



    It also turned out that the Ext JS framework itself pushes everyone towards the architecture built on publish / subscribe, because, in principle, it has all the UI components tied to this mechanism, and programmers unwittingly choose what the framework offers. And it’s kind of like publish / subscribe is the right pattern, but when you start looking at an application that has 100 pages, it turns out that you are trying to figure it out: ā€œDamn, what’s the effect of clicking this button in this panel and what does she pull? ā€



    And it turns out that, firstly, events can implicitly fall into parent classes, which, in turn, generate secondary events that fall into some classes with business logic, which in turn generate more events. Then part of the events is ignored by the framework, then some model changes, this model generates events that ā€œthe data in me have changedā€. Five more classes appear that are subscribed to its changes, and they change a state in themselves, which depends on the state of this model.

    As a result, after three hours, you finally build a harmonious picture and understand that all events have very similar names, and everywhere there is onclick. And you need to understand, this is onclick from this button that you pressed or onclick from the neighboring button that you pressed. Because the framework does not prohibit the subscription of any component to any. Those. you can get from someone supercontroller to a button in a specific panel and subscribe to it onclick. And it will be just onclick in quotes. And such matters are very difficult to debate, because there is no unique selectivity for these components. Those. it has its own mechanism called ComponentQuery, similar to XPath, in which you can write a RegEx query that tells you: ā€œFind me there all the buttons that are nested in a specific panel with a specific name.ā€ Therefore, when you try to refactor something, it’s very difficult to find everything, in general, the place where we react to a particular event. Often with us, this even led to event cycles when the application freezes because child events constantly appear, it starts processing them, and this cycle is endless. Until you write some tricky if like ā€œIf this event has already come to me, I don’t process it,ā€ then we will not process it further. Those. it's about intricate architecture. I don’t process it ā€, then we do not process it further. Those. it's about intricate architecture. I don’t process it ā€, then we do not process it further. Those. it's about intricate architecture.

    Everything is fine.



    And now I have a big question. In the code of large applications with a tight connection between the view logic, between the spread of functionality across different classes and the very poor delimitation of areas of responsibility between languages, technologies and other things, which is usually not?



    And so it happened. And it is not clear, in fact, why it happened. Because, in my opinion, it could be better. But, in short, we checked the Arrays objects, the rest is how it goes. And this eternal story is that when you start writing tests, you learn a lot about your application, that in fact, you never had to make so many connections, because locking 15 objects for the sake of calling one function is very hemorrhoids. And in this regard, they received the tests "come on, goodbye."

    What are the findings? How would such conclusions, of course ...



    But in reality, what are the real conclusions?



    That the framework is very difficult for developers to understand, especially developers who have not defended their doctoral dissertation on Java before. Secondly, the code that came out is very confusing. It has a lot of connections, all classes know about each other, and the events that appear are not controlled by anyone, and this leads to fireworks-like explosions of application state changes, when 15 places are subscribed to some state, events then generate their children events, and even some other places begin to process these events ... In this regard, the framework is terribly asynchronous, and this asynchronism explodes the brain. It turns out that the components are ruled by people who understand at the same time the template language, mixed JS-code, html, CSS and all this in one file. To hire an ordinary typesetter? I don’t know ... How much does the layout designer get now? For 40-60 thousand, it is impossible to find a layout designer and put him in a simple routine ā€œremove this button in this panelā€, because the assembly of the entire UI takes place in JS code by creating instances of JS classes. Those. You describe a large tree, which button to insert into which panel, which parameters to transfer, which links, to which events then subscribe.

    Accordingly, my main question was - is the framework to blame for this? In fact, of course, to blame. Partially. Because it pushes you to publish / subscribe, because it pushes you to the kind of mvc that they themselves do, the pseudo mvc. Because it does not have dependency injection out of the box, because it does not tell you how to test this whole thing ...



    This, in fact, is about the fact that we really need not so much code performance as just normal clear rules that are understandable for developers - where to put files, how to name a program, what is good and what is bad, what architecture is useful, what architecture is useless. We need a code in which you can hire a person, give him two weeks, he will understand it and begin to finish it normally, without shooting himself in the foot, by dereferencing some tricky links and trying to track where this event ends.

    We need a clear separation of work by people: some people make layouts, other people inhale something in layouts, third people are responsible for working with the API, and fourth are responsible for designers. We need a separation of languages ​​and technologies, preferably file-based, so that it is possible for some people who are not versed in JS-code to give some secondary tasks, for example, translations, i.e. localization to the desired language.

    Of course, I want a less connected architecture, because testing it is unrealistic, writing tests for this is very difficult. Therefore, I want some kind of isolation. Clear micro-components, each of which is responsible for its own small piece. And a simpler UI layer.



    What is the main message of this whole presentation (and this is the most important slide) - that all your songs about front-end performance turn into a noodle-like code, lack of standards and "we hired a new dude, and he has been correcting one bug for four months." First, let's improve the productivity of developers, give them normal, and not bent tools, and they will create code that will work much better, because these tasks were solved at the foundation level. Those. we will stand on the shoulders of giants.

    Accordingly, they decided that something needs to be changed somehow, something needs to be chosen, of course, it is necessary to somehow evaluate this whole matter independently and impartially.

    Of course, I went online. Well, what to do? Here everyone would go online.



    It turned out that for five years, while I was managing and working on PHP, a lot has changed in the JS world, in this regard I had to learn a lot from the beginning.



    And these thousands of frameworks, each of which, like two drops of water, are often similar to each other, especially in flux frameworks - it’s directly ā€œcome up with your name JS pointā€. And from this hell where the Google Web Toolkit has long died, we must somehow choose. Damn what to do? Of course, it was necessary to think something, how to see how others somewhere choose something on the Internet, climb in and somewhere to steal the result.

    As a result, it turned out that I won’t be able to erase the result, I have to make an honest assessment, because they are all very different. Therefore, a whole big serious presentation was made for the authorities, in which there was an attempt to realistically and impartially evaluate what kind of frameworks companies and sites of all kinds are using.



    It was about companies and sites that I cut out slides from there, it remains just honest numbers. This is the number of lines of code written generally since the advent of Github on various technologies. Plus or minus.



    This slide tells about how many reports were made on which technologies at which major conferences dedicated to the front in 2015 abroad.

    And everywhere the picture is different.



    In this picture, the trend of Google searches popularity. There are several of them ... Here, if you look closely, you can see that all technologies are actually declining, except for React js and Angular js.



    If you take some old more or less frameworks of dip Dojo, Yahoo ui and our beloved Ext js, then everything also goes into decline. In this regard, no one will fight with React js and Angular js, because this is the only thing that goes up.

    We looked further at such a study, where 2.5 thousand developers were surveyed, each of whom chose one technology.



    This is an American company that makes and sells a cloud IDE. The result is such a picture, completely different. Those. those developers who support the products, they are still strong, for example, Backbone, which by and large is outdated, but, nevertheless, there are many projects on it that are still being completed.



    And this is the Russian market. We tried to evaluate who we can hire, because it is obvious that we are not working in space, and we need to make products in the company, there are a lot of products and plans are huge, so someone needs to be hired. Here, in general, the picture is different. It turned out that one way or another, with one of the versions of ExtJS (since it is quite long) and with some of the versions of Backbone (since it was also born in 2008), one way or another, someone was dealing. Those. this does not guarantee that this person is ready to do something realtime right now on this framework, but, nevertheless, it turned out that among the growing technologies of React js and Angular js, Backbone and ExtJS suddenly appeared, and vacancies for they are, and there are a lot of them. Backbone Jobs More Than With React Knowledge This is an amazing picture on the Russian market.



    As a result, we crossed all these studies as much as possible and left what we are interested in. They added Dojo there and added ExtJS 6, which they initially wanted to switch to. And Dojo, because it is used by Parallels, with whom we integrate closely, and on which they have something written.



    Here five slides were brazenly carved. I will not talk about why it did not suit us all, because the story there is very boring. I will not stop there. If you climb to study for yourself, then you will form some kind of picture for yourself. We evaluated based on our objectives. One of the tasks was that the technology should be more or less embedded in parts in the existing code, i.e. we need not a monolithic framework, but rather a set of some techniques and libraries that we can slowly introduce. In this regard, it turned out that Knockout is not a framework at all, but a UI library, Dojo is just a mammoth, and ExtJS 6, although it introduces a new architecture, is actually not much different from ExtJS 4. That is, there appeared some kind of support, better work with mobile devices, but the concept has not changed. The architecture there has become a little better, but for us, as we have estimated, it’s about the same that we will rewrite the architecture honestly on ExtJS 6, just like they suggest that we will remodel it on any other framework - about the same in cost. As a result, they refused because all the same UI layer, all the same publish / subscribe.

    In fact, there were only two true candidates.



    The first - AngularJS - for obvious reasons, which was still very actively upheld by several departments of the company and some external advisers. But a very interesting dilemma arose with him. On the one hand, it looked really a very good solution, on the other hand, I saw a lot of articles on HabrƩ and, in general, on the English-language Internet, in which they discuss some conceptual errors made during its design, which lead to the fact that everything would be very cool, but we are confused.

    Our own view on this matter is such that if we take version 1, on which we have two projects in our company, and sit and smoke the source code, then this framework has really good modularity of dividing into separate pieces, each of which makes its own small functionality - this is very useful and good. But there is no single style of file layout, there is no single style of naming any variables and a single style of code formatting, i.e. this is the thing that I would like to somehow get to the heap with the framework, but never mind. And over time, this layout style changes. I’ll also add from myself that there are often places in the code that, in a good way, should be separate classes, but for some reason they are shoved there in the form of an object with functions. It’s hard to debase, a lot of different tricky ā€œmagicā€, it is very difficult to integrate with some new technologies, because the standards are absolutely all of your own ... How to assemble this business is also not very clear, but this issue can be resolved. But the worst thing is that I couldn’t sell it to the authorities, because we all said that "Guys, they are making a new version, and the code will be incompatible." What to do next is unclear.



    OK, they climbed to watch version 2. Version 2 directly looks great in general, like what you need, such a backend-oriented approach, everything is laid out on the shelves, very good TypeScript syntax is what you need. But, damn it, there is no chance of a release, in general, no. I, most importantly, do not understand, this super-mega google corporation, it has been working with python for a long time ... An example of how python switches from version 2 to 3 is just a textbook example of how to do this. You must maintain the syntax of the old version, you must be backword compatible. And here some hellish hell is simple. It will be incompatible. ā€œWe are doing something new now. Here is the alpha version, there’s no documentation for it. When we start, it is unclear and, most importantly, we have a different syntax in all three languages. ā€ Well, get sick, damn it!

    Is this a solution? Excuse me, this is a front-end development locomotive, is it, like, the coolest framework that everyone is terribly fond of? And what should I do with the admins four people are currently writing on AngularJS? Come and say: ā€œGuys, you know, we just sit down and rewrite everything. Nothing will get better with us, we are just moving to a new version. ā€ - "Why move?" - "Well, because they abandoned the old one." And they, of course, will ask me: ā€œListen, but there is such a thing as in python, like,ā€œ by 2 to 3 ā€. Those. let's set some kind of parser on, and it will now reformat the code for us, and it will somehow begin to assemble. ā€ You say, ā€œSorry, no. Moreover, not only that, but now it is still changing. We will have a different syntax tomorrow. ā€ And this is also impossible to sell to anyone. The board of directors will look at me and fire me for tomorrow and that’s it. T.



    We began to look further, and there was a second solution - this is React JS, which Facebook made. With surprise it turned out that this is not a framework, but just a UI library. It has a very clear understandable structure, it is clear that this is a single data flow that only receives data, only draws them. Each component is isolated, each component has a declaration of what it receives for input, what it ultimately draws, what inside it stores as an intermediate state. No, in general, some kind of magic filters and other garbage that you need to connect from somewhere, learn and know how it works ... In this regard, everything is as predictable as possible and it is very cool. I liked that there is a very simple opportunity for tuning performance - it’s clear how it works, it’s clear how to use it, there’s nothing super complicated about it.



    The Flux architecture, which is actively driven by Facebook, went all the way to this. We looked at the whole thing, we, as it were, were so-so. On the one hand, that one-way data flow, and that synchronous processing is like a state machine, where a certain state of the application is clearly understood, is super. But how an application is divided into independent blocks and how to separate it, as in Angular JS, into some separate entities is not very clear. Because, it seems to me, there are clearly antipatterns in the form that stores store data, at the same time implement business logic, and also implement the logic for changing this data. Those. it is both a model and a controller at the same time. The idea with a single dispatcher, as a single Event Bus with uniquely named events, where you can quickly find in the code where what has changed, do a quick refactoring, and the components work isolated from each other - it's super. But it is completely incomprehensible how the dynamics is provided, how to open, for example, two windows on one screen that would work independently of each other, but at the same time generate the same events, for example ...

    By and large, Facebook hasn’t overlaid the code, it’s not there, this isn’t a framework, it’s some kind of architectural idea. Moreover, invented in the 80s, which is called Event Bus.



    OK. Let's see some third-party frameworks that implement this garbage. I reviewed five pieces, they are all like two drops alike, and they are all much worse in this regard than AngularJS, and much worse than Ext JS, because there is almost nothing in them. Yes, it’s better to see how the architecture works, but there’s still no question of any dynamic creation of stores, unloading them, and some kind of linking of UI components between stores so that parts of the application work isolated from each other and you can two components would be created the same, with the same view, and two controllers, and they would not have fought each other with these events. Therefore, in this regard, with the development of web applications, everything is very strange, i.e. it is often unclear how to do this. But in these frameworks you can see the development of javascript over the past 5 years, in the form of isomorphism, in the form of npm-modules, in the form of rendering the functionality of the library, in the form of ES6 support - this is good. Only, damn it, no fig, in general, they have no testing infrastructure, and it is not clear how to write a test. Especially with this new super hierarchy, it is unclear how to write a test. And there is no internationalization.

    Along the way, we came across typescripts. In this regard, this is, in general, a bomb.



    I thought that the most super thing - to remove the unnecessary creativity of different developers who really like to make their "bikes" - with this you can perfectly. Typescript is a trans compiler, i.e. you write javascript-like code with the same syntax, just setting the types. Those. each variable has a type, moreover, they can be complex, it can have several types at the same time, and as a result it removes these types, creating a javascript file with absolutely the same syntax where these types are simply removed, and there are still some useful syntactic sugar things that comply with ECMAScript 2006 standards. just a compiler from ECMAScript 6 to 5.



    There, for example, there are such complex data types when you can make an entire contract, i.e. there are objects with a nested structure, and now you have different parts of the application know in advance that such a cunning nested object comes from the API, or, for example, the fields are repeated in it. We use this as a kind of glue between the separate parts of the application, i.e. everyone writes this business logic, focusing on some kind of interface. And the compiler immediately checks when building whether it can be compiled, if you organize access to these fields correctly, if you mean the correct type in them.



    Then, there are interfaces. Looking ahead - the framework we wrote is based heavily on interfaces, i.e. We, guided by the principle of solid, divide into smaller areas of responsibility and make our different classes dependent on small interfaces. It turns out we have a greater decoupling of the application.



    Just like in python, there is support for generics. There are decorators, as in python, there are generics, as is customary in the C ++ world, and we are actively using it. And there are compound types. In rare cases, we can say that in this variable there can be either a string or a number, when this cannot be avoided. He also works fine with this.



    As a result, after this study, questions became only more. Which architecture to choose? Which solution is right? How to keep up with the development of javascript, in the form of ECMAScript 6? Where to get the library of UI components?

    And in this regard, Ext JS is very active in holding the blow, it has all this. It has its own assembly, it has a mechanism of internationalization, it has a clear architecture and more. Those. what happened then turned out to be strange, but there is no alternative. Well, as it were, she is, but she must be done herself. As a result, we want a Typescript framework, everyone wanted a Typescript framework at this point. Without - no one wanted.



    Well, what to do? Let's write the task for ourselves. JS encoders must write code. Layout designers need to typeset and communicate with designers. Obviously, you need to make the UI layer as simple as possible for the designer to understand, and for the programmer to understand without the terrible inheritance of CSS styles at three or four levels without the terrible inheritance of components. We need to make a clear and understandable architecture, a code that is understandable to backend developers, and we need to separate the areas of responsibility - separately layout, separately code, separately controllers, separately data storage, try to cram the application state into one kind of class type, calling it a model. And, most importantly, more boundaries, rules and standards: naming, code formatting, file layouts, all of this. And at the same time on Typescript. And yet so



    We ended up taking a framework called Este.js. He does not tell you anything; he was the most revolutionary and innovative. They copied smoothly until nothing was left of him.

    In the end, there were several problems.



    The first problem. It turns out that store is a kind of antipattern in flux. In practice, nothing good has come of it. As a result, we divided them back into classes that store data and can change them, and separately the business logic in the controller. This is roughly the same as where flux development is going when they have separately staked objects with a state. We have this object with a state simply called store.



    It was like that.

    It turned out something like this:



    Those. isolated blocks, about the same as in AngularJS, with the same mechanism as modules. In each module there is one or more of its stores, which communicate with one of several controllers. And in the end, this whole thing works separately from view. View only reads store data and generates certain actions that a single dispatcher scatters (in fact, not a single one, each isolated block can have its own) between controllers, each of which subscribes to events and decides if it responds to this event or not. As a result, our application works as a set of applications embedded in each other, in each of which inside flux. This is a hierarchical MVC where the views are simply nested and the controllers are isolated.

    The second problem is that Facebook suggests doing templates like this:



    Of course, we suffered for a long time, we realized that this is not an option at all, and we shoot ourselves in the foot. I absolutely don’t understand why I need to mix a bunch of JS-code, braces, parentheses, logic and all together in the UI component, when, by and large, the essence of the UI component is that it takes some kind of template and renders it in the browser. We looked at a project like wix-react-templates, wrote our own, very, very similar. But there is no code in it. Only there are blocks that provide iteration, if, then, else and variables, nothing else. Those. the task of the component is to push into this variable in advance what will be displayed in it. And the component’s task is to indicate how many times iterate which block with which data. This is what the template looks like:



    Here we wrote our own parser of these templates, which makes a DOM tree from it and generates such templates that are very similar to those generated by JSX:



    Now, this business is already automatically generated, and React works with this business.



    And the essence of the UI component is that it declares some props, declares some states, and in the simplest way it stuffs these props into blocks and variables. They built a certain tree, which is then rendered.



    For translations, we made a little thing that bites the text from these templates and generates a file for us. We translate this file with pens into Russian. You can add some kind of layout there. Note that there is a span added in the last line. We are laying this business for the pluralization of words.



    And, accordingly, the same template is further generated, but only in it these lines are replaced by lines in Russian and this span is also parsed and substituted into the template.



    The trouble with the dynamics is that Facebook does not really explain how this is done, how to make the two components work independently. In this regard, we have found several solutions and are now working on them.

    What is the result?



    It turned out to be a framework with good OOP and a small interface, with generics, closely similar to how it was written in java. With dependency injection, which provides the connection of classes within one module, which has only two external dependencies - it is React and lodash. In which any architecture can be made - we want reflax, we can do reflax, we want MVC - we can do MVC. Because there are three and a half files and plus React. And with a normal build mechanism via web-pack ...



    We made two pilot projects - one on Ext JS 6, the other on React. Absolutely from scratch, without using the existing code, both repeat the same functionality of the existing admin panel, but only one single page on it, on which some buttons do not click. Quite a bit, all this together took about a month of work in total.

    The tasks were - to make animations, to make a custom, we draw a scrollbar, to make a separate interface for narrow screens such as a la tablets, to make a separate mobile version when the screen is completely narrow, and to make it all authorized and go to json rest, load real data that we have in the API and allowed to work with them.

    As a result, the following numbers were obtained:



    You can not look at them, but the bottom line is that both projects are implemented from scratch, it turned out that flux + react won from 2 to 5 times. But with a big asterisk, that when we have as many UI components as ExtJS has, build sizes and initialization speed, it will certainly fall, because in this regard we compete with the industry monster.



    It’s clear that one cannot just move to this business. Therefore, we sat down, smoked all the existing interfaces with the designers, put together a single file, in which 60 simple components such as panels and buttons, 15 complex ones — this is the type we have a table in which we can turn off a column, sort rows or, for example , there is a drop-down in which you can type tags - these are directly specifically difficult things.



    I made some of them. Directly made working components on react, it took me about 4 days.



    As a result, it turned out that we did 10 percent, rated it as 2 thousand lines of code in 4 days, and received a rough estimate of 2 man-months for the implementation of all the UI components that make up our projects.



    We thought for a long time how to do it, but so far decided that we immediately do new projects on a new framework, simultaneously creating this UI library in a separate repository. We don’t touch the old code, but we embed ā€œindependent blocksā€ into it a new functionality in the form as ā€œwe take a separate panel or page, we rewrite it on a new oneā€. Or, if this is a new functionality, then, in general, we make this page again. Accordingly, the new framework pretends to be a UI component inside Ext JS, pretending to be some kind of panel that somehow renders and does something inside of itself, and outward, it gives a maximum of one or two events. And, of course, when modifying the old code, you either port the existing functionality or edit it as it is.



    So the essence of the report is, as always: overcome difficulties; bicycles, bugs, crutches - do everything your own. Do your own because your team now has the technology and expertise in how it works. Those. we read the sources of react and finally understand how it works.

    Contacts


    Ā» XEK
    Ā» [email protected]
    Ā» facebook
    Ā» twitter
    Ā» Acronis Blog

    This report is a transcript of one of the best speeches at the conference of developers of highly loaded systems HighLoad ++ . Now we are actively preparing the 2016 conference - this year HighLoad ++ will be held in Skolkovo on November 7 and 8.

    Also, some of these materials are used by us in an online training course on the development of highly loaded systems HighLoad. Guide is a chain of specially selected letters, articles, materials, videos. Already in our textbook more than 30 unique materials. Get connected!

    Read Next