Vue 项目中 CDN 引入的利弊及解决方案

在Vue项目中,引入到工程中的所有js、css文件,编译时都会被打包进vendor.js,浏览器在加载该文件之后才能开始显示首屏。若是引入的库众多,那么vendor.js文件体积将会相当的大,影响首屏的体验。通过调试发送时间主要消耗在下载文件上,服务器的带宽本来就小,而下载一个vendors.js差不多3M多,占用了主要的时间。于是,使用了CDN加速方式,将依赖的组件从vendors.js中拆分出来,加快vendors.js文件的下载速度,同时通过CDN加载依赖资源也减少对服务器带宽的占用。优化后,首页加载速度在4s左右,但这个过程却遇到了依赖组件使用上的一些问题。

我们为了减少打包体积和缩短打包时间,选择通过 CDN(内容分发网络)引入一些常用的第三方库,如 Vue、Lodash、Element-UI 等。然而,这种引入方式也存在一定的风险,例如 CDN 服务的稳定性问题。一旦所依赖的 CDN 服务出现故障或不可用,项目将无法正常加载这些关键库,从而导致整个应用无法正常运行。

一、CDN 引入的优势

1、减少打包体积

在使用 npm 安装第三方库时,这些库会被打包到最终的构建文件中,导致构建文件体积增大。而通过 CDN 引入,这些库不会被打包到构建文件中,从而显著减少了打包后的文件体积。例如,对于一些大型库如 Element-UI,其打包后的体积可能相当可观,通过 CDN 引入可以有效减轻打包负担。

2、缩短打包时间

由于不需要将第三方库打包到构建文件中,Webpack 等打包工具在打包过程中可以节省大量的时间和资源。这在大型项目中尤为明显,能够显著提高开发效率,减少每次构建的等待时间。

3、提高加载速度

CDN 服务通常在全球范围内分布了多个节点,能够根据用户的地理位置自动选择最近的节点进行资源加载。相比本地服务器,CDN 的加载速度通常更快,尤其是在用户与服务器距离较远的情况下。此外,CDN 服务通常会进行资源的缓存和优化,进一步提升加载性能。

4、减少服务器负载

将静态资源托管在 CDN 上可以减轻你的服务器负载,特别是对于访问量大的网站。

5、跨域问题

使用 CDN 可以避免跨域资源共享(CORS)问题,因为资源直接从 CDN 服务器加载。

二、CDN 引入的潜在风险

1、CDN 服务不可用

CDN 服务的稳定性是影响项目正常运行的关键因素。如果 CDN 服务提供商出现故障、网络问题或被某些地区屏蔽,项目将无法加载所需的第三方库。例如,某些地区的网络环境可能无法访问国外的 CDN 服务,导致项目加载失败。

2、版本不一致问题

在项目开发过程中,可能会因为 CDN 链接中的版本号不明确而导致加载的库版本与项目依赖的版本不一致。这可能会引发兼容性问题,导致项目运行异常。例如,Element-UI 的不同版本可能存在 API 差异,如果加载了错误的版本,可能会导致组件无法正常渲染或功能异常。

3、安全性问题

通过 CDN 引入外部资源时,可能会面临一些安全风险,如中间人攻击、恶意代码注入等。如果 CDN 服务被攻击或篡改,可能会导致项目加载到恶意代码,从而对用户数据和应用安全造成威胁。

三、解决方案

1、使用多个 CDN 服务

为了避免单一 CDN 服务不可用导致的问题,可以在项目中同时使用多个可靠的 CDN 服务。例如,可以同时使用 jsDelivr、CDNJS 和 BootCDN 等服务。在加载资源时,可以先尝试加载主 CDN 的资源,如果加载失败,则自动切换到备用 CDN。以下是一个示例代码:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Vue App</title><script>function loadScript(src, callback) {const script = document.createElement("script");script.src = src;script.onload = callback;script.onerror = () => {console.error(`Failed to load script from ${src}`);// 尝试加载备用 CDNif (src.includes("cdn.jsdelivr.net")) {loadScript("https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.14/vue.min.js", callback);} else if (src.includes("cdnjs.cloudflare.com")) {loadScript("https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.min.js", callback);}};document.head.appendChild(script);}</script>
</head>
<body><div id="app"><h1>{{ message }}</h1></div><script>loadScript("https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.min.js", () => {new Vue({el: "#app",data: {message: "Hello Vue!"}});});</script>
</body>
</html>

2、本地备份方案

为了进一步提高项目的可靠性,可以为关键的第三方库提供本地备份方案。在项目中同时提供 CDN 链接和本地文件路径,当 CDN 加载失败时,自动切换到本地资源。以下是一个示例代码:

<!DOCTYPE html>
<html lang="en">
<head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Vue App</title><script>function loadScript(src, fallbackSrc, callback) {const script = document.createElement("script");script.src = src;script.onload = callback;script.onerror = () => {console.error(`Failed to load script from ${src}`);// 尝试加载本地备份loadScript(fallbackSrc, null, callback);};document.head.appendChild(script);}</script>
</head>
<body><div id="app"><h1>{{ message }}</h1></div><script>loadScript("https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.min.js","/path/to/local/vue.min.js",() => {new Vue({el: "#app",data: {message: "Hello Vue!"}});});</script>
</body>
</html>

3、本地缓存

在本地项目中缓存 CDN 资源,例如使用 npm 的 file-loader 或 copy-webpack-plugin 将 CDN 资源下载到本地项目中。这样,即使 CDN 不可用,项目仍然可以正常运行

// 使用 webpack 的 copy-webpack-plugin 示例
const CopyWebpackPlugin = require('copy-webpack-plugin');module.exports = {plugins: [new CopyWebpackPlugin({patterns: [{ from: 'node_modules/some-library/dist', to: 'libs/some-library' }]})]
};

4、版本锁定

明确指定 CDN 资源的版本号,确保项目在不同环境中的一致性。例如,使用 JSDelivr 的 URL 时,可以指定版本号:

<script src="https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.min.js"></script>

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

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

相关文章

UE5以插件的形式加载第三方库

之前在UE中加载第三方库的形式是以静态或者动态链接的形式加载但是不太容易复用。就想着能不能以插件的形式加载第三方库&#xff0c;这样直接把插件打包发行就可以复用了&#xff0c;之前也找过相应的教程但是很难找到比较简单易懂的教程&#xff0c;要么是比较复杂&#xff0…

Go执行当前package下的所有方法

需求&#xff1a;需要一个文件一个定时任务方法&#xff0c;当项目初始化完毕后&#xff0c;自动加载并执行这些定时任务方法 项目目录架构 main.go 初始化 package mainimport ("sql_demo/schedule" )func main() {/***** 其他初始化完毕后的操作**/// 定时任务sc…

AnyAnomaly: 基于大型视觉语言模型的零样本可定制视频异常检测

文章目录 速览摘要1. 引言2. 相关工作视频异常检测大型视觉语言模型&#xff08;LVLMs&#xff09; 3. 方法3.1. 总览3.2. 关键帧选择模块3.3. 上下文生成基于 WinCLIP 的注意力机制网格图像生成 3.4. 异常检测提示词设计异常评分 4. 实验4.1. 数据集4.2. 评估标准4.3. 结果4.4…

【AWS入门】2025 AWS亚马逊云科技账户注册指南

【AWS入门】2025 AWS亚马逊云科技账户注册指南 A Guide To Register a New account on AWS By JacksonML 0. AWS亚马逊云科技简介 Amazon Web Service(AWS) 即亚马逊云科技&#xff0c;其在全球Cloud Computing(云计算)市场占有最为重要的地位。 AWS连续13年被Gartner评为…

Spring 中 SmartInitializingSingleton 的作用和示例

一、 接口定义 SmartInitializingSingleton 是 Spring 框架提供的一个 单例 Bean 全局初始化回调接口&#xff0c;用于在 所有非延迟单例 Bean 初始化完成后 执行自定义逻辑。 核心方法&#xff1a; public interface SmartInitializingSingleton {void afterSingletonsInsta…

element tree树形结构默认展开全部

背景&#xff1a; el-tree树形结构&#xff0c;默认展开全部&#xff0c;使用属性default-expand-all【是否默认展开所有节点】&#xff1b;默认展开一级&#xff0c;设置default-expanded-keys【默认展开的节点的 key 的数组】属性值为数组。 因为我这里的数据第一级是四川【省…

大数据-spark3.5安装部署之local模式

spark&#xff0c;一个数据处理框架和计算引擎。 下载 local模式即本地模式&#xff0c;就是不需要任何其他节点资源就可以在本地执行spark代码的环境。用于练习演示。 上传解压 使用PortX将文件上传至/opt 进入/opt目录&#xff0c;创建目录module&#xff0c;解压文件至/o…

Discuz建站教程之论坛头部logo跳转链接怎么修改?

在修改头部logo跳转链接前&#xff0c;我们需要知道对应代码在哪个文件目录&#xff0c;进入宝塔或是服务器&#xff0c;找到文件&#xff1a;\template\default\common\header.htm&#xff0c;编辑器打开&#xff0c;搜索以下代码&#xff0c;大概在135行 <a href"{i…

【FreeRTOS】FreeRTOS操作系统在嵌入式单片机上裸机移植

目录 一 RTOS概述 二 FreeRTOS移植 三 FreeRTOS使用 四 附录 一 RTOS概述 先了解一些基础概念,以下内容摘自FreeRTOS官网(FreeRTOS™ - FreeRTOS™): 【1】RTOS基础知识 实时操作系统 (RTOS) 是一种体积小巧、确定性强的计算机操作系统。 RTOS 通常用于需要在严格时间限…

编译支持 RKmpp 和 RGA 的 ffmpeg 源码

一、前言 RK3588 支持VPU硬件解码&#xff0c;需要rkmpp进行调用&#xff1b;支持2D图像加速&#xff0c;需要 RGA 进行调用。 这两个库均能通过 ffmpeg-rockchip 进行间接调用&#xff0c;编译时需要开启对应的功能。 二、依赖安装 编译ffmpeg前需要编译 rkmpp 和 RGA&#xf…

深度学习基础:线性代数本质2——线性组合、张成的空间与基

目录 一、线性组合 1. 用一个有趣的角度看向量坐标 2. 如果我们选择不同的基向量会怎样&#xff1f; 3. 线性组合 4. 张成的空间 ① 二维向量的张成的空间 ② 三维向量的张成的空间​编辑 5.线性相关 6.线性无关 7. 基的定义 一、线性组合 1. 用一个有趣的角度看向量坐…

openharmony5.0中HDF驱动框架源码梳理-服务管理接口

要想大概了解一个公司&#xff0c;我们可能只需要知道它的运行逻辑即可&#xff0c;例如我们只需要知道它有财务有研发有运营等&#xff0c;财务报销、研发负责产品等即可&#xff0c;但是如果想深入具体的了解的话我们就要了解都有什么部门(对象)、各部门都包含哪些职责(对象方…

Go语言环境搭建并执行第一个Go程序

目录 一、Windows环境搭建 二、vscode安装插件 三、运行第一个go程序 一、Windows环境搭建 下载Go&#xff1a;All releases - The Go Programming Language 这里是Windows搭建&#xff0c;选择的是windows-amd64.msi&#xff0c;也可以选择zip直接解压缩到指定目录 选择msi…

Netty基础—4.NIO的使用简介一

大纲 1.Buffer缓冲区 2.Channel通道 3.BIO编程 4.伪异步IO编程 5.改造程序以支持长连接 6.NIO三大核心组件 7.NIO服务端的创建流程 8.NIO客户端的创建流程 9.NIO优点总结 10.NIO问题总结 1.Buffer缓冲区 (1)Buffer缓冲区的作用 (2)Buffer缓冲区的4个核心概念 (3)使…

linux 命令 tail

tail 是 Linux 中用于查看文件末尾内容的命令&#xff0c;常用于日志监控和大文件快速浏览。以下是其核心用法及常见选项&#xff1a; 基本语法 tail [选项] 文件名 常用选项 显示末尾行数 -n <行数> 或 --lines<行数> 指定显示文件的最后若干行&#xff08;…

网络华为HCIA+HCIP数据链路层协议-以太网协议

以太网协议 以太网是当今现有局域网(Local Area Network,LAN)采用的最通用的通信协议标准&#xff0c;该标准定义了在局域网中采用的电缆类型和信号处理方法。以太网是建立在CSMA/CD(Carrier Sense Multiple Access/Collision Detection,载波监听多路访问/冲突检测)机制上的广…

缓存id路由页面返回,历史路由栈

功能需求 网页端需要做页面数据缓存&#xff08;vue动态路由数据缓存&#xff09;&#xff0c;可根据id值打开多个编辑详情页&#xff0c;需要在页面操作返回时关闭面包屑页签 隐藏问题 1.页面缓存会有初始化和组件激活访问生命周期调用数据接口过多&#xff0c;有性能损耗 2.使…

mingw工具源码编译

ming-w64 mingw编译生成的库&#xff0c;需要mingw的lib文件支持。 https://github.com/mingw-w64/mingw-w64 使用msys2的bash git checkout v8.0.3 ./configure --disable-dependency-tracking --targetx86_64-w64-mingw32 mingw32-make.exe -j4 修改makefile中的make 改成mi…

使用OpenCV和MediaPipe库——抽烟检测(姿态监控)

目录 抽烟检测的运用 1. 安全监控 (1) 公共场所禁烟监管 (2) 工业安全 2. 智能城市与执法 (1) 城市违章吸烟检测 (2) 无人值守管理 3. 健康管理与医疗 (1) 吸烟习惯分析 (2) 远程监护 4. AI 监控与商业分析 (1) 保险行业 (2) 商场营销 5. 技术实现 (1) 计算机视…

大数据学习(66)- CDH管理平台

&#x1f34b;&#x1f34b;大数据学习&#x1f34b;&#x1f34b; &#x1f525;系列专栏&#xff1a; &#x1f451;哲学语录: 用力所能及&#xff0c;改变世界。 &#x1f496;如果觉得博主的文章还不错的话&#xff0c;请点赞&#x1f44d;收藏⭐️留言&#x1f4dd;支持一…