href 和 src 有什么区别,它们对性能有什么影响?

目录

[href 和 src 有什么区别,它们对性能有什么影响?](#href 和 src 有什么区别,它们对性能有什么影响?)

[一、核心语义:src 与 href 的本质区别](#一、核心语义:src 与 href 的本质区别)

1、基本语义(根本差异)

2、典型使用场景与对应元素案例

[3、URL 解析与协议行为(src 与 href 通用)](#3、URL 解析与协议行为(src 与 href 通用))

[二、从请求、阻塞、优先级、渲染流程看 src 和 href 的浏览器行为](#二、从请求、阻塞、优先级、渲染流程看 src 和 href 的浏览器行为)

1、请求触发时机

2、页面阻塞与执行

3、资源优先级

三、工程化实践中的实际使用

1、性能优化

[①脚本优化:defer / async / dynamic import](#①脚本优化:defer / async / dynamic import)

②样式优化:分割与预加载

③图片优化:loading="lazy"

④资源预加载策略

[2、在 Vue / Vite 中如何使用 src 与 href](#2、在 Vue / Vite 中如何使用 src 与 href)

四、结语


作者:watermelo37

CSDN全栈领域优质创作者、华为云云享专家、阿里云专家博主、腾讯云"创作之星"特邀作者、火山KOL、支付宝合作作者,全平台博客昵称watermelo37。

一个假装是giser的coder,做不只专注于业务逻辑的前端工程师,Java、Docker、Python、LLM均有涉猎。


温柔地对待温柔的人,包容的三观就是最大的温柔。


href 和 src 有什么区别,它们对性能有什么影响?

在前端开发中,src 和 href 是最常使用的两个 HTML 属性,许多工程师主要依靠经验使用,而不真正清楚它们在浏览器中的语义、行为差异以及性能与安全影响。难道它们只是"约定俗成"的

小瓜将从语义基础 → 浏览器行为 → 工程实践,由浅入深分享分享 href 与 src 的小秘密。

一、核心语义:src 与 href 的本质区别

1、基本语义(根本差异)

**src = 引入资源 → 当前元素必须使用该资源。**元素会"把资源装进来"并执行/渲染/播放。常见对象:img、script、iframe、video、audio。

**href = 建立关系或导航 → 当前元素指向另一个资源。**并不一定"加载并执行资源",而是声明一种关系或跳转。常见对象:a、link、area、base。

总结起来就是:src 是"我需要它";href 是"它在那里"。

2、典型使用场景与对应元素案例

使用 src 的元素(真正依赖资源):

html 复制代码
<img src="...">
<script src="...">
<iframe src="...">
<audio> / <video> / <source>
<embed> / <track> / 图片按钮 <input type="image">

使用 href 的元素(声明关系或导航):

html 复制代码
<a href="...">(导航)
<link href="..." rel="stylesheet">(关系:样式表)
<link rel="preload" href="...">(建立资源关系,rel也可以为prefetch,icon,dns-prefetch)
<base href="...">

3、URL 解析与协议行为(src 与 href 通用)

首先相对路径的解析必须依赖base元素,它是相对路径的"基准"。如:

<base href="https://example.com/assets/">

其中可以使用多种协议,比如 http(s):、data:、blob:、file:、javascript:(不推荐)。不推荐的原因是javascript:只对 href 有意义,对 src 则无效,并且会破坏src相对路径解析的默认行为(从当前文档的URL作为默认URL)。

二、从请求、阻塞、优先级、渲染流程看 src 和 href 的浏览器行为

从工程角度看,真正影响用户体验的是浏览器如何处理这两个属性。

1、请求触发时机

对 src 立即请求,解析到元素时即触发请求。如:

html 复制代码
<script src="app.js"></script>
<img src="banner.png">

对 href 则会视元素类型而定,比如:

  • <link rel="stylesheet">:立即请求,并阻塞渲染。
  • <link rel="preload">:立即高优先级请求。
  • <a href="...">:不请求,等待用户点击。
  • <link rel="prefetch">:延迟、低优先级请求。

总而言之,href 是关系声明,不一定马上发请求;src 则大部分情况下立即下载。

2、页面阻塞与执行

首先是 script 的三种行为,这部分主要是涉及到 defer 和 async 的执行原理和时机:

写法 下载时机 执行时机 是否阻塞 HTML
<script src> 立即 下载后立即 阻塞
<script defer src> 立即 DOM 完成后按顺序执行 不阻塞
<script async src> 立即 下载完成后立即(无序) 不阻塞解析,但可能中断

然后就是 CSS(href=stylesheet)的行为,因为渲染树需要样式信息,下载 CSS 会阻塞渲染,对性能影响较大。

最后就是媒体标签,比如 img、video、audio 中的 src,他们不阻塞 HTML 解析,但加载完成后可能导致页面重排或者重绘。

3、资源优先级

浏览器有内部优先级系统,从高到底举例:高优先级(Highest):CSS(渲染关键路径)、preload 资源(rel=preload);中优先级:JS 脚本(src);低优先级:图片、字体、prefetch / dns-prefetch(最低)。

三、工程化实践中的实际使用

1、性能优化

①脚本优化:defer / async / dynamic import
  • 主业务脚本 → 推荐 defer
  • 独立、不依赖任何脚本 → 推荐 async(如埋点)
  • Vue/Vite 中主入口 JS 默认使用 type="module" → 内置 defer
②样式优化:分割与预加载
  • 关键 CSS 内联(critical CSS)
  • 非关键 CSS 使用 media="print" + onload trick 延迟加载
  • 使用 preload 加快关键 CSS 下载
③图片优化:loading="lazy"

使用原生的懒加载属性

html 复制代码
<img src="xxx.jpg" loading="lazy">
④资源预加载策略

每一个 rel 都是性能优化工具,各有作用,具体的以后找机会再分享。

  • preload:用于当前页面关键路径上的资源。
  • prefetch:用于用户可能访问的后续页面资源。
  • dns-prefetch:用于所有外部域名(成本低,收益中)。
  • preconnect:用于确定要加载的外部域名(成本高,收益高)。
html 复制代码
<link rel="preload" href="/app.js" as="script">
<link rel="preload" href="/main.css" as="style">
<link rel="prefetch" href="/next-page.js">
<link rel="dns-prefetch" href="//cdn.example.com">
<link rel="preconnect" href="https://fonts.googleapis.com">

2、在 Vue / Vite 中如何使用 src 与 href

关于图片与静态资源处理 Vue/Vite 推荐使用模块化方式引入,而不是硬编码 URL:

html 复制代码
<script setup>
import logo from '@/assets/logo.png'
</script>

<template>
  <img :src="logo">
</template>

Vite 会自动将其转换为绝对路径,并自动处理 public和assets 的差异。

四、结语

src 与 href 看似只是两个普通的属性,但它们背后牵涉到浏览器解析与网络栈、脚本执行时机、性能优化、构建工具的特殊处理等内容,理解它们的底层差异,可以让你的页面加载更快、结构更语义化,代码更专业,提升"前端工程化"的实践效果。

只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~

其他热门文章,请关注:

极致的灵活度满足工程美学:用Vue Flow绘制一个完美流程图

你真的会使用Vue3的onMounted钩子函数吗?Vue3中onMounted的用法详解

Web Worker:让前端飞起来的隐形引擎

测评:这B班上的值不值?在不同城市过上同等生活水平到底需要多少钱?

通过array.filter()实现数组的数据筛选、数据清洗和链式调用

DeepSeek:全栈开发者视角下的AI革命者

TreeSize:免费的磁盘清理与管理神器,解决C盘爆满的燃眉之急

通过Array.sort() 实现多字段排序、排序稳定性、随机排序洗牌算法、优化排序性能

高效工作流:用Mermaid绘制你的专属流程图;如何在Vue3中导入mermaid绘制流程图

通过MongoDB Atlas 实现语义搜索与 RAG------迈向AI的搜索机制

深入理解 JavaScript 中的 Array.find() 方法:原理、性能优势与实用案例详解

前端实战:基于Vue3与免费满血版DeepSeek实现无限滚动+懒加载+瀑布流模块及优化策略

【前端实战】如何让用户回到上次阅读的位置?

el-table实现动态数据的实时排序,一篇文章讲清楚elementui的表格排序功能

JavaScript双问号操作符(??)详解,解决使用 || 时因类型转换带来的问题

内存泄漏------海量数据背后隐藏的项目生产环境崩溃风险!如何避免内存泄漏

MutationObserver详解+案例------深入理解 JavaScript 中的 MutationObserver

JavaScript中通过array.map()实现数据转换、创建派生数组、异步数据流处理、DOM操作等

相关推荐
会飞的战斗鸡3 分钟前
JS中的链表(含leetcode例题)
javascript·leetcode·链表
方也_arkling37 分钟前
别名路径联想提示。@/统一文件路径的配置
前端·javascript
毕设源码-朱学姐39 分钟前
【开题答辩全过程】以 基于web教师继续教育系统的设计与实现为例,包含答辩的问题和答案
前端
qq_1777673744 分钟前
React Native鸿蒙跨平台剧集管理应用实现,包含主应用组件、剧集列表、分类筛选、搜索排序等功能模块
javascript·react native·react.js·交互·harmonyos
qq_177767371 小时前
React Native鸿蒙跨平台自定义复选框组件,通过样式数组实现选中/未选中状态的样式切换,使用链式调用替代样式数组,实现状态驱动的样式变化
javascript·react native·react.js·架构·ecmascript·harmonyos·媒体
web打印社区1 小时前
web-print-pdf:突破浏览器限制,实现专业级Web静默打印
前端·javascript·vue.js·electron·html
RFCEO1 小时前
前端编程 课程十三、:CSS核心基础1:CSS选择器
前端·css·css基础选择器详细教程·css类选择器使用方法·css类选择器命名规范·css后代选择器·精准选中嵌套元素
烬头88212 小时前
React Native鸿蒙跨平台采用了函数式组件的形式,通过 props 接收分类数据,使用 TouchableOpacity实现了点击交互效果
javascript·react native·react.js·ecmascript·交互·harmonyos
Amumu121382 小时前
Vuex介绍
前端·javascript·vue.js
We་ct2 小时前
LeetCode 54. 螺旋矩阵:两种解法吃透顺时针遍历逻辑
前端·算法·leetcode·矩阵·typescript