JavaScript-only: homogeneous architecture of web projects

    The work of the front-end developer is filled with tasks to optimize the code, transfer ready-made fragments between versions of projects, etc., the complexity of which is often determined by the historically established approach to the development itself. In his report at the HolyJS conference , which will be held on June 5 in St. Petersburg, front-end developer Alexey Ivanov will tell how these problems can be reduced by abandoning the usual approach when the application consists of disparate parts in favor of “all-in-JS” . We, on the eve of the conference, talked with Alexey about exactly what difficulties his ideas were delivering (the ideas themselves will be disclosed in more detail in the report). - Tell us briefly about yourself and your work.





    - My name is Alexey Ivanov, I’m a front-end developer at Evil Martians. This is a distributed development group that helps large companies such as eBay or Groupon, as well as various startups, in a short time and without problems launch Internet projects with the expectation of rapid growth.
    In Martians, I’m currently doing a front-end service called eBay Social for the Russian eBay office. This is a classic Ruby on Rails application with separate interactive parts written in React.
    Before Martian, I made the first version of the SPA application for ridero.ru on Backbone, helped launch a couple of services for Yandex using bem-tools, and also developed other server and SPA applications of different sizes, which allowed me to touch a bunch of different tools and methodologies development. I like to study and compare different ways of organizing code, working with dependencies and conflict resolution, used in different methodologies and tools.

    - Where did the idea of ​​a global change in the approach to development come from?

    - Martian front-end tenders work with two main types of projects.
    First, we create classic Ruby on Rails projects. In such projects, templates are rendered on the server inside Rails themselves, and the assembly of CSS and JavaScript lives separately in Node.js and Gulp or another collector. We use pre- and post-processors, collect individual files into common bundles and compress Clean CSS and UglifyJS code, but CSS and JavaScript know very little about each other, and they don’t know anything about the HTML they work with.

    Secondly, we create single-page applications (SPA) that build HTML, and often CSS immediately in the browser, and communicate with the server only at the data level.
    In fact, these are two parallel worlds in the modern frontend. At some point, SPA spun off from classic server applications into a separate evolutionary branch and went their own way with their own set of mutations and new ideas. As a result, the toolkit that is used on these two types of projects is very different.

    The tools and approaches used in modern SPA, allow with minimal effort to solve many classic problems of front-end development: the intersection of variable names and CSS classes in the global namespace, the removal of unused code and styles, the creation of CSS and JavaScript assemblies for specific sections and pages. The most pleasant thing is that the main part of the work here is done by the machine for you with your minimal intervention.

    Therefore, returning to classic server applications after working with SPA causes pain and suffering. Things that worked out of the box in the SPA, now either do not work, or they require a lot of time and effort to implement.

    As a normal person, I am looking for ways to get rid of pain and suffering. And my report is the result of these searches. I want to talk about existing problems, how to solve them in SPA, tools that appeared in SPA, but which can be used on the server, as well as concepts from SPA that are not yet implemented in the form of ready-made software for server applications (however, in if software was implemented, they would help to solve many currently unsolved problems).

    - Can you give examples of the mentioned problems inherent in the development of server applications?

    - In large projects, there are a number of tasks related to optimizing the download speed and reducing the amount of code that is sent to the browser.

    Suppose we send the user an HTML page, CSS, and JavaScript. CSS is written according to the BEM methodology. One way to optimize is to shorten the long CSS names that we wrote for ourselves when developing to avoid conflicts with other classes.

    Suppose we have a class:

    .block__element_modificator {}

    And we have about a few thousand such lines. I want to send something less long instead, let's say:

    .b1 {}

    How do we do this?
    CSS classes are used in several places: firstly, in the CSS file itself, secondly, in HTML, and thirdly, in JavaScript.
    Let's start with the CSS file. The first thing that needs to be done is to merge the CSS files into one, because if we deal with the replacement in different files, we can’t be sure that there are no conflicts (technically, you can shorten the names without combining them into one file, but an intermediate list will be needed replacements that will have to be loaded during the processing of each new file; this option is more difficult and more expensive to implement from the point of view of necessary resources - Ed. ). Next, we will go through the received file with some program and get two things in the output: a file with replaced names and a list of replacements in the form:

    { 'block__element_modificator': 'aBc' }

    So far, everything is simple. Move on.
    Now we need to replace these classes in HTML. This is not so simple: classes can be assembled from separate pieces of strings, variables in templates can be part of classes, we can collect the class name from these parts not inside the class attribute, but somewhere separately, etc. Well, somewhere in our place a single class can be used on a tag, and somewhere in a few. We need to identify all these points:


    If we miss at least one such place, the layout will break.

    In addition, we use class names in JavaScript. There it is even more difficult to determine what exactly is the name of the class:

    var className = "block__element_modificator";
    $elem.addClass(className);

    but do not edit anything superfluous:

    var block = ...;

    It is worth noting that a class in JavaScript can be stored simply as a variable, according to which it will not be clear that this is a class. Again, any logic can be used when constructing class names, or a variable can be called as a class, i.e. just a regular expression cannot replace it.

    As a result, a simple task - abbreviation of class names - turns into something non-trivial for us.

    With all this, compressing class names gives us not a very big gain in size. There are more effective ways to optimize the size of styles - for example, cleaning files from unused rules. When using libraries like Bootstrap or iconic fonts like Font Awesome, hundreds of unused rules get into the assembly. In the same way, weight is added to the rules that are skipped and uncleaned during refactoring. If we could send only really used rules to the browser, this would give us a much larger gain in size.

    - Is it also difficult to remove unused elements from the assembly? And does this “historical tail” really give a big increase to the size of the assembly?

    - If the project has been developing for several years, then tons of garbage can accumulate in it. And now I'm talking not only about individual class names, but also about complex selectors with nesting. For example, the rule:

    .news .title {}

    On our site, both the news class and the title class can be used separately. Moreover, in such a combination, as in the rule, they may never occur. In this situation, the rule can also be safely removed. As a result, to remove unused code, we need to understand the structure of the page, not only in the current state, but in every possible way (the page can be for an authorized or unauthorized user, with pop-ups, personalized ads, or a selection of records of a certain type in the friends stream). It is worth considering that to understand the structure of the page, HTML alone is not enough for us, because we have JavaScript that can change all this. In a good way, after we have built a tree of possible states for the page, we need to understand how exactly our JavaScript can change this tree.

    And only after we all understood this, we can with good conscience remove the rules from CSS.

    The same goes for JavaScript shortening. We can automatically delete unused variables and functions. But we can’t delete the code regarding working with HTML, because without knowing the structure of the page, we cannot understand what we really need from it and what will never be used.

    - Is it possible to simply use some other approach during optimization?

    - We can try to come in from the other side. For example, breaking a common CSS and JavaScript bundle into separate bundles for different pages, so that only what is needed for the current page is sent to the user. Let's say he came to the main page - let's send him only what is necessary for the main page, so that it seems faster, and load the rest somehow later. For simplification, we can even do not build pages, but according to the state of the user - for authorized or unauthorized (i.e. add a part after authorization).

    Only in order to do this quickly, we again need to know what page is located on, and how HTML, CSS and JavaScript affect each other. Of course, we can prescribe all this by hand, but this work is very long and ungrateful.

    And we have so far discussed only the reduction in the size of files sent to the browser. And there are also problems of name conflicts, resolving dependencies, transferring code from project to project in such a way that you don’t forget anything, removing unnecessary items from the source in the editor, and many others.

    - Is there really no tools for solving these problems? How then to get out of this "vicious circle"?

    - At the beginning of the interview, I just said that in the frontend there are now two parallel worlds: the world of server applications and the world of SPA. In the world of SPA, many of the problems described above have been successfully resolved, and no one remembers them, but in the world of server applications, they are still relevant.

    At the same time, we can’t just take everything and start writing SPA, because there are still a large number of areas where there are few dynamics on the pages, and indexing by search engines and accessibility from the maximum number of devices is relevant: these are online stores, directories, government sites with high requirements for accessibility and others.

    Unfortunately, it’s also impossible to simply take existing tools from SPA. They were created for a different environment with different requirements. But here the ideas and approaches that are used in these tools are remarkably carried over and used anywhere. It is about these ideas, approaches, features and problems of their application in different environments, as well as about what can already be used both there and there will be my report on HolyJS .

    - The idea, it seems, lies on the surface. Why doesn’t it go to the masses?

    - The idea is still going to the masses. There are isomorphic applications and attempts to cross React with Django and Rails . There are bem-tools, the reason for creating which were many of the problems that I will discuss in my report. There are attempts to make friends HTML and CSS on the server through pstcss-modules , which was written by my colleague Sasha Madyankin. That is, there are many approaches to the problem from many different sides, although there is no one common popular universally accepted solution.

    One of the main reasons why this solution has not yet appeared, in my opinion, is that the number of SPA developers is much less than the number of server application developers. And even among the latter, those who came across and worked with all those tools and concepts that I will talk about in the report are not very many.

    Just so that as many people as possible learn about these concepts and start thinking in these terms and, I hope, write tools for working with them on the server, I am preparing my report.

    Thank you for the conversation!

    As part of the conversation, we briefly described the problems that front-end developers face daily. For information on how exactly the “everything in JS” approach can simplify the situation, listen to the report by Alexey Ivanov on HolyJS. In addition, the conference will have several other reports related to the architecture of web applications. Well, of course, it will be possible for our today's interlocutor to ask questions that are of interest to you there, on the spot.

    Also popular now: