Module Federation: It means module federation, which became popular in webpack 5 and also belongs to a micro front-end solution.
1. Background
1. High-frequency work scenarios of customer service
Front -line customer service: Based on the online workbench and telephone workbench in the one-stop workbench, according to the user's feedback on the line, view the work order details or order details related to the current user, and decide whether to create a new work order according to the actual situation.
Second-line customer service: According to the work order feedback from various channels ( one of the main sources is the feedback from the first-line customer service ), according to the content of the work order, contact the user or other relevant parties to communicate and process and complete the work order.
2. Use the background of the iframe
In the above scenario we can know:
- First-line customer service and second-line customer service are not the same group of students, but belong to different departments;
- Due to some differences in business, IM and work order are two different front-end projects, which are also developed and maintained by different front-end students;
- Even if the micro frontend is used for splitting, IM, phone and work order belong to different micro-applications, and the work order page cannot be directly introduced into the work order details page in the IM and phone sub-applications
Before the transformation, the work order details pages used in the IM and phone workbenches were all nested using iframes , which was the easiest and most compatible solution in the early stage.
2. Existing problems
1. The expansion of the iframe problem
We know that a single iframe occupies more memory and is slow to open . When it is only used occasionally, these may not be a big problem, but there are such scenarios in front-line customer service that will greatly expand these problems, as follows:
- During the dialogue between the front-line customer service and a single user, open multiple work order details or order details of the user
- Front-line customer service docking with multiple users for consultation
- Front-line customer service frequently and quickly switch between different users and different work orders/order details
- Because the customer service has requirements for the response of switching between different sessions, the IM side caches different session pages (such as keep-alive)
This will lead to a sharp increase in memory consumption, slow switching response, and even browser crashes, poor customer service experience , and ultimately reduced customer service performance .
2. Memory keeps increasing
Simulate the user to open a new customer's message in IM, click to create a work order, click the work order details, and then open a new customer message to repeat the above actions. The trend graph of the number of page documents, memory usage and number of page nodes is as follows:
Due to the existence of the page cache, it can be seen that the memory occupancy is getting higher and higher, from more than 100 MB to more than 500 MB in more than a minute , and it can be judged that when the user performs such operations, the memory occupancy will be Continues to go higher, although in most cases the browser's garbage collection mechanism will kick in, but due to:
- Page-level caching makes garbage collection less effective
- Under the long-term work of customer service, the memory will continue to rise
In the end, the application will become slower and slower, and even cause a crash, and there are already some customer service feedback about the crash:
3. Slow response
First look at the video that opens the details of the work order, as follows:
It takes 2.8 seconds to open the work order details in the video, not the first screen, and even 7s when the first screen is opened!
Note: The data here and later are collected in the test environment. Since it is a new tab page implemented internally, it cannot be used for LCP (Largest Contentful Paint, maximum content rendering), TTI (Time to Interactive, interactive time), etc. Very good collection, mainly based on the time data in the screenshots in the Google performance tool, the value is closer to the TTI.
3. Model selection and corresponding strategies
According to the current situation, it is no longer possible to continue to use iframes, so what solutions can meet our current situation? First of all, we sort out our current demands, which mainly have two aspects:
- On the one hand, of course, it is to solve the above problems, improve performance, and improve customer service experience.
- On the other hand, it needs to be friendly enough to the front-end, achievable, and compatible, while maintaining the current low-cost maintenance of the front-end.
There are about two common solutions in front of us, npm package and micro-frontend represented by qiankun
Program | performance | maintain |
---|---|---|
npm | Well, no different from native components, performance is the best | Poor, once the work order is released, IM has to follow the release, which is unacceptable |
micro frontend | better | Well, the project is decoupled, and the IM side does not need to care about the iterations and specific technologies of the work order side. |
1. Is npm package suitable?
Let's take a look at the page itself that we need to reference, as shown in the following figure:
It is a three-level page-level component with high complexity, high business relevance, and high update frequency. It is completely unsuitable for making low-frequency npm packages.
2. Is the micro front end suitable?
You may think that I want to choose a micro-frontend solution based on qiankun, but it is not, because qiankun or other similar micro-frontend solutions also have some problems in our specific scenarios:
2.1, the support for nested scenes is not high
In the overall solution of our one-stop workbench, qiankun has been used to split the work order, IM, and phone into three sub-applications. If IM refers to the work order sub-application, it will form a nesting between applications, as shown in the following figure :
Search for micro-frontend nesting solutions:
- There is no official support for nesting schemes in the community: qiankun micro-front-end practice summary (2) - This article from Nuggets describes the nesting scheme. It can be seen that although there is no official recommended scheme, the community already has relevant practices, but the degree of support Not good enough, and these practices are based on building on webpack;
- qiankun is not friendly to vite: see the issue and want to ask if it will consider supporting vite in the future · Issue #1257 · umijs/qiankun , only recently has the support for vite been slowly added.
Conclusion : Whether it is webpack or vite, micro-frontends with sandbox isolation as the main solution are not well supported in nested scenarios , and if there are more, deeper, or even loop nesting situations in the future, it will be more tricky .
2.2, the scene is not suitable
The micro-frontend solution with sandbox isolation will still reference and parse and load the files required for the initialization of the project itself every time it is referenced. Even if you reference a small component, it will do so, which will still affect the speed of component loading. So it mainly solves the reference, isolation and performance problems in the project dimension . Not suitable in the case of module or component dimension, it is still a bit heavy.
So is there such a solution, which can be as smart as the npm package, only load the corresponding component code, and can be directly referenced like a micro-frontend, regardless of the project, the answer is yes, that is the protagonist of this time - Module Federation (Module Federation).
4. Module Federation module federation
Module Federation, which was first popularized in webpack 5, can be seen in the documentation: Module Federation | webpack Chinese documentation , and it also belongs to a micro-frontend solution.
1. We pay attention to what it can do
I think it can be summed up in one sentence: it allows an online deployed project to load components from other online deployed projects at runtime .
The key points are as follows:
- It has no sandbox isolation scheme and shares a window environment with the host environment
- Load only the target component and its associated content
- There is no need to change the location or structure of the component or page in the previous project directory, and it can be directly referenced according to the corresponding directory level
- It is used in the same way as the components of this project, because it is a component, just loaded remotely
2. Basic principles
Imagine that some subsequently loaded modules can be packaged into chunk packages in webpack, and then lazy loaded when the module is used, usually in the same project.
So can we also package a component and its dependencies into a chunk package in project A, and asynchronously import the chunk package of project A just now in project B according to the agreed address, and run it? The answer is Module Federation.
2.1, some concepts
- The remote component provider is called the remote side, and the remote component consumer is called the host side.
- A project can be either the remote side or the host side, it can use components from several different other projects, or it can provide different components for several other projects.
Based on this, we can even create a decentralized application cluster, roughly like this:
2.2. Community application
And this technology has been applied in several well-known manufacturers:
- Explore the application of module federation, a new feature of webpack5, in Tencent documents - Nuggets (Tencent)
- The most comprehensive summary of micro-front-end knowledge and actual combat (EMP technical solution) - Nuggets (YY)
2.3. Module Federation scheme in vite
The vite plugin vite-plugin-federation provides the ability to benchmark webpack, but the loading method is changed to ESM, and its plug-in interface design is almost the same as the parameter design of webpack. vite-plugin-federation is also a plugin officially recommended and included by vite, which has been included in the community plugin list GitHub - vitejs/awesome-vite: ⚡️ A curated list of awesome things related to Vite.js .
2.4, specific to our scene
The work order workbench application, as a remote terminal , can provide work order details, order details and multiple page-level components such as work order creation and payment modules.
IM or phone workbench applications, as the host side , can use the above components.
3. Specific practice
Since both of our projects are using the vue3 + vite scheme, using the vite-plugin-federation plugin is our best choice. First, you need to install plugins on the host side and remote side, with the following commands:
yarn add @originjs/vite-plugin-federation -D
Note: The official plug-in is used here for the convenience of display. In fact, due to project-related reasons, we have made some changes to the official plug-in.
3.1. Work order workbench as remote configuration
(1) Register the components that need to be provided in the plugin
And provide third-party dependencies that need to be shared
(2) Package after configuration is complete
After packaging on the remote side, the corresponding entry file, chunk file and dependency package file will be generated:
3.2, IM and telephone workbench as the configuration of the host side
(1) Plug-in configuration, set the remote package address
(2) Referencing and registering components , the main.ts file is as follows
At this time, it should be noted that ticket-share is the package name registered in the vite plugin on the host side, and Detail is the component name declared by the remote side exposed (exposes field). In addition to being registered globally, it can also be referenced anywhere that needs to be referenced.
(3) Use of components
Introduce and use where needed, and pass props according to business conditions. The use of props is no different from ordinary components.
At this point, we have completed all the configuration, and then we only need to package it and run it online.
Fifth, the effect after reconstruction
1. Loading speed
Another video
You can compare it with the first video, and you can see a very intuitive difference.
above the fold | Secondary (below the fold) | |
---|---|---|
iframe | 7076ms | 2594ms |
module federation | 1279ms | 428ms |
Note: The above data is obtained by averaging ten times in the test environment, and the test value is closer to the TTI.
As can be seen from the data, the module federation loading speed is increased by 5.5 times in the above-the-fold environment (that is, without any cache). In the secondary loading scene (this scene is the scene most frequently used by customer service), the speed is increased by 6 times!
2. Memory
We still simulate the situation where the customer service opens multiple work orders/order details for multiple users according to the starting scenario. As shown in the figure above, we can first find:
- No memory leaks!
- The memory usage in the same period of time only reached a maximum of 55MB, and fell back.
- Single ticket details open memory increase reduced from 10MB to less than 1MB.
Because in addition to the direct benefits brought by the module federation, we also enjoy its additional benefits. Since the module federation itself refers to a component, we can reuse the same instance for multiple work order details using the characteristics of the vue component itself!
3. Customer service feedback
After going online, we have never received any negative feedback , such as slow opening of ticket details, or feedback that the browser crashes!
6. Follow-up planning
1. Disadvantages of module federation: maintaining shared libraries
It is not without any shortcomings. During the configuration process, we can see that the share field needs to be configured , that is, the three-party library that different projects need to share. For example, project A uses vue, and project B also uses vue, then we need to declare vue, plug-ins Vue will be automatically split, so that A and B projects can be shared and used. It needs to be declared on both the remote side and the host side. The declaration is as follows:
shared: {
vue: {
// remote端该字段为requiredVersion
version: '3.1.5'
},
axios: {
version: '0.21.1'
},
vuex: {
version: '4.0.0'
},
'vue-router': {
version: '4.0.8'
}
}
However, there are very unfriendly points for developers here:
- You need to manually find out the packages shared by the components
- Sharing is sometimes mandatory. If some packages are missed, it may cause the page to report an error or crash. Imagine that the page has two vues at the same time.
- The same library sometimes needs to be maintained within the agreed version range, and sometimes a package that is too old or too new will report an error when loading
In short, the maintenance cost of the shared package is huge!
2. Solutions
- Need to create daily and production build time hooks
- Then the self-built service listens to these hooks, compares the package differences and version differences of the third-party libraries, and throws corresponding warnings
- Introduce inspection, check the remote module part after the build is complete, because not every change will make the test return, but every change may cause the page to crash.
- The plugin is further encapsulated, so that developers do not need to care about the management of third-party dependencies.
3. Conflicts with the release of de-applied assets
- Since the release of assets naturally requires the introduction of a version number, the address of all resources in each iteration will be brought in the version number
- The remote component reference needs to determine the entry file address of a remote side by convention, which is basically fixed
Therefore, at present, remote-side projects cannot be released using assets. Next, it can be replaced by an interface, and the second is to negotiate between teams to deal with this problem.
4. Imagination in a larger direction
Remember the picture "Can build a decentralized application cluster"? References to components not only appear within the team, but may also be shared between teams. For example, the module that creates a work order will be referenced by teams such as intelligence systems.
That is to say, the components or modules that reference each other between teams or within teams, which are mainly solved by iframe at present, can be solved by module federation.
There can also be such a platform within the company, which integrates module federation teams, business module display management, shared dependency package verification, warning or automatic patching and other functions to achieve efficient collaboration inside and outside the business-level team.
Further reading:
【1】 https://juejin.cn/post/6856569463950639117#heading-29
[2] https://github.com/umijs/qiankun/issues/1257 \
[3] https://webpack.docschina.org/concepts/module-federation/#root
【4】 https://juejin.cn/post/6844904127596593160
【5】 https://juejin.cn/post/6911496724938752007
[6] https://github.com/vitejs/awesome-vite#plugins
[7] https://github.com/vitejs/awesome-vite#plugins
Text / LIUZHOUCHANG
Pay attention to Dewu Technology and be the most fashionable technical person!
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。