【性能优化】DNS解析优化

【性能优化】DNS解析优化性能优化 DNS 解析优化 dns 优化

大家好,欢迎来到IT知识分享网。

前言

DNS 简单来说就是将 域名 映射到 ip,访问页面时浏览器会检查本地缓存是否有该域名的 IP 地址记录。

  • 如果缓存没有,浏览器会向 DNS 服务器发起请求,查找该域名对应的 IP 地址。
  • 如果 DNS 查询成功,返回相应的 IP 地址,浏览器就知道应该与哪个服务器建立连接。

小结:

  • DNS解析过程消耗时间
  • DNS有本地缓存

比如首次访问某站点,会耗费很多时间进行DNS解析,但解析结束后会将ip地址存入本地设备,后续再访问此域名时就会直接从缓存中取。

首次访问页面时,本页面的DNS解析是无法优化的,但是页面中可能用到其他域名下的资源,如css、图片、js等,可以通知浏览器提前对这些资源进行异步DNS解析。d

在这里插入图片描述

实现

以下代码引入了其他域名下的资源,需要在head中添加link进行dns预解析,格式如下:

<link rel="dns-prefetch" href="https://www.xxx.com"> 
<!DOCTYPE html> <html lang="en"> <head> <link rel="dns-prefetch" href="https://www.abc.com"> <link rel="dns-prefetch" href="https://www.aaa.com"> <link rel="dns-prefetch" href="https://www.tes.com"> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> .container { 
      background: url('https://www.abc.com/imgs/main-bg'); } </style> </head> <body> <div class="container"> <img src="https://www.aaa.com/img/32fd.jpg" alt=""> </div> <script src="https://www.tes.com/sss.js"></script> </body> </html> 

框架内实现

但是合作开发模式下,站外资源的引用会分散到很多组件中,难以集中控制且由于是手动写死的地址,也会提高维护成本

本文提供两种方式,分别为手写js实现以及vite插件,如果想将js插件发布到npm可以看另一篇文章:如何将自己的插件发布到npm上。

方式一:手写js实现

标准的做法应该是根据构建工具写一个插件,如vite用的rollup,就要写一个rollup插件,但是本文通过node实现

首先需要实现分析打包结果中的js,取出站外资源对应域名,并动态添加link标签到html的head中。

在这里插入图片描述

新建js用于动态插入link

项目中新建scripts目录,

确保项目中有如下插件

npm install node-html-parser
npm install glob
npm install url-regex

dns-prefetch.cjs代码内容如下:

// 该node文件:识别打包结果中的站外资源地址并动态插入index.html中link实现dns-prefetch,提高渲染速度 // 调用方式:node ./scripts/dns-prefetch.js const fs = require("fs") const path = require("path") const { 
    parse } = require("node-html-parser") // 可以脱离浏览器环境将html字符串解析成HTML节点 const { 
    glob } = require("glob") const urlRegex = require("url-regex") // 可以分析文件中所包含的url const { 
    strict } = require("assert") const urlPattern = /(https?:\/\/[^/]*)/i // 获取外部链接 const urls = new Set() // url集合 // 遍历dist目录中的所有 HTML 文件 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]) // 将域名加到Set中 } }) } } } // 将遍历好的所有域名生成link预解析标签并插入到index.html中 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(), "utf-8") } } async function main() { 
    await searchDomain() await insertLinks() } main() 

package.json中在打包处理后执行该js

"scripts": { 
    "dev": "vite", "build": "vite build && node ./scripts/dns-prefetch.cjs", "preview": "vite preview" }, 

&&的意义:如 vite+ts 项目默认打包为:"build": "tsc && vite build",意为先进行ts语法检查,再打包,如果语法检查错误则立即停止。所以此处将自定义js放到打包后执行。

查看dist中index.html,发现link已经插入。

在这里插入图片描述

方式二:vite-plugin-prefetch-dns插件

npm install vite-plugin-prefetch-dns 
import { 
    defineConfig } from 'vite'; import prefetchDns from 'vite-plugin-prefetch-dns'; export default defineConfig({ 
    plugins: [ ...其他插件 prefetchDns() ] }); 

执行npm run build,打包完毕后看到正确插入link标签。

免责声明:本站所有文章内容,图片,视频等均是来源于用户投稿和互联网及文摘转载整编而成,不代表本站观点,不承担相关法律责任。其著作权各归其原作者或其出版社所有。如发现本站有涉嫌抄袭侵权/违法违规的内容,侵犯到您的权益,请在线联系站长,一经查实,本站将立刻删除。 本文来自网络,若有侵权,请联系删除,如若转载,请注明出处:https://haidsoft.com/113142.html

(0)
上一篇 2026-01-14 07:45
下一篇 2026-01-14 08:10

相关推荐

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注微信