DNS预解析脚本
图例:
# DNS 预解析
通过在 html 文件的
head
标签里面添加<link rel="dns-prefetch" href="//api.example.com">
来实现 DNS 预解析可以减少 DNS 的查询时间:用户首次访问网页时,浏览器需要解析所有外部资源,所以可以提前进行 DNS 预解析,从而减少后续资源加载时的延迟
加速首屏加载:可以有效减少页面加载的时间,尤其是首屏有资源需要加载的情况
# 实现思路
扫描目录,提取 URL 域名:遍历打包产物路径下的所有的
.js
、.css
和.html
文件,使用正则表达式提取其中的 URL 域名- 可以设置一些需要排除的域名,因为扫描的结果会把
react
、lodash
这些包的官网地址也扫描出来
- 可以设置一些需要排除的域名,因为扫描的结果会把
添加 link 标签到 HTML 文件中:扫描出的域名,映射成
<link rel="dns-prefetch">
标签,然后添加到打包产物目录下的所有 HTML 文件的head
部分
# 实现代码
点击 展开/收起 jsx 代码
import fs from 'fs';
import path from 'path';
import { fileURLToPath } from 'url';
// 获取当前模块的文件路径
const __filename = fileURLToPath(import.meta.url);
// 获取当前模块的目录路径
const __dirname = path.dirname(__filename);
// 扫描目录下的所有文件 得到其中的 url
function scanDistUrls(distPath) {
const urlSet = new Set();
const urlRegex = /https?:\/\/([a-zA-Z0-9.-]+)/g;
// 定义要排除的域名或路径关键字
const excludeList = [
'w3.org', // 排除 w3.org
'github.com', // 排除 GitHub
'quilljs.com', // 排除 Quill
'npms.io', // 排除 NPM
'lodash.com', // 排除 lodash
'html2canvas.hertzen.com', // 排除 html2canvas
'openjsf.org', // 排除 openjsf
'reactjs.org', // 排除 React
'github.io', // 排除 GitHub
'underscorejs.org', // 排除 Underscore
'hertzen.com', // 排除 Hertzen
];
// 递归扫描目录下的所有文件
function scanDistFiles(distPath) {
const files = fs.readdirSync(distPath);
for (let file of files) {
const filePath = path.join(distPath, file);
const stats = fs.statSync(filePath);
if (stats.isDirectory()) {
scanDistFiles(filePath);
} else if (
file.endsWith('.js') ||
file.endsWith('.html') ||
file.endsWith('.css')
) {
const content = fs.readFileSync(filePath, 'utf8');
const urls = content.match(urlRegex);
if (urls) {
for (let url of urls) {
if (!excludeList.some((keyword) => url.includes(keyword))) {
urlSet.add(url);
}
}
}
}
}
}
scanDistFiles(distPath);
return Array.from(urlSet);
}
// 将得到的urls 映射成 <link rel="dns-prefetch"> 添加到html中head标签里面
function addDnsPrefetchToHtml(distPath, urls) {
const files = fs.readdirSync(distPath);
for (let file of files) {
const filePath = path.join(distPath, file);
const stats = fs.statSync(filePath);
if (stats.isDirectory()) {
addDnsPrefetchToHtml(filePath, urls);
} else if (file.endsWith('.html')) {
let content = fs.readFileSync(filePath, 'utf8');
const dnsPrefetchTags = urls
.map((url) => `<link rel="dns-prefetch" href="${url}">`)
.join('\n');
// 插入到head标签里面
content = content.replace(/<\/head>/i, `${dnsPrefetchTags}\n</head>`);
fs.writeFileSync(filePath, content);
}
}
}
function main() {
console.log(
'--------------------------------------------------------------------------\n',
);
const quantanalysisPath = path.join(__dirname, 'quantanalysis');
console.log('正在添加 dns-prefetch 到 html 文件中...\n');
console.log(`获取 ${quantanalysisPath} 路径下所有css、js、html内的url...\n`);
// 扫描 quantanalysis 目录
const urls = scanDistUrls(quantanalysisPath);
if (urls.length > 0) {
console.log(`urls获取成功,开始添加 dns-prefetch 到 html 文件中\n`);
console.log(urls);
addDnsPrefetchToHtml(quantanalysisPath, urls);
console.log('dns-prefetch 添加成功');
} else {
console.log('没有发现需要添加 dns-prefetch 的文件\n');
}
console.log(
'--------------------------------------------------------------------------\n',
);
}
main();
← 提交脚本 node服务更新脚本 →