重慶網站建站建設的費用seo最強
前言
- DNS解析過程消耗時間
- DNS有本地緩存
比如首次訪問某站點
,會耗費很多時間
進行DNS解析,但解析結束后會將ip
地址存入本地設備,后續(xù)再訪問此域名時就會直接從緩存
中取。
首次訪問頁面時,本頁面的DNS解析是無法優(yōu)化的,但是頁面中可能用到其他域名下的資源,如css、圖片、js等,可以通知瀏覽器提前對這些資源進行異步
DNS解析。
實現
以下代碼引入了其他域名下的資源,需要在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>
框架內實現
但是合作開發(fā)模式下,站外資源
的引用會分散
到很多組件中,難以集中控制
且由于是手動寫死的地址,也會提高維護成本
。
本文提供兩種方式,分別為手寫js實現以及vite插件,如果想將js插件發(fā)布到npm
可以看另一篇文章:如何將自己的插件發(fā)布到npm上。
方式一:手寫js實現
標準的做法應該是根據構建工具寫一個插件,如vite用的rollup,就要寫一個rollup插件,但是本文通過node實現
。
首先需要實現分析打包結果中的js,取出站外資源對應域名,并動態(tài)添加link標簽到html的head中。
新建js用于動態(tài)插入link
確保項目中有如下插件
npm install node-html-parser
npm install glob
npm install url-regex
dns-prefetch.cjs代碼內容如下:
// 該node文件:識別打包結果中的站外資源地址并動態(tài)插入index.html中l(wèi)ink實現dns-prefetch,提高渲染速度
// 調用方式:node ./scripts/dns-prefetch.jsconst fs = require("fs")
const path = require("path")
const { parse } = require("node-html-parser") // 可以脫離瀏覽器環(huán)境將html字符串解析成HTML節(jié)點
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中在打包處理后執(zhí)行該js
"scripts": {"dev": "vite","build": "vite build && node ./scripts/dns-prefetch.cjs","preview": "vite preview"
},
&&的意義:如 vite+ts 項目默認打包為:"build": "tsc && vite build"
,意為先進行ts語法檢查,再打包,如果語法檢查錯誤則立即停止。所以此處將自定義js放到打包后執(zhí)行。
查看dist中index.html,發(fā)現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()]
});
執(zhí)行npm run build,打包完畢后看到正確插入link標簽。