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.mzph.cn/diannao/73380.shtml

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

相关文章

拥有一台云服务器能做什么呢?

拥有一台云服务器就像拥有了一台24小时在线的远程电脑&#xff0c;你可以通过互联网随时随地管理它。它的用途非常广泛&#xff0c;无论是个人学习、开发测试&#xff0c;还是企业级应用部署&#xff0c;都能发挥重要作用。以下是常见的应用场景&#xff0c;按需求分类整理&…

PHP 在 if 判断时由于运算符优先级导致 false 的问题

首先来看一段代码&#xff1a; $price 187.50;if (!is_numeric($price) || $price < 0 || ($price * 100 > 1000000)) {echo "价格错误&#xff1a;$price\n"; } else {echo "价格正确&#xff1a;$price\n"; }乍一看是不是认为并没有什么问题&…

从零基础到能独立设计单片机产品,一般需要经历哪些学习阶段?

相信很多人&#xff0c;内心都有“钢铁侠”的幻想&#xff0c;成为能写程序&#xff0c;能设计硬件&#xff0c;能设计结构&#xff0c;能焊接的全能型人才。 上次徐工问我&#xff0c;如果你财富自由了&#xff0c;想去做啥&#xff1f; 我说出来&#xff0c;可能大家都不信&a…

Liunx启动kafka并解决kafka时不时挂掉的问题

kafka启动步骤 先启动zookeeper&#xff0c;启动命令如下 nohup ./zookeeper-server-start.sh /home/kafka/kafka/config/zookeeper.properties > /home/kafka/kafka/zookeeper.log 2>&1 &再启动kafka&#xff0c;启动命令如下 nohup ./kafka-server-start.sh…

使用STM32CubeMX配置定时器中断实现LED每秒闪烁一次(STM32G070CBT6)

说明&#xff1a; 本案例采用的定时器3&#xff08;TIM3&#xff09;实现&#xff0c;使用其他定时器是一样配置。 如何新建一个工程以及如何配置LED的端口&#xff0c;请查看前面文章&#xff1a;使用STM32CubeMX实现LED灯每秒闪烁一次&#xff08;STM32G070CBT6单片机&…

暴力破解Excel受保护的单元格密码

暴力破解Excel受保护的单元格密码 分享一个暴力破解Excel受保护的单元格密码的方法 第一步 在Excel中按下Alt F11&#xff0c;打开Visual Basic for Applications&#xff08;VBA&#xff09;编辑器。 第二步 在VBA编辑器中&#xff0c;点击插入菜单&#xff0c;选择模块…

Git常用操作之GitLab

Git常用操作之GitLab 小薛博客官网&#xff1a;小薛博客Git常用操作之GitLab官方地址 1、GitLab安装 https://gitlab.cn/install/ 1、Docker安装GitLab https://docs.gitlab.cn/jh/install/docker.html 1、设置卷位置 在设置其他所有内容之前&#xff0c;请配置一个新的…

pgsql创建新用户并赋只读权限

在 PostgreSQL 中&#xff0c;为新用户赋予只读权限的步骤如下&#xff1a; —### 1. 创建新用户首先&#xff0c;创建一个新用户&#xff08;角色&#xff09;&#xff0c;并设置密码&#xff1a;sqlCREATE ROLE 用户名 WITH LOGIN PASSWORD 密码;例如&#xff1a;sqlCREATE R…

数据结构与算法——算法3 面试常用排序算法

首先了解排序算法性能和优缺点 然后了解快排 和堆排序的方法。 可以参考如下的博客 八大排序(超详解附动图源码)

linux root丢失修改密

在RHEL7下重置密码 第一种方式&#xff1a;光驱进入急救模式 //做之前最好 selinuxdisabled Conntinue 然后chroot /mnt/sysimag 然后编辑/etc/shadow文件 第二种方式&#xff1a; 1&#xff1a;编辑启动菜单按e,找到linux16行&#xff0c;在行尾加入 init/bin/sh,同时在…

数据类设计_图片类设计之3_半规则图类设计(前端架构基础)

前言 学的东西多了,要想办法用出来.C和C是偏向底层的语言,直接与数据打交道.尝试做一些和数据方面相关的内容 引入 接续上一篇讨论半规则图类型的设计 半规则图的定义 什么是半规则图?笔者看见了一些似乎规则又不是太规则的图形,例如带圆角的矩阵,在页面上找一个圆角框 为了…

Qt 信号与槽机制

1. 信号 和 槽 Qt 信号与槽机制 是一种用于对象间通信的低耦合设计模式&#xff0c;核心思想是&#xff1a;当某个信号触发&#xff0c;自动调用预先关联的处理函数&#xff08;槽函数&#xff09;。 在 Qt 中&#xff0c;如果一个类需要使用信号与槽机制&#xff0c;则该类必…

实验8 搜索技术

实验8 搜索技术 一、实验目的 &#xff08;1&#xff09;掌握搜索技术的相关理论&#xff0c;能根据实际情况选取合适的搜索方法&#xff1b; &#xff08;2&#xff09;进一步熟悉盲目搜索技术&#xff0c;掌握其在搜索过程中的优缺点&#xff1b; &#xff08;3&#xff09;…

区块链知识点2

1.用非对称加密方式传输对称加密的密钥 2.数字签名&#xff1a;私钥加密&#xff0c;公钥解密 3.RSA由于计算较大&#xff0c;通常用于数字签名和密钥交换&#xff0c;而非直接的数据加密。 4.签名过程 发送方A将消息用Hash算法产生一个消息摘要(Message Digest) 发…

消费级显卡上ollama部署QwQ32B

ollama部署QwQ32B QwQ32B硬件要求 魔改2080ti 的 22G 显存差不多够用 ollama中的是Q4_K_M量化模型 硬件配置模型推理模型高效微调模型全量微调显存占用最低配置显存占用最低配置显存占用最低配置FP_1664GRTX3090&#xff0a;4&#xff08;94G&#xff09;92GRTX3090&#xff0a…

万字长文详解嵌入式电机软件开发

目录 第一章:嵌入式电机概述 1.1 电机类型:选对 “主角” 有多重要? 1.2 嵌入式系统特点:硬件的 “灵魂” 靠什么支撑? 第二章:开发环境搭建 2.1 硬件平台选择:给 “大脑” 找个好载体 2.1.1 ARM Cortex 系列:全能选手 2.1.2 AVR 微控制器:简约而不简单 2.1.3 …

python-54-使用环境变量库python-dotenv进行应用程序配置参数的管理

文章目录 1 python-dotenv简介1.1 十二因素原则1.1.1 引言1.1.2 背景1.1.3 十二因素1.2 python-dotenv概述2 python-dotenv应用2.1 文件.env2.2 方式一load_dotenv()2.3 方式二dotenv_values()2.4 指定配置文件路径3 Flask结合dotenv3.1 Flask的config3.2 结合使用4 代码中的配…

How to introduce a new product in English?

How to introduce a new product in English? References Introducing a new product Forever: Yeah, sure. Today I am glad to announce [əˈnaʊns] that our new App has made it through the final testing stage. The name of the new App is on-device Stable Diffus…

数字电路 | 触发器 / 单稳态触发器 / 双稳态触发器

注&#xff1a;本文为 “数字电路 | 触发器” 相关文章合辑。 如有内容异常&#xff0c;请看原文。 未整理。 数字电路基础 — 触发器 Oliver-H 已于 2024-04-07 15:06:25 修改 触发器&#xff08;Flip-Flop&#xff09; 也是数字电路中的一种具有记忆功能的逻辑元件。触发…

SSM基础专项复习5——Maven私服搭建(2)

系列文章 1、SSM基础专项复习1——SSM项目整合-CSDN博客 2、SSM基础专项复习2——Spring 框架&#xff08;1&#xff09;-CSDN博客 3、SSM基础专项复习3——Spring框架&#xff08;2&#xff09;-CSDN博客 4、SSM基础专项复习4——Maven项目管理工具&#xff08;1&#xff…