微前端集成优化:让所有子应用体积更小,加载更快!

简介

随着前端的日益发展,微前端架构越来越受到青睐。它通过将前端应用拆分为多个独立的子应用,每个子应用可以独立开发、部署和运行,从而提升了开发效率和团队协作。目前主流的微前端方案应该是qiankun了。

以笔者公司为例,采用的就是qiankun框架,主应用采用了vue3,子应用五花八门都有。笔者公司前端服务的子应用大约有400多个,后期也会继续增多!因此,如何优化子应用的体积和加载速度,提升用户体验和性能是我们亟待解决的问题!本文将分享我们公司用到的一些优化方案。

优化方案

在代码层的优化,比如按需加载、懒加载、静态资源优化的都是大家熟知的方案了,这里我就展开了。我们主要的优化在打包上,我们减少体积的两大方案主要是:

  • gzip压缩
  • 依赖共享

本文将详细介绍依赖共享,在了解依赖共享前,我们先了解一下普通的项目打包浏览器初次加载需要请求的文件。

项目初次加载需要请求的文件

对于一个没有特殊配置打包项的普通项目,其核心的请求文件如下:

请求文件

作用

资源尺寸

请求时间

0.js

路由页面内容

(prefetch cache)

60 ms

app.js

main.js等非路由页面内容

893 kB

12 ms

chunk-vendors.js

node_modules内容

37.9 MB

427ms

可以看到,影响一个前端服务体积、加载速度的主要文件就是第三方依赖chunk-vendors.js!

优化思路

依赖共享

假设我们有非常多的子应用,每个子应用的nodmodlues依赖打包也是单独的,在请求这个子应用时,这个依赖文件也是必须请求的!

但是,我们很多子应用的第三方依赖都是重复的!比如vue的底层依赖、store的依赖、eslint的依赖及一些常用的工具依赖!

如果每个子应用都打包自己的依赖库,这是非常愚蠢的,会导致重复加载,浪费带宽和资源!如果我们能让这些公用的依赖只加载一次,那么,所有子应用都不需要额外请求这些依赖,打包体积也会非常小,这样自然会极大的提升每个子应用加载速度!

那么,我们如何才能实现依赖共享呢?

外部化依赖

最简单的实现方案就是可以将常用的依赖库)配置为外部依赖,不打包在每个子应用中,而是通过CDN加载,如这样:

为什么能提高加载速度

当我们采用外部依赖的时候,首先所有应用不需要打包nodemodules的依赖,体积上非常小,在请求基础文件时自然会快很多!

当我们加载主应用时,主应用通过CDN的方式请求了vue的底层依赖、一些常用的公共库等所有依赖。当我们加载子应用时,和主应用相同的这些依赖因为已经请求过了,浏览器会通过缓存机制直接读取已经缓存的数据,避免了重新请求,子应用的加载速度也得到了进一步的提升!

技术方案

目前主流框架如vite、webpack的打包工具默认都是将nodemodlues依赖打包成js文件,我们通过一些配置,就可以将打包方式改变,打包成CDN引文的形式。

使用vite-plugin-cdn-import

首先,安装所需的包

npm install vite-plugin-cdn-import --save-dev

然后,创建或编辑你的 vite.config.js 文件,并添加插件配置:

import { defineConfig } from 'vite';
import cdnImport from 'vite-plugin-cdn-import';export default defineConfig({plugins: [cdnImport({imports: [{// 库名,比如 `react`libraryName: 'react',// 库的CDN地址,比如 `https://cdn.jsdelivr.net/npm/react@17.0.1/umd/react.production.min.js`url: 'https://cdn.jsdelivr.net/npm/react@17.0.1/umd/react.production.min.js',// 生产环境是否使用CDNprod: true,// 开发环境是否使用CDNdev: false,},// 可以继续添加其他库的配置...],}),],
});

在上面的配置中,libraryName 是你想要替换的库名,url 是CDN上该库的地址。prod 和 dev 分别指示是否在生产环境和开发环境中使用CDN。

现在,当你运行 Vite 开发服务器或构建你的项目时,所有列在 imports 数组中的依赖项都将通过CDN链接注入到你的代码中。

这种方式的缺点就是,所有依赖都要我们一个个配置,非常麻烦!

借助rollup-plugin-html

要在打包时将所有的 node_modules 依赖以 <script> 标签的形式引入到 HTML 文件中,我们也可以使用 Rollup 的插件,如 rollup-plugin-html 和 rollup-plugin-node-resolve,并结合一些自定义逻辑来生成最终的 HTML 文件。以下是一个具体的实现步骤:

安装必要的插件

经安装了必要的 Rollup 插件:

npm install --save-dev rollup-plugin-html rollup-plugin-node-resolve rollup-plugin-terser

配置 Rollup

接下来,在 rollup.config.js 中配置 Rollup:

import resolve from '@rollup/plugin-node-resolve';
import html from '@rollup/plugin-html';
import { terser } from 'rollup-plugin-terser';
import { defineConfig } from 'rollup';const generateHTML = () => {return {name: 'generate-html',generateBundle(options, bundle) {const scriptTags = Object.keys(bundle).filter(fileName => fileName.endsWith('.js')).map(fileName => `<script src="${fileName}"></script>`).join('\n');const htmlContent = `
<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>My App</title>
</head>
<body>${scriptTags}
</body>
</html>`;this.emitFile({type: 'asset',fileName: 'index.html',source: htmlContent});}};
};export default defineConfig({input: 'src/main.js',output: {dir: 'dist',format: 'esm',entryFileNames: 'static/js/[name]-[hash].js',chunkFileNames: 'static/js/[name]-[hash].js',assetFileNames: 'static/assets/[name]-[hash][extname]'},plugins: [resolve(),terser(),generateHTML()]
});

generateHTML 是一个自定义的 Rollup 插件,用于生成 index.html 文件,并自动插入打包生成的 JavaScript 文件。

    • generateBundle 钩子:在生成包的过程中调用。它通过遍历 bundle 对象中的所有文件,找到以 .js 结尾的文件,并生成相应的 <script> 标签。
    • this.emitFile 方法:用于将生成的 HTML 内容作为一个新文件输出到 dist 目录中。

上述方案中,我们通过generateBundle钩子实现了所有js文件的遍历与cdn链接的生成。这个方法中,html文件是在vite.config.js中写的,然而我们一般可能更倾向于外部引入index.html。

优化方案

此方案只给出大致思路:

  • 借助generateBundle钩子获取所有文件的cdnList
// 借助generateBundle 钩子实现
const cdnList = getCdnList()
  • 使用 createHtmlPlugin 注入数据

使用 vite-plugin-html 提供的 createHtmlPlugin 插件,将 cdnList 作为数据注入到 HTML 模板中:

import { createHtmlPlugin } from 'vite-plugin-html';const packageName = edgeClient ? 'meos-autocontrol-web-edge' : 'meos-control-web';export default defineConfig(({ mode }) => {const plugins = [// ...其他插件createHtmlPlugin({minify: true,inject: {data: {title: packageName,cdnList: cdnList}}}),// ...其他插件];return {// ...其他配置plugins,// ...其他配置};
});
  • 在 index.html 中使用模板语法将 cdnList 渲染到 HTML 中
<!DOCTYPE html>
<html lang="en"><head><meta charset="UTF-8" /><link rel="icon" type="image/svg+xml" href="/vite.svg" /><meta name="viewport" content="width=device-width, initial-scale=1.0" /><meta http-equiv="Content-Security-Policy" /><title><%- title -%></title><% cdnList.forEach(function(cdn) { %> <%- `<script src="${cdn}"></script>` -%> <% }) %></head><body><div id="app"></div><script type="module" src="./src/main.ts"></script></body>
</html>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/878221.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于SpringBoot的在线答疑系统

你好呀&#xff0c;我是计算机专业毕业生&#xff0c;专注于在线教育平台的开发与实现。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;Java技术 Spring Boot框架 工具&#xff1a;IntelliJ IDEA、Navicat、Maven、Tomcat 系统展示 首页 个人中心…

scrapy--图片管道-ImagesPipeline

免责声明:本文仅做演示与分享~ 目录 介绍 ImagesPipeline pipelines.py items.py zz.py settings.py 介绍 scrapy 还提供了处理图片、视频、音频等媒体文件的插件&#xff0c;如&#xff1a; - scrapy-images&#xff1a;用于下载和处理图片 - scrapy-video&#xff1…

责任链设计模式详解

责任链设计模式详解 一、定义 责任链设计模式&#xff08;Chain of Responsibility Pattern&#xff09;是一种行为设计模式&#xff0c;它允许多个对象有机会处理请求&#xff0c;从而避免请求的发送者和接收者之间的耦合。这种模式将这些对象连接成一条链&#xff0c;并沿着…

提前还房贷结果失败了该怎么办?需要注意哪些?怎么做更顺利?

提前还房贷结果失败了&#xff0c;该怎么办&#xff1f; 1. 满足条件再申请&#xff1a;部分银行对提前还款设有一定的条件和限制&#xff0c;例如需要提前预约&#xff0c;对已还款时间和还款金额也有具体的要求。如果借款人未能满足这些条件&#xff0c;提前还款的申请可能会…

【精选】计算机毕业设计之:基于springboot超市进销存系统

博主介绍&#xff1a; ✌我是阿龙&#xff0c;一名专注于Java技术领域的程序员&#xff0c;全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师&#xff0c;我在计算机毕业设计开发方面积累了丰富的经验。同时&#xff0c;我也是掘金、华为云、阿里云、InfoQ等平台…

Stable Diffusion AI绘画工具的安装与配置(MAC用户)

AI绘画的热潮席卷了整个创意行业&#xff0c;Stable Diffusion作为其中的翘楚&#xff0c;让艺术创作变得前所未有的简单。然而&#xff0c;对于使用Mac电脑用户来说&#xff0c;安装和配置Stable Diffusion可能显得有些棘手。别担心&#xff0c;这份详细的教程将手把手教你如何…

【Material-UI】Select 组件中的 `Auto width`、`Small Size` 和 `Other Props` 详解

文章目录 一、Select 组件概述1. 组件介绍2. Select 组件的基本结构 二、Auto width 属性详解1. Auto width 的作用2. Auto width 属性的基本用法3. Auto width 的实际应用场景 三、Small Size 属性详解1. Small Size 的作用2. Small Size 属性的基本用法3. Small Size 的实际应…

Windows怎么让防火墙开放端口

开放端口的方法 先从控制面板,进入到Windows Defender防火墙 点击高级设置,点击入站规则 点击右边的新建规则,点击端口,点击下一步 选择协议类型和端口号点击下一步即可 查看是否开放端口成功的方法: 进入任务管

【rk3588】环境搭建及系统编译

开发板&#xff1a;ROC-RK3588S-PC 官方链接&#xff1a;Welcome to ROC-RK3588S-PC Manual — Firefly Wiki (t-firefly.com) 串口调试配置 一、产品介绍 — Firefly Wiki (t-firefly.com)&#xff0c;可以按照官方链接的说明在个人PC上使用串口。这个串口会输出rk3588的日…

【Python机器学习】NLP词频背后的含义——从词频到主题得分

目录 TF-IDF向量及词形归并 主题向量 一个思想实验 一个主题评分算法 一个LDA分类器 LDiA TF-IDF向量&#xff08;词项频率—逆文档频率向量&#xff09;可以帮助我们估算词在文本块中的重要度&#xff0c;我们使用TF-IDF向量和矩阵可以表明每个词对于文档集合中的一小段…

计算机视觉编程 1(图片处理)

目录 灰色度 缩略图 拷贝粘贴区域 调整图像尺寸 旋转图像45 画图线、描点 灰色度 灰度是指图像中每个像素的亮度值&#xff0c;用来描述图像中各个像素的明暗程度。在计算机视觉中&#xff0c;灰度可以通过以下方式来计算&#xff1a; 1. 平均值法&#xff1a;将图像中每…

Java基础——自学习使用(泛型)

一、泛型的定义 泛型的本质是参数化类型&#xff0c;也就是所操作的数据类型被指定为一个参数。 泛型泛指一切类型&#xff0c;能够代表一切类型&#xff0c;是一种在编程中广泛使用的概念&#xff0c;特别是在面向对象编程中。它允许在编写代码时使用类型参数&#xff0c;这些…

MES管理系统助力印刷企业实现智能化工艺流程

在印刷这一古老而充满活力的行业中&#xff0c;科技的浪潮正以前所未有的速度重塑着每一个生产环节。随着制造业数字化转型的深入&#xff0c;引入MES管理系统&#xff0c;为印刷企业带来了从原材料入库到成品出库的全流程智能化变革&#xff0c;不仅提升了生产效率&#xff0c…

剪辑小白必看:好用的剪辑工具推荐!

作为一位热爱创作的视频制作者&#xff0c;我尝试过不少剪辑软件&#xff0c;今天我想分享自己对福昕视频剪辑、爱拍剪辑、达芬奇和VSDC Video Editor这四款软件的使用体验。 福昕视频剪辑 链接&#xff1a;www.pdf365.cn/foxit-clip/ 我第一次接触到福昕视频剪辑是在朋友的…

树数据结构(Tree Data Structures)的全面指南:深度解析、算法实战与应用案例

树数据结构&#xff08;Tree Data Structures&#xff09;的全面指南&#xff1a;深度解析、算法实战与应用案例 引言 树数据结构&#xff08;Tree Data Structures&#xff09;作为计算机科学中的基石之一&#xff0c;以其独特的层次结构和分支特性&#xff0c;在众多领域发…

2012-2022年各省新质生产力匹配数字经济数据

2012-2022年各省新质生产力匹配数字经济数据 1、时间&#xff1a;2012-2022年 2、来源&#xff1a;各省年鉴、能源年鉴、工业年鉴、统计年鉴 3、指标&#xff1a;prov、year、gdp亿元、在岗职工工资元、第三产业就业比重、人均受教育平均年限、教育经费强度、在校学生结构、…

【STM32】IWDG独立看门狗与WWDG窗口看门狗

本篇博客重点在于标准库函数的理解与使用&#xff0c;搭建一个框架便于快速开发 目录 WDG简介 IWDG IWDG特性 独立看门狗时钟 键寄存器 超时时间 IWDG代码 WWDG WWDG特性 窗口看门狗时钟 超时时间 WWDG时序 WWDG代码 IWDG和WWDG对比 WDG简介 WDG&#xff08;…

面经:什么是Transformer位置编码?

过去的几年里&#xff0c;Transformer大放异彩&#xff0c;在各个领域疯狂上分。它究竟是做什么&#xff0c;面试常考的Transformer位置编码暗藏什么玄机&#xff1f;本文一次性讲解清楚。 Transformer的结构如下&#xff1a; 可能是NLP界出镜率最高的图 Transformer结构中&a…

最大公约数(欧几里得算法)

欧几里得算法 只需要记住一个公式&#xff08;不需要推导&#xff0c;这就是数论的基础知识&#xff09;&#xff1a; step1&#xff1a; 判断小括号内右边的数字 b 是否为0&#xff0c;如果为0&#xff0c;输出小括号左边的数字 a &#xff0c;就是一开始要求的两个数的最大…

深度学习入门笔记

深度学习入门笔记 感知机逻辑与门与非门或门多层感知机异或门 神经网络激活函数输出层设计损失函数均方误差 MSE交叉熵误差 反向传播算法计算图局部计算计算图反向传播反向传播 参数更新训练过程总结 该篇文章为本人学习笔记的一部分。笔记基于《深度学习入门 基于python理论实…