Write it at the very beginning

This is a scientific article for mobile developers, starting from the initial process of front-end development, combined with the demonstration code, discuss the evolution of the development process, hoping to cover part of the front-end development technology stack, so as to form a preliminary understanding of the concepts related to front-end development.

Some sample code will be provided in this article, but they will not run and do not need to be fully understood. It is more for readers to have a more concrete feeling and a clearer understanding of related concepts and solutions.

In the process of writing, I read and learned taobao’s blog on the separation of front and back end and the evolution of front-end development technology, and benefited a lot. Relevant articles are listed in the references at the end of the article. At the same time, due to my limited ability, MY understanding of many concepts is relatively simple, even wrong, welcome to exchange correction.

The difference between mobile and front-end

In the process of developing an App, we don’t think about the development process, because everything seems very natural. What can be determined locally is written to death, otherwise asynchronously initiates network requests and dynamically modifies, and finally compiles the source code into executable binaries for the client to install.

Front-end development is fundamentally different from mobile development. The final presentation style of a web page is influenced by HTML + CSS, while JavaScript scripts are responsible for user interaction. Instead of being compiled into an executable, a page consists of several text files that are sent to the browser in clear text by the server and drawn to the screen.

The concept of “rendering” may be mentioned repeatedly throughout the rest of this article, but unless otherwise noted, it does not refer to parsing an HTML document (DOM) and drawing it to the screen, as this is done by the browser kernel and generally requires little understanding or intervention.

Web pages can be divided into two types: static and dynamic. The former is an HTML file, while the latter may be just a template. When requested, the data is dynamically calculated and finally spliced into HTML strings.

Another significant difference between front-end and mobile development is that while HTML can be debugged locally, the HTML content actually needs to be deployed on the server so that HTML text can be returned when a user makes an HTTP request.

The chaotic age of front-end development

In the beginning, we didn’t have any tools, just brute force. We know that servlets are server-side programs written in Java that can easily handle HTTP requests and returns, so we can directly return HTML text as a string, which is the same as rendering above:

public class HelloWorldServlet extends HttpServlet {
    @Override
    public void doGet(HttpServletRequest req, HttpServletResponse resp)
        throws ServletException, IOException {
        resp.setContentType("text/html");

        PrintWriter out = resp.getWriter();
        out.println("<html><head><title>Hello World Sample</title></head>");
        out.println("<body><h1>Hello World Title<h1><h2>" +new Date().toLocaleString() + "</h2></body></html>"); out.flush(); }}Copy the code

In theory, we could have started all the front-end development, but writing maintainable code in these early days requires a lot of prehistoric power. Writing the UI and business logic together is a very strong coupling that is not conducive to future expansion of the project. You can’t require everyone to write Java and a front end at the same time.

The back-end MVC

One of the problems with the above solution is that the logic is confusing, which most mobile developers experience at the beginning stage. The solution is simple: use MVC, pull the business logic out of the Controller, and let the View layer focus on displaying the UI.

Implementation of MVC scheme

In the field of front-end development, there are similar technologies, such as JSPS, which are compiled into servlets. When writing a JSP, we care more about the page style, so the code looks like HTML, but within the <% %> code block we can call Java functions:

<HTML> <HEAD> <TITLE>JSP test page --HelloWorld! </TITLE> </HEAD> <BODY> <% out.println("<h1>Hello World! </h1>"); %> </BODY> </HTML>Copy the code

JSPS are equivalent to the View layer, which fetches data from the Model and, more specifically, uses a back-end language (such as Java) to access the interface provided by the Model layer.

As a module directly in contact with the client, Controller is responsible for parsing request, data verification, route distribution, result return and other logic. Route distribution refers to invoking different Models and Views to provide services depending on the request path.

Disadvantages and improvements of MVC

With MVC architecture (such as the well-known Struts), it seems that the responsibilities become clearer, with the front-end developer writing JSPS and the back-end developer writing controllers and models, but there are still a lot of problems in actual development.

First, business logic is still not strictly differentiated, and without good coding specifications, JSP will be mixed with a lot of business logic. The purpose of a framework is to allow new people to write decent code without a lot of training. In addition, front-end developers also need to have a general understanding of back-end logic and be familiar with the back-end programming language, so there are a lot of communication and learning costs.

The front end is just Demo

One solution is for the front-end developer to just write the Demo, that is, to provide static HTML effects to the back-end developer, who will do the view layer (such as JSP) development. Front-end developers don’t need to know anything about the back end.

Unfortunately, it’s a good idea, but there are problems with putting it into practice. First, backend developers rely on the front-end Demo, and only when they see the HTML file can they start implementing the View layer. The front-end relies on the back-end developers to complete the overall development and check the final effect through network access, otherwise they can’t get real data.

To make matters worse, once the requirements change, the process has to be reworked, and communication between the front and back ends is still inevitable. Generally speaking, the cost of front and rear end docking is too high.

For example, while developing an App, your colleague sends you a piece of code that is a locally written view and says, “The text for this button needs to be retrieved from the database, and the content for that image needs to be retrieved from the web. Change the code.” . So you spend half a day fixing the code, PM comes to tell you that the button text is dead, but the background color needs to be read from the database, and add a button. WTF?

Obviously, this development process is extremely inefficient and unacceptable.

HTML template

In fact, to a certain extent, JSP can be seen as the prototype of HTML templates. HTML basically does two things: frame the page and describe the content. An HTML template is a framework that uses a structured syntax to represent HTML, while isolating specific data.

For example,

111

represents a paragraph with the content of “111”. If you use a template, you can write

Content

, p Content, etc. Anyway, instead of obsessing over the syntax, just know:

Data + template = HTML source code

For example, at the Controller layer, it could be called like this:

// The template name is not specified here, because the idea of dependency inversion is to bind the View corresponding to the Controller in the configuration file
return res.view({title: "111"});Copy the code

The code in the template is as follows:

<h1><% = Content% ></h1>Copy the code

Readers familiar with front-end development will notice that this is actually losa.js + EJS. The former is a javascript-based server-side application, the latter is a template based on HTML syntax, and the other style is Jade, but the purpose of this article is not to focus on how to use these tools.

Going back to the concept of templates, it has an advantage over JSP in that it uses tools to forcibly prohibit front-end developers from writing business logic at the view layer. The front-end developer only needs to care about the UI implementation and determine the variables in the HTML. The back-end developer simply passes in arguments to get the STRING in HTML format.

Another benefit of template development is that the front and back ends can be developed simultaneously. The two parties agree on a data format, so that the front end can simulate fake data and use it for self-testing, and the back end can compare the generated data with fake data for testing. At the same time, the agreed data format plays the role of contract and document, standardizing the form of data communication between the two parties, thus saving the time cost of communication. Please refer to this link for more Mock Server topics.

Summary of back-end MVC architecture

Using the back-end MVC architecture plus template development is one of the prevailing development models, but it’s not perfect. Because the templates are done by the front-end developers, it is required that the front-end developers have some knowledge of the back-end environment (note that this is not an implementation detail).

As a simple example, the backend of a large application is divided into many folders, which requires the front end to understand the code structure, SSH, VIM, and dependency on the server environment when uploading files.

In general, with server-side MVC, HTML is rendered in the back end and the overall development process is based on the back end environment. So the front-end engineer inevitably needs to rely on the back end (although the situation has greatly improved with the use of templates).

AJAX versus front-end MVC

AJAX stands for Asynchronous Javascript And XML. It is not a framework, but a programming idea. It uses JavaScript to make requests asynchronously, the results are returned in XML format, and JavaScript can then locally manipulate the DOM based on the returned results.

The biggest advantage of AJAX is that instead of reloading the entire data, you can simply retrieve the changed content. This may seem natural in mobile programming, but front-end development is done exclusively with AJAX, and by default every minor change to a web page requires a reload of the entire web page.

Analog mobile application, AJAX is fit to be a single page updates, but not good at page jump, jump is just like your app page to create a new UIViewController/Activity rather than directly change the content of the current page.

Thanks to AJAX, HTML rendering in the front end became possible. You can download an empty shell HTML file and a JavaScript script, and then get the data in the JavaScript script to add nodes to the DOM.

There are lots of front-end MVC frameworks like backbene. js, AngularJS(let’s just say MVVM is a variant of MVC), and you can find their demos here. Take React, which I’m relatively familiar with:


      
<html>

<head>
  <script src=".. /build/react.js"></script>
  <script src=".. /build/react-dom.js"></script>
  <script src=".. /build/browser.min.js"></script>
</head>

<body>
  <div id="example"></div>
  <script type="text/babel">
    var LikeButton = React.createClass({ 
      getInitialState: function() { 
        return {liked: false}; 
      }, 
      handleClick: function(event) { 
        this.setState({liked: !this.state.liked}); 
      }, 
      render: function() { 
        var text = this.state.liked ? 'like' : 'haven\'t liked'; 
        return (
          <p onClick={this.handleClick}>
            You {text} this. Click to toggle.
          </p>); }}); ReactDOM.render(<LikeButton />, 
      document.getElementById('example') 
    );
  </script>
</body>

</html>Copy the code

This code doesn’t have to be completely readable, just realize that with the introduction of the React.js framework, we can move away from HTML programming. All the logic is written in JavaScript code within the

We also created a LikeButton component that can have its own methods, manage its own state, and so on. The React example is a bit of a misstep because it’s really just a View layer implementation that needs to work with the Flux or Redux architecture. But it’s enough to get a feel for pure JavaScript development.

This development mode is very similar to mobile terminal development. JavaScript is used to call DOM interface to draw views, and JavaScript is used to realize business logic, process data, initiate network requests, etc. You can think of it as simply developing a mobile application in JavaScript on a browser, but the user downloads a JavaScript script instead of a compiled binary file in a traditional static language.

With the use of front-end MVC framework, for Single Page Application, the front and back ends have their own functions, and the only connection becomes API calls. Front-end developers no longer rely on the backend environment, and HTML and JavaScript can be placed on the CDN server. This is what we call the basic concept of front and back end separation, where the front end is responsible for presentation and the back end is responsible for output.

Disadvantages of front and rear end separation

However, in my opinion, the above front-end and back-end separation scheme is far inferior to the back-end MVC + template development process, because in the actual development, pure SPA scenarios are not common, even the mobile terminal is not only a view, but a lot of page hopping logic, let alone hyperlinked web pages everywhere?

Let’s take a look at the disadvantages of using front-end MVC framework to separate the front and back ends when SPA and multi-page hops coexist.

Two-ended MVC is not unified

The front-end MVC mainly deals with the logic within a single page, while the back-end MVC framework deals with the logic of the entire Web server. To paraphrase Herman’s image from jSCONF:

Because the front and back end MVC frameworks have different priorities, they have different positions. The front-end MVC framework is responsible for page presentation, so it is just the View layer (or maybe just part of the View) of the back-end MVC framework.

This can lead to the following problems:

  1. The front-end Model and the back-end Model are highly similar in structure, for example, the front-end uses onenameProperty, and the back end must define one in a JavaBeanname. In some cases, the back end may have done some preprocessing to prevent the front-end from doing too much logic to the data and causing performance degradation. It’s like when we write an App, the feed stream might be filtered and sorted, but on the mobile side we have to do some transformation in the ViewModel before we can use it. Therefore, logical coupling between the front and back ends cannot be completely avoided.
  2. The front-end Controller is responsible for page scheduling, such as control state management and style changes. The Controller at the back is responsible for invoking services, user authentication, and so on. The two are not equivalent at all.
  3. The front-end also has a routing module, which is mainly responsible for the jump between controllers within the page, such as the React-Router. The back-end route distributes different network requests to the specified Controller. The two logic can not be unified.

SEO

SEO(search engine optimization) is an issue that mobile developers never think about, but front-end developers consider life and death. Search engines work by visiting every web page, analyzing the tags and keywords in the HTML and taking notes.

In a purely asynchronous web page, THE HTML is almost empty shell, but the key data are all dynamically delivered, which affects the working process of search engine crawlers. They will think that the web page has nothing, even if the recorded data is not critical data.

A few years ago, Google introduced the Hash-Bang protocol to compensate for AJAX’s negative impact on SEO, essentially providing a degraded processing mechanism for back end rendering for crawlers. Google crawlers can read JavaScript code and crawl data to a certain extent, but AJAX doesn’t support crawlers as well as DIRECT HTML text transfers.

The performance is not enough

As you can see from the React example above, the HTML file is very small and is quickly opened. But the rendering logic of the page doesn’t start executing until the JavaScript file is downloaded, which leads to a blank screen for a while.

On mobile networks, the performance of front-end rendering HTML is certainly not as good as that of back-end rendering, and frequent sending of HTTP requests will also affect the loading experience, so pages that rely on front-end rendering still have a lot of room for improvement in terms of performance.

Concentration Or separation?

Many years ago, JavaScript and CSS were not written separately in external files, but were built directly into HTML code:

<p style="background-color:green"
    onclick="javascript:myFunction()">
    This is a paragraph.
</p>Copy the code

For ease of management and modification, we separate CSS from JavaScript. React, however, seems to go backwards, with all the logic in JavaScript.

My understanding is that this approach lends itself to componentization, where it is easy to define a component and reuse it. This idea might work for complex spAs, but it’s too heavy for uncomplex web pages with multiple pages. The introduction of frameworks like React and the MVC structure, on the contrary, would be overdesigned, increasing the amount of code and complexity.

This is more likely to lead to performance problems, given the previously stated problem of not being able to reuse the front-end logic.

Node.js

The philosophy of front end separation

So far, we’ve tried a variety of options such as back-end MVC architecture, HTML templates, and front-end MVC architecture, but the results have always been unsatisfactory, and it’s time to summarize the reasons.

In the process of doing this, we overemphasize the separation of front and back ends in the physical layer, but ignore the natural coupling between the two. In fact, the front-end developer should be concerned not only with the implementation of the View, but also with some of the logic in the Controller, while the back-end developer should be concerned with data fetching and processing, as well as some of the business logic across terminals.

If the page is rendered to the back-end implementation, the front-end developer becomes dependent on the back-end implementation and development environment, and the back-end developer is forced to become familiar with the front-end logic (instead of calling the API, the back-end developer is forced to generate the data directly and apply the template, which requires that the data obtained be converted to the data needed by the template).

If page rendering is all in the front end, the business logic will be too far forward to be reused. That seems like overkill. In addition, there are a number of AJAX downsides that have been introduced in the previous article.

We seem to be caught between a rock and a hard place where page rendering doesn’t fit either on the front end or back end. This makes sense. Page rendering involves data logic and UI, and should be handled separately by the front-end and back-end developers.

But wouldn’t the problem be solved if front-end engineers could write back-end code? The actual processing of the data can be divided into two steps: get the data from a database or third-party service, and put it into a usable form for the View. The former tends to be associated with C++/Java servers, while the latter is associated with front-end templates that act more like viewmodels in the MVVM architecture.

Node. Js stratification

In my last article, I outlined node.js as “a back-end application framework developed in JavaScript.” So it’s the perfect solution to the problem of the front end not knowing the back end logic and code.

Node.js acts as an intermediate layer, invoking services provided by upstream Java servers to retrieve data. It is responsible for handling business logic, routing requests, cookie reading and writing, page rendering, etc. The front end is responsible for applying CSS styles and JavaScript interaction, similar to the original model.

To illustrate the picture in the evolution of The Web RESEARCH and development mode of Yubo:

There is also a very detailed table of explanations for reference.

Practical application

This is not a blog post about Node.js, and I’m not familiar with the application of the framework, but this is an example of how Node.js does front-end and back-end separation.

I chose the losa.js framework and the code for the project is given at Github: losa-react-example.

Views are stored in the views directory, using EJS as the template, and Node.js is responsible for rendering on the server side:

<div class="container">
<h1><% = __('Comment') % >s for SAILS<small>js</small> + REACT<small>js</small></h1>
</div>
<script src="/js/commentMain.js"></script>Copy the code

Controllers are responsible for page forwarding and template rendering, and the Services are handed over to the Controllers:

module.exports = {
  app : function(req, res) {
    // Call Services here to get data if necessary
    returnres.view({}); }};Copy the code

Services are not implemented in this Demo, but are usually used to interact with a real back end, either HTTP or SOAP depending on the situation, and process the results returned. In addition, policies/ Responses module deals with HTTP request and returned content respectively.

The front-end code is wrapped in the template layer and seamlessly integrates with Node.js.

Risk control

Although we have addressed some of the pain points of front-end and back-end separation by adding node.js processing layers, we need to be more thoughtful in practical applications.

After adding a layer, performance is bound to suffer. Layering, however, is a tradeoff that can be made to minimize performance loss through various optimizations. In addition, BigPipe can be used in the Node.js layer to handle multiple asynchronous requests.

When a traditional web page loads a page, it gets the HTML first, and then the CSS and JavaScript referenced in it. BigPipe separates the page into smaller chunks while the browser waits for data to be prepared on the server and transferred over the network. Although the loading logic of each chunk remains the same, the pipeline between blocks prevents the browser from waiting indefinitely.

Using BigPipe technology can replace multiple asynchronous requests with Ajax in certain scenarios. See BigPipe Learning Study for details.

With Node.js, the technical requirements for front-end developers will increase, and the coding workload will increase accordingly. However, this is the only way to engineering, the increase in coding is actually behind the improvement of communication and maintenance efficiency.

conclusion

To deal with the complex logic of the front and back ends, we tried to use a back-end MVC framework to separate the business and AN HTML template to separate the data from the UI style. Web pages with Ajax technology are more suitable for single-page applications. Although physical layer separation is achieved, there are still many problems when dealing with multiple pages.

In fact, page rendering is the topic of common concern between the front and back ends, and we should separate the front and back ends according to the business logic. Finally, Node.js is selected. With the help of its JavaScript features, front-end engineers are responsible for the processing of data acquisition and the use of templates, sharing part of the tasks that logically belong to the front-end, but technically tend to the back-end. This kind of development mode looks like a kind of regression, in fact, it is a spiral upward and return to simplicity.

Node.js’ event-based and asynchronous I/O features, as well as its excellent ability to handle high concurrency, are ideal for scenarios where the front and back ends are separated, and technologies such as BigPipe are sufficient to minimize the loss caused by layering. Choosing Node.js for front and back separation is not always a best practice, but it seems to have good applications so far, and you need to explore as you go.

The resources

  1. Taobao front and back end separation practice
  2. The evolution of the Web development model
  3. Thinking and Practice on The Separation of Front and back Ends (I)