script 标签上有那些属性,分别作用是啥?

每个前端开发者都在使用 <script> 标签,但90%的人只掌握了它20%的能力。本文将揭示那些能显著提升页面加载速度的隐藏属性!

一、基础属性:必备技能

1. src - 脚本来源定位器

作用 :指定外部JS文件路径
案例:引入第三方库

html 复制代码
<script src="https://cdn.example.com/vue@3.4.0.global.js"></script>

原理 :浏览器会发起GET请求获取资源并执行
对比

  • 行内脚本 <script>console.log('hi')</script> 适用于小段代码
  • 外部脚本更易缓存且复用率高

2. type - 脚本类型定义

作用 :声明脚本MIME类型或模块类型
高级用法

html 复制代码
<!-- ES模块(现代浏览器) -->
<script type="module" src="main.js"></script>

<!-- 旧式兼容 -->
<script nomodule src="legacy.js"></script>

动态类型案例

html 复制代码
<script type="application/json" id="config">
  {"theme": "dark", "apiBase": "/v2"}
</script>
js 复制代码
// 前端获取配置
const config = JSON.parse(document.getElementById('config').textContent);

二、加载控制:性能关键属性

1. defer - 异步延迟执行

作用 :不阻塞HTML解析,在DOMContentLoaded前按顺序执行

优化案例

html 复制代码
<head>
  <script src="analytics.js" defer></script>
  <script src="vender.js" defer></script>
  <script src="app.js" defer></script>
</head>

执行顺序
analytics.jsvender.jsapp.js(即使下载完成顺序不同)

2. async - 异步立即执行

作用:下载不阻塞解析,下载完成立即执行(无序)

适用场景:独立第三方脚本

html 复制代码
<!-- 广告/统计脚本 -->
<script async src="https://www.googletagmanager.com/gtag/js"></script>

对比表:defer vs async

特性 defer async
执行时机 DOM解析后,DOMContentLoaded 下载完成立即执行
顺序保证 按声明顺序执行 不保证顺序
适用场景 主业务脚本 独立第三方脚本
是否阻塞解析 下载时不阻塞,执行时阻塞

三、安全增强:保护你的应用

1. integrity - 资源完整性校验

作用:防止CDN资源被篡改(Subresource Integrity)

用法

html 复制代码
<script 
  src="https://cdn.example.com/react.production.min.js"
  integrity="sha384-9aVv5e0d3dJ7A00a4F7FZl2M4G4hqiqZ9M0Qb5thzP5Z"
  crossorigin="anonymous">
</script>

原理

浏览器会计算脚本SHA384哈希值并校验是否匹配

不匹配则拒绝执行

2. nonce - 内容安全策略

作用:防止XSS攻击,配合CSP使用

案例

http 复制代码
# HTTP Header
Content-Security-Policy: script-src 'nonce-EDNnf03nceIOfn39fn3e9h3sdfa'
html 复制代码
<script nonce="EDNnf03nceIOfn39fn3e9h3sdfa">
  // 内联脚本必须匹配nonce值才能执行
</script>

3. crossorigin - 跨域控制

作用:控制跨域脚本的请求模式和凭据发送

作用
anonymous 跨域请求不带Cookie
use-credentials 携带Cookie(需Access-Control-Allow-Credentials)

错误捕获案例

html 复制代码
<script 
  src="https://another-domain.com/error-monitor.js" 
  crossorigin="anonymous"
  onerror="fallback()">
</script>

四、前沿实战技巧

1. 动态脚本加载

javascript 复制代码
// SEO友好方案:先显示核心内容,后加载非关键脚本
window.addEventListener('load', () => {
  const script = document.createElement('script');
  script.src = 'lazy-analytics.js';
  script.setAttribute('async', '');
  document.body.appendChild(script);
});

2. 现代化模块加载器

html 复制代码
<!-- 现代浏览器加载ESM -->
<script type="module" src="modern.js"></script>

<!-- 老旧浏览器回退方案 -->
<script nomodule src="legacy.js"></script>

3. 预加载优化

结合<link rel="preload">提升性能:

html 复制代码
<head>
  <!-- 提前加载不阻塞渲染 -->
  <link rel="preload" href="critical.js" as="script">
</head>
<body>
  <!-- 实际使用 -->
  <script src="critical.js" defer></script>
</body>

效果对比

普通加载:⬛⬛⬜⬜ JS下载中...

预加载:⬛⬛⬛⬛ JS已准备就绪


五、其他

1. 脚本阻塞渲染怎么办?

症状 :页面白屏时间长
优化

html 复制代码
<!-- 错误 -->
<script src="heavy-script.js"></script> <!-- 阻塞! -->

<!-- 正确 -->
<script src="heavy-script.js" defer></script>
<!-- 或 -->
<script src="heavy-script.js" async></script>

2. 如何避免重复加载?

javascript 复制代码
// 动态脚本加载防重复
if (!window.myLibraryLoaded) {
  const script = document.createElement('script');
  script.src = 'library.js';
  document.head.appendChild(script);
  window.myLibraryLoaded = true;
}

3. 脚本加载失败处理

html 复制代码
<script src="essential.js" onerror="handleScriptError()"></script>
javascript 复制代码
function handleScriptError() {
  // 1. 加载备用CDN
  // 2. 降级到静态版本
  // 3. 显示用户通知
}

🌟 最佳实践总结

  1. 核心脚本 :使用defer保证顺序不阻塞

    html 复制代码
    <script src="framework.js" defer></script>
  2. 独立脚本 :使用async加速加载

    html 复制代码
    <script async src="analytics.js"></script>
  3. 动态资源 :结合preload预加载

    html 复制代码
    <link rel="preload" href="dynamic-module.js" as="script">
  4. 安全防护 :必须添加integrity校验

    html 复制代码
    <script integrity="sha384-..." src="https://cdn.com/lib.js"></script>
  5. 现代兼容:模块化方案

    html 复制代码
    <script type="module" src="app.mjs"></script>
    <script nomodule src="fallback.js"></script>

首屏关键脚本defer,非关键脚本动态加载,第三方用async,CDN资源必加integrity

相关推荐
brzhang31 分钟前
颠覆你对代码的认知:当程序和数据只剩下一棵树,能读懂这篇文章的人估计全球也不到 100 个人
前端·后端·架构
斟的是酒中桃1 小时前
基于Transformer的智能对话系统:FastAPI后端与Streamlit前端实现
前端·transformer·fastapi
烛阴1 小时前
Fract - Grid
前端·webgl
JiaLin_Denny1 小时前
React 实现人员列表多选、全选与取消全选功能
前端·react.js·人员列表选择·人员选择·人员多选全选·通讯录人员选择
brzhang1 小时前
我见过了太多做智能音箱做成智障音箱的例子了,今天我就来说说如何做意图识别
前端·后端·架构
为什么名字不能重复呢?2 小时前
Day1||Vue指令学习
前端·vue.js·学习
eternalless2 小时前
【原创】中后台前端架构思路 - 组件库(1)
前端·react.js·架构
Moment2 小时前
基于 Tiptap + Yjs + Hocuspocus 的富文本协同项目,期待你的参与 😍😍😍
前端·javascript·react.js
Krorainas3 小时前
HTML 页面禁止缩放功能
前端·javascript·html
whhhhhhhhhw3 小时前
Vue3.6 无虚拟DOM模式
前端·javascript·vue.js