DNS解析与优化

这篇笔记总结自网课👉DNS解析和优化【渡一教育】

DNS用于将域名转换成IP地址。

特点

  1. DNS解析过程耗费时间长;

  2. DNS有本地缓存。

    DNS解析完成得到IP地址,这个IP地址会存储到本地设备,后续再读这个域名会直接返回本地缓存的IP地址。

用户浏览网页中的DNS解析流程

  1. 首先用户输入url地址,然后需要对网站的域名进行DNS解析,这个解析过程无法优化。
  2. 而在站点中可能还用到了很多其它域名下的资源,在解析html的过程也会触发DNS解析。

例如:<img>标签的src引用了其它域名站点的图片,或者<script>标签引入了外部的脚本文件,或者<link>标签引入了其它域名站点的css文件。

当解析html的过程中遇到了站外的script标签且本地无缓存时,解析html的进度会暂停,直到script标签引入并执行再继续。

随着网站规模越来越大,这种外部资源的引入可能越来越多。而多次的DNS解析会耗费许多时间。

优化思路:源代码中使用的外部域名是已知的,可以把它们都提取到html的头部,提前异步解析。

提前异步解析DNS

使用link标签的dns-prefetch

<html>
	<head>
 <link rel="dns-prefetch" href="https://www.a.com"/>
 <link rel="dns-prefetch" href="https://www.b.com"/>
 <link rel="dns-prefetch" href="https://www.c.com"/>
 ...
 </head>
 <body>
 ...
 </body>
</html>

但是,考虑到我们平时的开发环境有以下特点:

  1. 使用框架开发,不同的域名分散在不同的组件;
  2. 多人开发,不知道其他人有没有引入外部域名;
  3. 一般不会手动编辑打包后的index.html文件。

我们需要较为自动化的脚本协助完成整个项目中的外部域名统计,并写入到最终打包的index.html头部。

脚本编写

目的:读取dist文件夹中的.css.js文件,统计外部域名并写入到index.html头部。

创建脚本:项目根目录下创建文件夹/scripts,创建文件dns-prefetch.js

脚本内容

const fs = require('fs');
const path = require('path');
const { parse } = require('node-html-parse');
const { glob } = require('glob');
const urlRegex = require('url-regex');
// 获取外部链接的正则表达式
const urlPattern = /(https?:\/\/[^/]*)/i;
const urls = new Set();
// 遍历dist目录中的所有HTML, JS, CSS文件
async function searchDomain(){
 const files = await glob('dist/**/*.{html,css,js}');
 for(const file of files){
 const source = fs.readFileSync(file, 'utf-8');
 const matches = source.match(urlRegex({strict: true}));
 if(matches){
 matches.forEach((url)=>{
 const match = url.match(urlPattern);
 if(match && match[1]){
 urls.add(match[1]);
 }
 });
 }
 }
}
async function insertLinks(){
 const files = await glob('dist/**/*.html');
 const links = [...urls]
 .map((url) => `<link rel="dns-prefetch" href="${url}"/>`)
 .join('\n');
 for(const file of files){
 const html = fs.readFileSync(file, 'utf-8');
 const root = parse(html);
 const head = root.querySelector('head');
 head.insertAdjacentHTML('afterbegin', links);
 fs.writeFileSync(file, root.toString());
 }
}
async function main(){
 await searchDomain();
 // 在<head>标签中添加预取链接
 await insertLinks();
}
main();
  • glob用于使用正则表达式将匹配的文件都找到;
  • fs用于读取选中的文件;
  • urlRegex用于分析出文件中的URL地址;
  • node-html-parse用于在脱离浏览器的环境下,将读取到的html代码文本转换为节点。

当脚本编写完成之后,将其添加到打包代码的工具流程中。

package.json文件中:

{
	"scripts": {
 "build": "vite build && node ./scripts/dns-prefetch.js"
 }
}
作者:feixianxing原文地址:https://www.cnblogs.com/feixianxing/p/18017542/dns-prefetch-optimize

%s 个评论

要回复文章请先登录注册