


What should I do if the project is too big? How to split Angular projects reasonably?
AngularThe project is too large, how to split it reasonably? The following article will introduce to you how to reasonably split Angular projects. I hope it will be helpful to you!
One of the criticisms about Angular is that it is very large after being packaged. If you are not careful, main.js
will become ridiculously large. In fact, when you encounter similar problems Whether the problem is large volume, large data, or large traffic, there is only one idea: splitting. Coupled with the browser's caching mechanism, the project access speed can be optimized. [Recommended related tutorials: "angular tutorial"]
The relevant code for this article is at: https://github.com/Vibing/angular-webpack
Split ideas
The entire project includes: strong dependency library (Angular framework itself), UI component library and third-party library, and business code part;
User behavior dimension: all user access is based on routing, one route is one page;
It can be split from the above two points, based on the first You can package strongly dependent libraries and libraries that rarely change into a vendor_library
, which can contain @angular/common
, @angular/core
, @angular/forms
, @angular/router
and other similar packages, UI component libraries or libraries such as lodash
are not recommended to be packaged together, because we need to use TreeShaking, There is no need to package unused code, otherwise it will only increase the size.
Now that the strong dependency package is done, let’s package the business code based on point 2. We use route-based code spliting
for packaging. The idea is very simple. Whichever page the user visits, the js corresponding to the page is downloaded. There is no need to package the unvisited pages together. This will not only increase the size, but also increase the download time, and the user experience will also deteriorate. .
Custom webpack configuration
If we want to use DLL to import strongly dependent packages into a vendor, we must use the webpack function, which is already embedded in Angular CLI webpack, but these configurations are black boxes to us.
Angular allows us to customize webpack configuration, the steps are as follows
Installation
@angular-builders/custom-webpack
and@angular- devkit/build-angular
Create a new webpack.extra.config.ts for webpack configuration
In angular.json Make the following modifications
... "architect": { "build": { "builder": "@angular-builders/custom-webpack:browser", "options": { ... "customWebpackConfig": { // 引用要拓展的 webpack 配置 "path": "./webpack.extra.config.ts", // 是否替换重复插件 "replaceDuplicatePlugins": true } } }, "serve": { "builder": "@angular-builders/custom-webpack:dev-server", "options": { "browserTarget": "angular-webpack:build" } } ...
Use DLL
After you can customize the webpack configuration, create a new webpack.dll.js file to write the DLL configuration:
const path = require("path"); const webpack = require("webpack"); module.exports = { mode: "production", entry: { vendor: [ "@angular/platform-browser", "@angular/platform-browser-dynamic", "@angular/common", "@angular/core", "@angular/forms", "@angular/router" ], }, output: { path: path.resolve(__dirname, "./dll"), filename: "[name].dll.js", library: "[name]_library", }, plugins: [ new webpack.DllPlugin({ context: path.resolve(__dirname, "."), path: path.join(__dirname, "./dll", "[name]-manifest.json"), name: "[name]_library", }), ], };
Then introduce the dll in webpack.extra.config.ts
import * as path from 'path'; import * as webpack from 'webpack'; export default { plugins: [ new webpack.DllReferencePlugin({ manifest: require('./dll/vendor-manifest.json'), context: path.resolve(__dirname, '.'), }) ], } as webpack.Configuration;
Finally add a command to package the dll in package.json: "dll": "rm - rf dll && webpack --config webpack.dll.js"
, after executing npm run dll
, there will be a dll folder at the root of the project, which contains the packaged content:
After the packaging is completed, we need to use vendor.dll.js
in the project and configure it in angular.json
:
"architect": { ... "build": { ... "options": { ... "scripts": [ { "input": "./dll/vendor.dll.js", "inject": true, "bundleName": "vendor_library" } ] } } }
After packaging, you can see that vendor_library.js
has been introduced:
The purpose of DLL is to remove strong dependencies that will not be updated frequently. Packages are packaged and merged into a js file, which is generally used to package the Angular framework itself. When the user visits for the first time, the browser will download vendor_library.js
and cache it. Every subsequent visit will be taken directly from the cache. The browser will only download the js of the business code and will not download the framework. The relevant code greatly improves the application loading speed and improves the user experience.
ps: The hash behind vendor_library will only be changed if the code inside is changed during packaging, otherwise it will not change.
Routing-level CodeSpliting
The DLL has managed the code in the framework. Now let’s see how to implement on-demand loading of routing-level pages in Angular.
Let’s take a break here. How to do routing level code splitting in React or Vue? It's probably like this:
{ path:'/home', component: () => import('./home') }
The home here points to the corresponding component, but this method cannot be used in Angular. The code can only be split in units of modules:
{ path:'/home', loadChild: ()=> import('./home.module').then(m => m.HomeModule) }
Then Use routing in a specific module to access specific components:
import { HomeComponent } from './home.component' { path:'', component: HomeComponent }
Although you cannot import()
the component directly in the router, Angular provides dynamic import of components Function:
@Component({ selector: 'app-home', template: ``, }) export class HomeContainerComponent implements OnInit { constructor( private vcref: ViewContainerRef, private cfr: ComponentFactoryResolver ){} ngOnInit(){ this.loadGreetComponent() } async loadGreetComponent(){ this.vcref.clear(); // 使用 import() 懒加载组件 const { HomeComponent } = await import('./home.component'); let createdComponent = this.vcref.createComponent( this.cfr.resolveComponentFactory(HomeComponent) ); } }
In this way, when routing to access a certain page, as long as the content of the page being accessed uses import() and dynamically imported with the component, wouldn't it be possible to achieve the effect of lazyLoad on the page? ?
答案是可以的。但是这样会有一个大问题:被 lazyLoad 的组件中,其内容仅仅是当前组件的代码,并不包含引用的其他模块中组件的代码。
原因是 Angular 应用由多个模块组成,每个模块中需要的功能可能来自其他模块,比如 A 模块里要用到 table
组件,而 table
需取自于 ng-zorro-antd/table
模块。打包时 Angular 不像 React 或 Vue 可以把当前组件和用到的其他包一起打包,以 React 为例:在 A 组件引入 table 组件,打包时 table 代码会打包到 A 组件中。而 Angular 中,在 A 组件中使用 table 组件时,并且使用 imprt()
对 A 组件进行动态加载,打包出来的 A 组件并不包含 table 的代码, 而是会把 table 代码打包到当前模块中去,如果一个模块中包含多个页面,这么多页面用了不少UI组件,那么打包出来的模块肯定会很大。
那么就没有别的方法了吗?答案是有的,那就是把每个页面拆成一个 module,每个页面所用到的其他模块或组件由当前页面对应的模块所承担。
上图中 dashboard
作为一个模块,其下有两个页面,分别是 monitor
和 welcome
dashboard.module.ts:
import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { RouterModule, Routes } from '@angular/router'; const routes: Routes = [ { path: 'welcome', loadChildren: () => import('./welcome/welcome.module').then((m) => m.WelcomeModule), }, { path: 'monitor', loadChildren: () => import('./monitor/monitor.module').then((m) => m.MonitorModule), }, ]; @NgModule({ imports: [CommonModule, RouterModule.forChild(routes)], exports: [RouterModule], declarations: [], }) export class DashboardModule {}
在模块中使用路由 loadChildren 来 lazyLoad 两个页面模块,现在再看看 WelcomeModule:
import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { WelcomeComponent } from './welcome.component'; import { RouterModule, Routes } from '@angular/router'; const routes: Routes = [ { path: '', component: WelcomeComponent } ]; @NgModule({ declarations: [WelcomeComponent], imports: [RouterModule.forChild(routes), CommonModule] }) export class WelcomeModule {}
就是这么简单,就把页面级的 lazyLoad 完成了。当需要使用外部组件时,比如 table 组件,只要在 imports 引入即可:
import { NzTableModule } from 'ng-zorro-antd/table'; @NgModule({ ... imports: [..., NzTableModule] }) export class WelcomeModule {}
题外话:我更喜欢 React 的拆分方式,举个例子:React 中使用 table 组件,table 组件本身代码量比较大,如果很多页面都使用 table,那么每个页面都会有 table 代码,造成不必要的浪费。所以可以配合 import()
把 table
组件单拉出来,打包时 table
作为单独的 js
被浏览器下载并提供给需要的页面使用,所有页面共享这一份 js
即可。但 Angular 做不到,它无法在模块的 imports
中使用 import()
的模块 。
后续
以上都是对项目代码做了比较合理的拆分,后续会对 Angular 性能上做合理的优化,主要从编译模式、变更检测、ngFor、Worker等角度来阐述。
更多编程相关知识,请访问:编程视频!!
The above is the detailed content of What should I do if the project is too big? How to split Angular projects reasonably?. For more information, please follow other related articles on the PHP Chinese website!

JavaScript is widely used in websites, mobile applications, desktop applications and server-side programming. 1) In website development, JavaScript operates DOM together with HTML and CSS to achieve dynamic effects and supports frameworks such as jQuery and React. 2) Through ReactNative and Ionic, JavaScript is used to develop cross-platform mobile applications. 3) The Electron framework enables JavaScript to build desktop applications. 4) Node.js allows JavaScript to run on the server side and supports high concurrent requests.

Python is more suitable for data science and automation, while JavaScript is more suitable for front-end and full-stack development. 1. Python performs well in data science and machine learning, using libraries such as NumPy and Pandas for data processing and modeling. 2. Python is concise and efficient in automation and scripting. 3. JavaScript is indispensable in front-end development and is used to build dynamic web pages and single-page applications. 4. JavaScript plays a role in back-end development through Node.js and supports full-stack development.

C and C play a vital role in the JavaScript engine, mainly used to implement interpreters and JIT compilers. 1) C is used to parse JavaScript source code and generate an abstract syntax tree. 2) C is responsible for generating and executing bytecode. 3) C implements the JIT compiler, optimizes and compiles hot-spot code at runtime, and significantly improves the execution efficiency of JavaScript.

JavaScript's application in the real world includes front-end and back-end development. 1) Display front-end applications by building a TODO list application, involving DOM operations and event processing. 2) Build RESTfulAPI through Node.js and Express to demonstrate back-end applications.

The main uses of JavaScript in web development include client interaction, form verification and asynchronous communication. 1) Dynamic content update and user interaction through DOM operations; 2) Client verification is carried out before the user submits data to improve the user experience; 3) Refreshless communication with the server is achieved through AJAX technology.

Understanding how JavaScript engine works internally is important to developers because it helps write more efficient code and understand performance bottlenecks and optimization strategies. 1) The engine's workflow includes three stages: parsing, compiling and execution; 2) During the execution process, the engine will perform dynamic optimization, such as inline cache and hidden classes; 3) Best practices include avoiding global variables, optimizing loops, using const and lets, and avoiding excessive use of closures.

Python is more suitable for beginners, with a smooth learning curve and concise syntax; JavaScript is suitable for front-end development, with a steep learning curve and flexible syntax. 1. Python syntax is intuitive and suitable for data science and back-end development. 2. JavaScript is flexible and widely used in front-end and server-side programming.

Python and JavaScript have their own advantages and disadvantages in terms of community, libraries and resources. 1) The Python community is friendly and suitable for beginners, but the front-end development resources are not as rich as JavaScript. 2) Python is powerful in data science and machine learning libraries, while JavaScript is better in front-end development libraries and frameworks. 3) Both have rich learning resources, but Python is suitable for starting with official documents, while JavaScript is better with MDNWebDocs. The choice should be based on project needs and personal interests.


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

Video Face Swap
Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Article

Hot Tools

SecLists
SecLists is the ultimate security tester's companion. It is a collection of various types of lists that are frequently used during security assessments, all in one place. SecLists helps make security testing more efficient and productive by conveniently providing all the lists a security tester might need. List types include usernames, passwords, URLs, fuzzing payloads, sensitive data patterns, web shells, and more. The tester can simply pull this repository onto a new test machine and he will have access to every type of list he needs.

DVWA
Damn Vulnerable Web App (DVWA) is a PHP/MySQL web application that is very vulnerable. Its main goals are to be an aid for security professionals to test their skills and tools in a legal environment, to help web developers better understand the process of securing web applications, and to help teachers/students teach/learn in a classroom environment Web application security. The goal of DVWA is to practice some of the most common web vulnerabilities through a simple and straightforward interface, with varying degrees of difficulty. Please note that this software

SAP NetWeaver Server Adapter for Eclipse
Integrate Eclipse with SAP NetWeaver application server.

MinGW - Minimalist GNU for Windows
This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

Safe Exam Browser
Safe Exam Browser is a secure browser environment for taking online exams securely. This software turns any computer into a secure workstation. It controls access to any utility and prevents students from using unauthorized resources.