目录:
一、---------------------------cdn问答
1---------------------------什么是cdn?
2---------------------------为什么要使用cdn引入公共模块 ?
3---------------------------有cdn和没有cdn的区别是什么?
二、---------------------------关于缓存
三、---------------------------采用cdn引入公共组件的优点
四、---------------------------采用cdn引入公共组件的缺点
五、---------------------------在vue-cli2.x中的公共组件以cdn的方式引入
六、---------------------------在vue-cli3.x中的公共组件以cdn的方式引入
一:cdn的问答
8年前,还没有火车票代售点一说,12306.cn更是无从说起。那时候火车票还只能在火车站的售票大厅购买,而我所住的小县城并不通火车,火车票都要去市里的火车站购买,而从县城到市里,来回就是4个小时车程,简直就是浪费生命。后来就好了,小县城里出现了火车票代售点,可以直接在代售点购买火车,方便了不少,全市人民再也不用在一个点苦逼的排队买票了。技术来源于生活,如何将这种便利带入我们的项目中。
好了话不多说 上图
[图片上传失败...(image-593127-1639476511537)]
http缓存的介绍参考网址:<u>https://www.cnblogs.com/Leo_wl/p/5686610.html</u>,这里我们主要介绍cdn
1、什么是cdn?
CDN也叫内容分发网络,是一个经策略性部署的整体系统,包括分布式存储、负载均衡、网络请求的重定向和内容管理4个要件。而其中呢,内容管理和全局的网络流量管理是CDN的核心所在。通过用户就进行和服务器负载的判断,CDN确保内容以一种极为高效的方式为用户的请求提供服务
[图片上传失败...(image-9bda6c-1639476511536)]
2、为什么要使用cdn引入公共模块 ?
客户端直接从源站点获取数据,当服务器访问量大时会影响访问速度,进而影响用户体验,且无法保证客户端与源站点间的距离足够短,并且适合传输数据。
3、有cdn和没有cdn的区别是什么?
A、没有cdn:
-->用户在浏览器访问栏中输入要访问的域名;
-->浏览器向DNS服务器请求对该域名的解析;
-->DNS服务器返回该域名的IP地址给浏览器;
-->浏览器使用该IP地址向服务器请求内容;
-->服务器将用户请求的内容返回给浏览器;
B、有cdn:
-->用户在浏览器中输入要访问的域名
-->浏览器向DNS服务器请求对域名进行解析。由于CDN对域名解析进行了调整,DNS服务器会最终 将域名的解析权交给CNAME指向的CDN专用DNS服务器
-->CDN的DNS服务器将CDN的负载均衡设备IP地址返回给用户
-->用户向CDN的负载均衡设备发起内容URL访问请求
-->CDN负载均衡设备会为用户选择一台合适的缓存服务器提供服务
Ps:选择的依据包括:根据用户IP地址,判断哪一台服务器距离用户最近;根据用户所请求的URL中携带的内容名称,判断哪一台服务器上有用户所需内容;查询各个服务器的负载情况,判断哪一台服务器的负载较小,基于以上这些依据的综合分析之后,负载均衡设置会把缓存服务器的IP地址返回给用户
-->用户向缓存服务器发出请求
-->缓存服务器响应用户请求,将用户所需内容传送到用户
-->如果这台缓存服务器上并没有用户想要的内容,而负载均衡设备依然将它分配给了用户,那么这台服 务器就要向它的上一级缓存服务器请求内容,直至追溯到网站的源服务器将内容拉取到本地
二、关于缓存
没有CDN:浏览器缓存
使用了CDN:浏览器缓存+CDN缓存
在用户第一次访问网站后,网站的一些静态资源如图片等就会被下载到本地,作为缓存,当用户第二次访问该网站的时候,浏览器就会从缓存中加载资源,不用向服务器请求资源,从而提高了网站的访问速度,而若使用了CDN,当浏览器本地缓存的资源过期之后,浏览器不是直接向源站点请求资源,而是向CDN边缘节点请求资源,CDN边缘节点中也存在缓存,若CDN中的缓存也过期,那就由CDN边缘节点向源站点发出回源请求来获取最新资源。
浏览器在加载资源时,先根据这个资源的一些http header判断它是否命中强缓存,如果命中,浏览器直接从自己的缓存中读取资源,不会发请求到服务器,当强缓存没有命中的时候,浏览器一定会发送一个请求到服务器,服务器端依据资源的另外一些http header验证这个资源是否命中协商缓存,如果命中,服务器会将这个请求返回,但是不会返回这个资源的数据,而是告诉客户端可以直接从缓存中加载这个资源,于是浏览器还是从自己的缓存中加载资源,当协商缓存也没有命中的时候,浏览器直接从服务器加载资源数据
CDN节点缓存机制在不同服务商中是不同的,但一般都遵循HTTP协议,通过http响应头中的Cache-Control:max-age的字段来设置CDN节点文件缓存时间。当客户端向CDN节点请求数据时,CDN会判断缓存数据是否过期,若没有过期,则直接将缓存数据返回给客户端,否则就向源站点发出请求,从源站点拉取最新数据,更新本地缓存,并将最新数据返回给客户端。CDN服务商一般会提供基于文件后缀、目录多个维度来指定CDN缓存时间,为用户提供更精细化的缓存管理。CDN缓存时间会对“回源率”产生直接的影响,若CDN缓存时间短,则数据经常失效,导致频繁回源,增加了源站的负载,同时也增大了访问延时;若缓存时间长,数据更新时间慢,因此需要针对不同的业务需求来选择特定的数据缓存管理。
三、采用cdn引入公共组件的优点
1、****多域名加载资源
一般情况下,浏览器都会对单个域名下的并发请求数(文件加载)进行限制,通常最多有4个,那么第5个加载项将会被阻塞,直到前面的某一个文件加载完毕。
因为CDN文件是存放在不同区域(不同IP)的,所以对浏览器来说是可以同时加载页面所需的所有文件(远不止4个),从而提高页面加载速度。
2、文件可能已经被加载过并保存有缓存
一些通用的js库或者是css样式库,如jQuery,在网络中的使用是非常普遍的。当一个用户在浏览你的某一个网页的时候,很有可能他已经通过你网站使用的CDN访问过了其他的某一个网站,恰巧这个网站同样也使用了jQuery,那么此时用户浏览器已经缓存有该jQuery文件(同IP的同名文件如果有缓存,浏览器会直接使用缓存文件,不会再进行加载),所以就不会再加载一次了,从而间接的提高了网站的访问速度。
3、高效率
你的网站做的再NB也不会NB过百度NB过Google吧?一个好的CDNs会提供更高的效率,更低的网络延时和更小的丢包率。
4、分布式的数据中心
假如你的站点布置在北京,当一个香港或者更远的用户访问你的站点的时候,他的数据请求势必会很慢很慢。而CDNs则会让用户从离他最近的节点去加载所需的文件,所以加载速度提升就是理所当然的了。
5、内置版本控制
通常,对于CSS文件和JavaScript库来说都是有版本号的,你可以通过特定版本号从CDNs加载所需的文件,也可以使用latest加载最新版本(不推荐)。
6、使用情况分析
一般情况下CDNs提供商(如百度云加速)都会提供数据统计功能,可以了解更多关于用户访问自己网站的情况,可以根据统计数据对自己的站点适时适当的做出些许调整。
7、有效防止网站被攻击
一般情况下CDNs提供商也是会提供网站安全服务的。
四、采用cdn引入公共组件的缺点
硬核:必须依赖网络,如果没网,cdn的资源什么都回不来,可能导致页面崩塌。
五、在vue-cli2.x中的公共组件以cdn的方式引入
与其说是优化 Vue,不如说主要是在 webpack 打包的配置中做些文章,使得 Vue 编译后的文件尽可能的小。以下介绍自己在项目中进行优化的过程,其中的内容也许并不适合于每个项目,但整体思路是差不多的
1、定位问题
要想进行优化,首先我们得清楚问题所在。即:是哪些代码/依赖包导致最后的编译文件过大?
这里,我们需要使用 webpack-bundle-analyzer 工具。修改 package.json 文件,添加:
"analyze": "NODE_ENV=production npm_config_report=true npm run build"
[图片上传失败...(image-1e0abc-1639476511535)]
[图片上传失败...(image-ecccc2-1639476511535)]
Ps:vue-cli2.x脚手架中是默认有webpack-bundle-analyzer工具的,所以在这里我们只需要在 package.json中添加我们所需要的命令“analyz”。
注意:这里在添加命令“analyz的时候,"analyze": "NODE_ENV=production npm_config_report=true npm run build" 会报错:NODE_ENV不是本地命令,其实是因为使用NODE_ENV命令需要跨平台兼容,所以在此我们需要引入另外一个组件
"cross-env": "^5.2.0",
npm install cross-env -S
同事配置命令的时候:"analyz": "cross-env NODE_ENV=production npm_config_report=true npm run build"
之后在命令行输入:npm run analyze
我们会在浏览器上看到我们项目所打的包的具体大小:
[图片上传失败...(image-aee065-1639476511535)]
好了,找到病根,接下来就是对症下药,下面我们一vue为例作为讲解:
首先,为了避免我们从新使用cdn引入进来的文件与我们下载的好的元组件内容不一致,我们需要将引入的cdn版本号统一:
[图片上传失败...(image-3fd320-1639476511535)]
之后在index.html中全局引入
[图片上传失败...(image-61d4a-1639476511535)]
接下来就是要让webpack打包时将这些已经使用cdn引入的公共组件排除在外,已达到给我们的版本包瘦身的效果。
在webpack中有一个配置:externals
externals 配置选项提供了「从输出的 bundle 中排除依赖」的方法。相反,所创建的 bundle 依赖于那些存在于用户环境(consumer's environment)中的依赖也会从externals的配置中找寻。
externals 详解:<u>https://www.tangshuang.net/3343.html</u> (非官方地址)
有了externals配置就好说了,我们在webpack.base.conf.js中配置:
[图片上传失败...(image-7d1402-1639476511535)]
之后再运行npm run analyze你会发现包变小了,之前vue所占的大小被甩掉了。
恭喜通关!就是这么简单_
六、在vue-cli3.x中的公共组件以cdn的方式引入
首先还是定位问题:在vue-cli3.x中是没有默认安装webpack-bundle-analyzer工具的,所以
npm intall webpack-bundle-analyzer –save-dev
并在项目中新增vue.config.js文件,配置如下
[图片上传失败...(image-3e00b1-1639476511535)]
chainWebpack: config => {
config
.plugin('webpack-bundle-analyzer')
.use(require('webpack-bundle-analyzer').BundleAnalyzerPlugin)
}
之后运行命令:npm run serve;注意该方法会覆盖之前的npm run serve和npm run build 查看完毕之后如需还原,只需要将上边的配置注释即可!
之后同样是在index.html文件中全局引入cdn,注意版本号统一:
[图片上传失败...(image-7132ef-1639476511535)]
之后在vue.config.js配置文件中配置
[图片上传失败...(image-db46c8-1639476511535)]
configureWebpack: {
externals: {
vue: 'Vue'
}
},
好了恭喜你通关vue-cli3.x -
完!
后话:
更多vue-cli3.x配置参考!
const path = require('path');
const vConsolePlugin = require('vconsole-webpack-plugin'); // 引入 移动端模拟开发者工具 插件 (另:https://github.com/liriliri/eruda)
const CompressionPlugin = require('compression-webpack-plugin'); //Gzip
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; //Webpack包文件分析器
const baseUrl = process.env.NODE_ENV === "production" ? "/static/" : "/"; //font scss资源路径 不同环境切换控制
module.exports = {
//基本路径
baseUrl: './',
//输出文件目录
outputDir: 'dist',
// eslint-loader 是否在保存的时候检查
lintOnSave: true,
//放置生成的静态资源 (js、css、img、fonts) 的 (相对于 outputDir 的) 目录。
assetsDir: 'static',
//以多页模式构建应用程序。
pages: undefined,
//是否使用包含运行时编译器的 Vue 构建版本
runtimeCompiler: false,
//是否为 Babel 或 TypeScript 使用 thread-loader。该选项在系统的 CPU 有多于一个内核时自动启用,仅作用于生产构建,在适当的时候开启几个子进程去并发的执行压缩
parallel: require('os').cpus().length > 1,
//生产环境是否生成 sourceMap 文件,一般情况不建议打开
productionSourceMap: false,
// webpack配置
//对内部的 webpack 配置进行更细粒度的修改 https://github.com/neutrinojs/webpack-chain see https://github.com/vuejs/vue-cli/blob/dev/docs/webpack.md
chainWebpack: config => {
/**
* 删除懒加载模块的prefetch,降低带宽压力
* https://cli.vuejs.org/zh/guide/html-and-static-assets.html#prefetch
* 而且预渲染时生成的prefetch标签是modern版本的,低版本浏览器是不需要的
*/
// config.plugins.delete('prefetch');
// if(process.env.NODE_ENV === 'production') { // 为生产环境修改配置...process.env.NODE_ENV !== 'development'
// } else {// 为开发环境修改配置...
// }
},
//调整 webpack 配置 https://cli.vuejs.org/zh/guide/webpack.html#%E7%AE%80%E5%8D%95%E7%9A%84%E9%85%8D%E7%BD%AE%E6%96%B9%E5%BC%8F
configureWebpack: config => {
//生产and测试环境
let pluginsPro = [
new CompressionPlugin({ //文件开启Gzip,也可以通过服务端(如:nginx)(https://github.com/webpack-contrib/compression-webpack-plugin)
filename: '[path].gz[query]',
algorithm: 'gzip',
test: new RegExp('\\.(' + ['js', 'css'].join('|') + ')$', ),
threshold: 8192,
minRatio: 0.8,
}),
// Webpack包文件分析器(https://github.com/webpack-contrib/webpack-bundle-analyzer)
new BundleAnalyzerPlugin(),
];
//开发环境
let pluginsDev = [
//移动端模拟开发者工具(https://github.com/diamont1001/vconsole-webpack-plugin https://github.com/Tencent/vConsole)
new vConsolePlugin({
filter: [], // 需要过滤的入口文件
enable: false // 发布代码前记得改回 false
}),
];
if(process.env.NODE_ENV === 'production') { // 为生产环境修改配置...process.env.NODE_ENV !== 'development'
config.plugins = [...config.plugins, ...pluginsPro];
} else {
// 为开发环境修改配置...
config.plugins = [...config.plugins, ...pluginsDev];
}
},
css: {
// 启用 CSS modules
modules: false,
// 是否使用css分离插件
extract: true,
// 开启 CSS source maps,一般不建议开启
sourceMap: false,
// css预设器配置项
loaderOptions: {
sass: {
//设置css中引用文件的路径,引入通用使用的scss文件(如包含的@mixin)
data: `
$baseUrl: "/";
`
}
}
},
// webpack-dev-server 相关配置 https://webpack.js.org/configuration/dev-server/
devServer: {
host: 'localhost',
// host: "0.0.0.0",
port: 8000, // 端口号
https: false, // https:{type:Boolean}
open: true, //配置自动启动浏览器 http://XXX.XXX.X.XX:7071/rest/XXX/
hotOnly: true, // 热更新
proxy: 'http://localhost:8000' // 配置跨域处理,只有一个代理
// proxy: { //配置自动启动浏览器
// "/XX/*": {
// target: "http://XXX.XXX.X.XX",
// changeOrigin: true,
// // ws: true,//websocket支持
// secure: false
// },
// "/x/*": {
// target: "http://XXX.XXX.X.XX",
// changeOrigin: true,
// // ws: true,//websocket支持
// secure: false
// },
// }
},
// 第三方插件配置 https://www.npmjs.com/package/vue-cli-plugin-style-resources-loader
pluginOptions: {
'style-resources-loader': {//https://github.com/yenshih/style-resources-loader
preProcessor: 'scss',//声明类型
'patterns': [
// path.resolve(__dirname, './src/assets/scss/_common.scss'),
],
// injector: 'append'
}
}
}
更多前端性能优化:<u>https://www.cnblogs.com/chris-oil/p/9122633.html</u>
关于缓存:<u>https://www.jianshu.com/p/f4dbaaebe902</u>
Vue层面的性能优化:<u>https://www.haorooms.com/post/vue_webpack_youhua</u>
网友评论