Vue.js 使用CDN免费加速,国内未备案也能用腾讯云CDN

手上腾讯云 CDN 每月有 10GB 免费额度,迫于没有备案网站只能用 CloudFlare 提供的免费服务,近期使用 Vue.js 上线了一个工具页面,5 MB 的 js 文件花了 30 多秒才能加载完毕,最后奇思妙想“绕过”备案使用腾讯云成功加速了。

最后的效果就是通过局部加速,使用腾讯云页面都全部加载完毕了,使用 CloudFlare 还在解析域名点此查看效果

本文适用于以下条件的网站:

  • 网站在国外,用户在国内,但国内访问速度一般,需要国内 CDN 加速的
  • CDN 加速后效果显著的
  • 域名没有备案,不能使用国内 CDN 服务商加速的
  • 使用国外比较好的 CDN 服务商感觉不够性价比的

弃坑 CloudFlare

CloudFlare 原本是挺良心的一个服务商,对个人提供堪称够用的全球加速免费节点,奈何现在国内薅羊毛太厉害连科学上网都用上了,此处有介绍,现在质量已大不如前。

本站使用了Hexo + Netfily + CloudFlare 进行全免费的博客托管,写的在线工具是将 JSON 转为 TypeScript Interface 代码前端处理的,基本也是纯静态页面,并且我觉得没必要在代码层面做过多优化,按需加载、 Vue 优化 CDN 加速(Vue.js axios 等这些库不参与打包)这些技术都没用上,网速成了用户打开速度的唯一阻碍。

CloudFlare 的网络情况

晚间 8 点全国测速(西北的黄土高坡黄到沿海的灰头土脸):

image-20200304204510691

腾讯云 CDN

没有对比就没有伤害,同一时间使用 腾讯云 CDN 全站加速的效果(疫情退败全国春意盎然):

image-20200304204008957

操作步骤

加载架构

我们分析一下整个加载流程中遇到的问题:

  • html 文件必须从目标域名即 wivwiv.com 中加载,否则无法访问网站

  • js css 图片等可以跨域加载,可能会受到浏览器安全策略限制,但是不限域名

  • html 文件体积在 Vue.js 项目中比较小,恰巧 js 与 css 文件特别大

所以最终可以得到这么一个思路,将打包后的 css 与 js 以及图片资源上传到腾讯云 CDN 上,搭建专属的 CDN,整个架构如下:

image-20200304210359419

Vue 配置

实现这个很简单,Vue CLI vue.config.js 配置文件中配置如下,将生产环境的 publicPath 设置为 CDN 上的资源根路径,打包后上传上去即可:

// vue.config.js
module.exports = {
productionSourceMap: false,
// publicPath
publicPath: process.env.NODE_ENV === 'production' ? '//cdn.example.com/mindspark-c' : '/c',
};

注意默认生成 Vue 项目的路由也通过环境变量依赖了 publicPath 这个配置项,需要额外设置一下,否则就得用 CDN 域名这一串来作为浏览器根路径了:

// src/router/index.ts
const router = new VueRouter({
mode: 'history',
// base: process.env.BASE_URL,
base: '/c', // 即使用 https://wivwiv.com/c 来访问
routes,
});

上传到腾讯云

我使用的是腾讯云对象存储 + CDN 的方式,即不需要额外的主机,直接把内容存储在腾讯云对象存储上。

由于每次手动上传都比较复杂,这里写了一个脚本自动上传:

// _script/upload.js

const COS = require('cos-nodejs-sdk-v5');
const glob = require('glob');
const fs = require('fs');
const path = require('path');

const cos = new COS({
SecretId: '***',
SecretKey: '***',
});

// 读取 dist 下的文件结构
const list = glob.sync(path.join(__dirname, '../dist/**/**'));
list.forEach((file) => {
if (fs.statSync(file).isDirectory()) {
return;
}
const fileName = file.split('/dist/')[1];
// 拼接 路径 + 文件
const key = `mindspark-c/${fileName}`;
// 逐个上传
put(file, key);
});

function put(file, key) {
cos.putObject({
Bucket: 'blog-xxx', /* 必须 */
Region: 'ap-guangzhou', /* 必须 */
Key: key, /* 必须 */
StorageClass: 'STANDARD',
Body: fs.createReadStream(file), // 上传文件对象
onProgress(progressData) {
console.log(key, ':', JSON.stringify(progressData));
},
}, (err, data) => {
console.info(err || `${file} ${data.status} Done`);
});
}

每次打包后自动上传,修改 package.json build 命令:

{
"scripts": {
"build": "npm run build && node _script/upload.js"
}
}

申请腾讯云免费 CDN

具体流程本文不再赘述,本站目前每月享受免费 10GB 流量,要是哪天流量不够用了也应该有钱买流量包了P:)

这个思路下源站可以是朋友已备案的网站和对象存储,甚至是一些比较快的图床、 CDN 服务上。

有兴趣试试将静态资源传到 http://loli.net/ 上?连源站都省了。

更新:

看到有用 npm + jsDelivr 托管静态资源的教程,这个思路不错,后期我试一试。

测速跟腾讯云 CDN 有得比,jsDelivr 已经拿到 ICP 牌照,中国节点 2015 年就上线了,很可观。

另外 Hexo 生成的 js css 我也成功用 cheerio 解析处理了一下上传到 CDN 上了,文件不大但是数量多,招架不住 DNS 解析时间太长也是一个很大的耗时。

点此查看