IO /topic/1275#

Feed, which cut figure, write the page is sent to r&d engineers set of templates.

Hello, Cuttey.

preface

After brewing for a long time, I decided to write a series of articles to systematically introduce my understanding of the front-end, especially the Web front-end, from the perspective of engineering.

As long as we still think of our work as a software development activity, I’m sure this will resonate with you as well.

The front end is GUI software

Now the front end can be described as all-inclusive, product form is multifarious, covering a wide range, what lofty foundation library/framework, cool and cool publicity page, and diaobaotianxiao games…… But these small project is not the end of one or two files technology main application scenarios, a more commercial value is a complex Web applications, they are fully functional, interface is various, to provide users with a complete product experience, may be a news aggregator, may be a online shopping platform, may be a social network, may be a financial credit application, may be music community interaction, It could also be a video uploading and sharing platform…

Essentially, all Web applications are software that runs in a Web browser, with a Graphical User Interface (GUI) as the front end.

Such complex Web applications are often jointly developed and maintained by dozens or hundreds of people, and their front-end interfaces are usually quite large, no less than traditional GUI software:

While increasing the complexity of the Web application, the user puts forward higher requirements on the front-end interface also but today still don’t have much front-end developer will ponder the front-end development from the perspective of software engineering, to help the team’s development efficiency, moreover also on the front kept as simple as toys “” plantation in stereotypes, day after day.

The front-end development with a long history is always like a wild child, so primitive, unavoidable let a person sigh with regret!

There are three phases of front-end engineering

Currently, front-end development is not entirely empty. Looking back at the projects I have experienced or heard about, in order to improve the efficiency and performance of front-end development, the front-end team’s engineering construction generally goes through three stages:

Stage 1: Library/framework selection

The first task of front-end engineering construction is to select the technology according to the characteristics of the project.

Nowadays, no one can build a website from scratch, even for government projects, it is quite normal to use jquery. React/Angularjs and other frameworks have come into being, freeing up a lot of productivity. There is no doubt that proper technology selection can save a lot of work for projects.

Stage 2: Simple build optimization

After the selection, you can basically start to type code, but the development efficiency is not enough to solve the problem, we must take into account the operation performance. In the second phase of front-end engineering, a build tool will be selected to compress and verify the code, and then simple resource merging will be carried out on a page by page basis.

The third stage: JS/CSS modular development

Divide and conquer is an important idea in software engineering and the cornerstone of complex system development and maintenance. It also applies to front-end development. After solving the problem of basic development efficiency and operation efficiency, the front end team began to think about maintenance efficiency. Modularization is the most popular divide-and-conquer method in front end.

Many people think that the engineering significance of modular development is reuse, I do not agree with this view, in my opinion, the greatest value of modular development should be divide and conquer, is divide and conquer, divide and conquer! (Repeat three).

Whether or not you reuse a piece of code in the future, there are good reasons to divide and conquer it into a module.

JS modular scheme a lot, AMD/CommonJS/UMD/ES6 Module, etc., corresponding framework and tools are also a lot, it is very annoying, we own Baidu bar; The modular development of CSS is basically implemented with the support of import/mixin features of preprocessors such as LESS, SASS, and Stylus.

While the technology has a long history, in today’s era of “will and React” slightly outdated, but consider the industry’s most backward engineering team, when we looked around, literally, to reach the front end of the third stage team already belong to the ranks of high-end, basic has the ability to develop maintain general scale Web applications.

But is that enough? Naive!

The fourth stage

The front-end is an area of software development with fewer technical problems and more engineering problems.

When developing a complete Web application, the front end faces more engineering problems, such as:

  • Large volume: multi-function, multi-page, multi-state and multi-system;

  • Large-scale: multi-person or even multi-team development;

  • High performance: CDN deployment, cache control, file fingerprinting, cache reuse, request consolidation, on-demand loading, synchronous/asynchronous loading, CSS embedded in the first screen on the mobile terminal, and HTTP 2.0 server resource push.

These are undoubtedly a series of serious systems engineering problems.

While the previous three phases are a big step up from the “blood and blood” days of the past, the collaborative development and fine-grained performance optimization needed to support the fourth phase seems to be lacking.

What, after all, is missing?

There is no silver bullet

Anyone who has read the Myth of the Man-month has heard that there are no silver bullets in software engineering. Yes, front-end development doesn’t have silver bullets either, but these are the days when there aren’t even ™ buckshot! (Just got a BB, drop)

Front-end has always been known for “simplicity”, in the front-end developer community, the value of small and beautiful occupy the main discourse, even become a kind of belief, want to communicate with others about engineering experience, the response is often two words: too heavy.

Your sister! Do you have a 4K brain?

Engineering solutions can be small and beautiful! Except its small and beautiful does not mean the amount of code, but “rules”. Find the root of the problem, with the least simple and clear rules to develop the most easy to comply with the most easy to understand the development specifications or tools, in order to improve the development efficiency and project quality, this is also a small and beautiful model!

I had the opportunity to participate in FIS project, the front end of the research and development team with baidu many large and medium-sized project cooperation, continuously explore practice front-end development engineering solution, then leave the baidu to UC, faced with a completely different product forms, different business scenarios, different adapter terminals, even different network environment, the methodology of past will still be able to quickly fall to the ground, Tailor-made front-end solutions for different business scenarios for multiple teams.

These experiences taught me one thing:

As we move into phase four, there are only two things we need to do to dramatically improve the efficiency of front-end development, while also maintaining operational performance: componentized development and resource management.

First thing: Componentized development

Divide-and-conquer is indeed a very important engineering optimization tool. In my opinion, the front-end, as a KIND of GUI software, is not enough to have JS/CSS modularity, and there is an equally urgent need for the division and conquer of UI components:

Here’s my belief in front-end componentization:

Each separate visual/interactive area on the page is treated as a component;

Each component corresponds to a project directory, and various resources required by the component are maintained nearby in this directory.

Because components are independent, they can be combined freely between components.

A page is nothing more than a container for components that combine to form a fully functional interface.

When a component is not needed or you want to replace it, you can remove/replace the entire directory.

Which described in the second nearby maintenance principle, is the place where I feel the most engineering value, it provides a good partition for front-end development strategy, every developer will know, their development and maintenance of functional units, the code must exist in the directory, and the corresponding component in the directory can be found on the functional units of all internal logic, style, JS, page structure, it’s all there.

Componentized development has high universality, whether front-end rendering single page application, or back-end template rendering multi-page application, the concept of componentized development can be applied. The HTML part of a component can be a static HTML file, front-end template, or back-end template depending on the type of service:

Different technology selection determines different component packaging and invocation strategies.

Based on this engineering philosophy, it is easy to divide the system into individual components:

Because the system functions are divided into separate modules or components, particle size is fine, the form of the organization is loose, and temporal dependence between developers won’t produce development, improved efficiency of parallel development, theoretically allowing new members to join at any time claim component development or maintenance work, were also more likely to support multiple teams jointly safeguard for the development of a large site.

Combined with the modular development mentioned earlier, the front-end project can be divided into several development concepts:

Based on the above description, for general small and medium-sized projects, the source directory structure can be roughly planned as follows:

If the project is large and involves multiple teams, you can also organize the pages with relevant business functions together to form a subsystem, and further split the whole site into multiple subsystems to be assigned to different teams for maintenance. For this situation, I will write a separate article in detail later.

The above architecture design has been verified by many front-end teams in different business scenarios of different companies, and has gained a good reputation. It is an effective divide-and-conquer solution for front-end engineering.

Second thing: “smart” static resource management

The modular/componentized development mentioned above only describes a development concept, but can also be considered a development specification, and if you agree with the specification and resonate with its divide-and-conquer strategy, then we can move on to its implementation.

Obviously, after modular/componentized development, we have to solve the technical problem of module/component loading. However, there is one big difference between the front-end and client-side GUI software:

The front end is GUI software that is remotely deployed and incrementally downloaded at run time

Procedures required front-end applications without installation process, its resources are deployed on the remote server, the user use the browser to access a different page to load different resources, with the increase of page access, gradually will download the entire program to run locally, “incremental download” is the front-end engineering is different from the root cause of the client GUI software.

The figure above shows an application with various interfaces and rich functions. If it is implemented on the Web, it is believed to be a large volume. If users visit the page for the first time and are forced to load the static resources of the whole site for display, it is believed that there will be many users lost because of losing patience. According to the principle of “increment”, we should carefully plan the resource loading strategy for each page, so that users can load the resources required by the page whenever they visit, and those that have not been accessed need not be loaded, and those that have been accessed can be cached and reused, ultimately bringing a smooth application experience.

This is the beauty of “install free” Web applications.

Front-end optimization techniques derived from the “incremental” principle have almost become the core of performance optimization, including load-related loading on demand, delayed loading, preloading, request merging and other strategies. There are cache-related browser cache utilization, cache update, cache sharing, non-overwriting publishing and other schemes; There are also complex technologies such as BigRender, BigPipe, Quickling, PageCache, etc. All of these optimizations revolve around how to maximize the incremental principle.

So I think:

The most pressing aspect of phase 4 front-end development is implementing the incremental principle in the infrastructure.

We believe that this implementation will not change with the passage of time. In the foreseeable future, no matter in the era of HTTP1.x or HTTP2.0, no matter in the era of ES5 or ES6/7, no matter in the era of AMD/CommonJS/UMD or ES6 Module, no matter how technology changes in the end, We all have good reasons to do incremental loading of front-end resources.

As mentioned earlier, what is missing from phase 3 front-end engineering? I think it is the lack of such an “intelligent” resource loading scheme in its infrastructure. Without such a scheme, it is difficult to develop the scale of front-end application to the fourth stage, it is difficult to implement the componentized development scheme introduced before, and it is difficult to make multiple parties cooperate efficiently to complete the development of a large application and ensure its final performance is good. In phase four, we need strong engineering tools to manage the “toy-simple” front-end development.

In my mind, Facebook is one of the great pioneers in this field, and Dr. David Wei from Facebook has demonstrated their amazing static web resource management and optimization techniques for the industry.

Dr. David Wei mentioned some product data about Facebook at the conference that year:

  • Facebook has more than 10,000 static resources;

  • Each static resource has the potential to be translated into over 100 languages;

  • Each resource generates three different versions for the browser;

  • To do 5 different packaging methods for users with different bandwidth;

  • There are 3 or 4 different user groups for small batches to experience new product features;

  • Different delivery methods should also be considered, such as direct delivery or iframe to improve the speed of parallel resource loading.

  • Static resources can be switched between compressed and uncompressed states for debugging and locating online problems

This is a state explosion problem, and if you multiply all the states together, there are millions of combinations of resources on the site (about 3 million after de-duplication). The underlying architecture that supports such large-scale front-end projects is the Static Resource Management System shared by Dr. Wei in that speech, which is used to solve 3D problems related to front-end engineering in The Facebook project. Deployment, Debugging).

The practice of Facebook undoubtedly shines a bright light for us, but unfortunately it is not open source (not technical blockade, but the system relies on other aspects of THE FB system, so it is not universal and open source is of little significance). We can only try to mine relevant information, and there are still very few complete introductions about it on the Internet. I didn’t get much out of analyzing facebook’s front-end code until I stumbled across Celerity, a static management solution in Phabricator, a project management tool used by Facebook, with a description that looks like a mini version of Facebook’s static Resource Management system.

A simple look at the system shows that the principle is not complicated (a small but beautiful example). It uses a small tool to scan all static resources and generate a resource table. Then a PHP implementation of the resource management framework (Celerity) provides a resource loading interface instead of the traditional script/link static resource loading tags. Resources are eventually loaded by table lookup.

Although WE haven’t really seen the system of FB, the small frame in front of us gave us enough enlightenment at that time:

Static resource management system = Resource table + Resource loading framework

What an elegant implementation!

Resource table is a data file (such as JSON), is the project in all static resources (mainly JS and CSS) build information records, generated by build tools scanning project source code, is a kind of k – v of the structure of the data, with each resource id as the key, recorded the category, the path of deployment of resources, dependencies, packaging, etc

The resource loading framework provides apis for resource reference, allowing developers to reference resources by ID instead of static script/link tags to collect, de-duplicate, and load resources on demand. When these interfaces are invoked, the framework looks up a table to find information about the resource and recursively finds information about the resource it depends on, and in the process we can implement various performance optimization algorithms to “intelligently” load the resource.

Depending on the business scenario, the loading framework can be implemented in JS in a browser, server-side language in a back-end template engine, or even a combination of the two.

This design quickly proved to be flexible enough to perfectly support the performance optimization needs of different teams with different technical specifications, Performance optimizations like on-demand loading, lazy loading, preloading, request merging, file fingerprinting, CDN deployment, Bigpipe, Quickling, BigRender, first-screen CSS embedding, HTTP 2.0 server push and so on can be easily implemented on this architecture. It can even be automatically optimized based on performance logs (something Facebook has already done).

Because of the resource table, we can easily control the resource load, through various means at run time to calculate the resource usage of the page, so as to obtain the best load performance. This works equally well for single-page applications rendered front-end as well as multi-page applications rendered back-end.

In addition, it neatly constrains the build tool’s responsibility to only generate resource tables. Resource list data structure is very general, no matter what the business scenario, ultimately the business code can be scanned to the same table data structure, and mark the dependent relationships between resources, with the list after we need to customize different according to different business scenarios resource loading frame, say goodbye forever in the age of a team to maintain a set of tools!!!!!!

We’ll leave that to the benefits of digging deeper into static resource loading frameworks and being flexible and robust enough for future technological change.

conclusion

Review the three phases of front-end engineering mentioned earlier:

  • Stage 1: Library/framework selection

  • Stage 2: Simple build optimization

  • The third stage: JS/CSS modular development

Now add the fourth stage:

  • The fourth stage: componentized development and resource management

Due to congenital defects, the front-end infrastructure is more urgent than other software development needs componentized development and resource management, and the solution to resource management is not complicated at all:

A general-purpose resource table generation tool + table-based resource loading framework

Most of the resource loading optimizations you’ve heard about in recent years can be implemented on this basis, and the optimizations are completely transparent to the business, without refactoring performance optimizations — isn’t that what we’ve been waiting for? As Dr. Wei Xiaoliang said: We can gather excellent people to optimize loading.

How do you choose technologies, how do you customize specifications, how do you divide and conquer systems, how do you optimize performance, how do you load resources, and when you start to think about that, I want to say:

Hello, engineer!

Follow our official account below for more articles