惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

L
LINUX DO - 最新话题
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
PCI Perspectives
PCI Perspectives
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
H
Heimdal Security Blog
S
Security @ Cisco Blogs
N
News | PayPal Newsroom
J
Java Code Geeks
罗磊的独立博客
Security Archives - TechRepublic
Security Archives - TechRepublic
N
News and Events Feed by Topic
V
V2EX
WordPress大学
WordPress大学
Google Online Security Blog
Google Online Security Blog
N
News and Events Feed by Topic
www.infosecurity-magazine.com
www.infosecurity-magazine.com
月光博客
月光博客
AI
AI
小众软件
小众软件
The GitHub Blog
The GitHub Blog
MongoDB | Blog
MongoDB | Blog
A
Arctic Wolf
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
美团技术团队
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Hacker News - Newest:
Hacker News - Newest: "LLM"
T
Tailwind CSS Blog
S
Schneier on Security
博客园 - 三生石上(FineUI控件)
F
Full Disclosure
B
Blog RSS Feed
Forbes - Security
Forbes - Security
S
SegmentFault 最新的问题
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
人人都是产品经理
人人都是产品经理
云风的 BLOG
云风的 BLOG
Jina AI
Jina AI
Cisco Talos Blog
Cisco Talos Blog
U
Unit 42
Project Zero
Project Zero
H
Hacker News: Front Page
Y
Y Combinator Blog
Application and Cybersecurity Blog
Application and Cybersecurity Blog
The Cloudflare Blog
大猫的无限游戏
大猫的无限游戏
S
Secure Thoughts
The Hacker News
The Hacker News
Microsoft Azure Blog
Microsoft Azure Blog

Mengke's blog - Mengke's coding journey

年轻不是健康的免死金牌 深圳工作机会,前端 2025 年终总结 Skill 不是 MCP 的替代品:我理解的渐进式披露与选型原则 独立开发者如何开具发票 香港银行卡开户完整指南(2025年9月最新) 招商银行储蓄卡微信动账提醒恢复方法 再谈 MCP - Model Context Protocol(MCP)详解和开发教程 Get Human-Readable "Time Ago" in TypeScript 以「asset-price-mcp」为例,从 0 开发 MCP Server Model Context Protocol (MCP) 快速开始 DeepSeek + Dify 搭建本地知识库 An elegant solution for implementing optional property types using TypeScript 2024 年终总结 Quickly Create a Fullscreen WebView with Autoplay Support for Testing 以数字开头的 ID 在 querySelector 中的处理 String casing utilities in JavaScript Check if a string is a valid color Simple Event-Emitter/PubSub pattern Find which process is running on a certain port and kill it Markdown Code block's basic and advanced syntaxes Common npm commands to use locally Pnpm aliases How to safely rename a case sensitive file/directory in a git repo? A custom hooks to use an async effect A custom hooks to use local storage state 🤩 Mengke'blog 上线的这一年 🗼 五月底去了一趟日本,记录一下我的游记和攻略 闰年之约 - 2024年2月29日 A collection of some useful websites 2023 年终总结 WebGL 学习笔记(一)基础概念与实践 Android Webview <video> 标签去除默认播放按钮图 📷 纯前端也可以实现「用户无感知录屏」? Getting Spotify token to display now playing track on your website AVP - Web 端特效视频播放器 IndexedDB 基础入门 直接下载网易云音乐中歌曲MP3格式的方法 什么!一个项目给了8个字体包??? flex 布局中 start/end 和 flex-start/flex-end 的区别 深入 Pinia:从代码出发探索 Vue 状态管理的奥秘 Pinia 快速上手指南 Nest.js Typrorm 多对多关系如何创建 Strapi 快速入门 CentOS7 MySQL 数据库安装与卸载 Next.js 上手指南 Vue 数据响应式原理 deno 快速上手 - Hello World 案例 快速上手 Vue3 尝鲜 Vue 3.0 Combination API react-router-dom 路由基础教程 JavaScript 数组扁平化处理的方法总结
网站性能优化:如何高效预加载大型静态资源
Mengke · 2024-04-07 · via Mengke's blog - Mengke's coding journey

最近正在开发一款类似于养宠物的养成类网页游戏。虽然这个游戏并不是传统意义上的游戏,主要是为了增加用户粘性,让用户在APP中能找到一些新的乐趣。

我曾经也做过类似的游戏,这类网页的一个特点就是有很多非常炫酷的动效,这类动效体积很大。

当遇到大文件时,我们必须进行一些优化。对于这些资源,我希望在需要展示的时候可以不需要等待直接展示。最理想的方法是进行预加载,让浏览器在闲暇时提前去下载这些资源。

因此,今天我们来谈谈前端几种“推测性加载”机制。

浏览器推测加载机制

推测加载有多种机制:

  • 预取 涉及在需要渲染文档(或文档的一部分)之前获取渲染文档(或文档的一部分)所需的部分或全部资源,以便在渲染时可以更快地实现渲染。
  • 预渲染 更进一步,实际上渲染了准备在需要时显示的内容。根据具体操作方式,这可能会导致从旧页面即时导航到新页面。
  • 预连接 涉及通过抢先执行部分或全部连接握手(即 DNS + TCP + TLS)来加速来自给定源的未来加载。

允许浏览器在正式发出 HTTP 请求之前预先执行一些操作,如 DNS 解析、TLS 协商和 TCP 握手,从而减少往返延迟并节省用户时间。通过在 HTML 中的 <link> 标签中添加 rel="preconnect" 属性,可以告知浏览器预先建立与特定域名的连接,提高页面加载速度。Preconnect 技术的运用可以消除很多请求中的往返路径,极大地改善了页面加载性能。

如果一个页面需要与许多第三方域建立连接,将它们全部预连接可能会适得其反。<link rel="preconnect"> 提示最好只用于最关键的连接。对于其他连接,只需使用 <link rel="dns-prefetch">,以节省第一步 DNS 查询的时间。

当浏览器请求某个跨域资源时,需要先将域名解析成 IP地址,然后才可以发出请求,这个过程就是 DNS解析。

浏览器提供一个提示:用户可能需要来自指定资源来源的资源,因此浏览器可以通过抢先执行该来源的 DNS 解析来提高性能。它与 相同,<link rel="preconnect">只是它只处理 DNS 部分。

preload 通常用于指示浏览器在渲染页面之前提前加载某些重要资源,一般用于加载当前页面必要的关键资源。不太常用,因为有可能导致首屏渲染变慢。

大多数现代浏览器会在解析 HTML 文档时开始预加载指定的资源。这意味着浏览器会在主 HTML 文档解析过程中检测到 preload 标签,并尽早开始下载相应的资源,以便在当前页面渲染过程中使用。

预加载的资源通常与主文档的下载并行进行。这意味着浏览器会尽可能地利用可用的网络连接来同时下载主文档和预加载的资源,以加快整体页面加载速度。

我们也可以对 preload 的优先级进行控制,preload 标签支持使用 as 属性来指定资源的类型(例如,as="style"as="script" 等)。浏览器可能会根据资源的类型和网页的渲染情况来调整加载的优先级,确保关键资源能够尽快加载。 预加载的触发条件可能因浏览器而异。有些浏览器可能会考虑页面的加载状态和用户行为来触发预加载,以避免在用户可能不需要的情况下浪费带宽和资源。例如,当用户即将点击链接时,浏览器可能会预加载链接指向的页面。

向浏览器提供有关当前页面上哪些 JavaScript 模块具有高优先级的提示,以便浏览器可以尽早开始下载它们。它是专门用于预加载 js 模块的 “preload”。与 rel=preload 的工作方式基本相同,区别是浏览器不仅会预加载缓存,还会将它直接编译倒内存中的模块映射中。

prefetch 是预获取的意思,主要用于提前加载未来可能用到的资源,但不一定会在当前页面加载完成后立即使用。

和 preload 预加载的主要区别是加载的时机不同,preload 是在浏览器解析到该标签时即触发加载,而 prefetch 则是在浏览器空闲时再触发加载。

如果你使用 vue 的异步组件,你会发现它也是用 prefetch 实现的。

⚠️这是一个已经弃用的、非标准的功能,请不要使用。

<link rel="prerender" href="/next-page"**>** 在页面中加入这个标签后,就告知浏览器下次导航可能会跳转的页面,浏览器可以提前加载该页面的资源并离屏渲染该页面,以便在跳转到该路由的时候可以直接显示。

这种通过链接 rel=prerender 提示进行的旧版预渲染已被弃用,取而代之的是 NoState Prefetch,后者会提取未来页面所需的资源,但不会完全预渲染页面,也不会执行 JavaScript。NoState 预提取可以通过提高资源加载速度来帮助提高网页性能,但无法像完全预渲染那样提供即时网页加载。

怎么做

首先对几种推测性加载方法进行了简要介绍。

如果要处理的是体积较大的动画资源,而且首屏加载不能受到影响,那么"rel=prefetch"无疑是最为合适的解决方案。只需要从接口获取到全部资源列表后,在 <head> 中插入 <link> 标签即可,具体的加载时机则交给浏览器来判断。

不过很遗憾的是,这个连 IE11 都兼容的特性 Safari 并不兼容,这就使得在 Safari 浏览器上这个标签不会起任何作用,资源不会被预加载。

对于 Safari 我们只能另外想其他的办法了,最简单的就是通过请求去加载了。

因为在页面 onload 之后渲染主线程可能并不会空闲,没了浏览器的支持我们怎么才能判断当前的渲染主线程是否空闲?

有一个 requestIdleCallback 函数,当主线程空闲时会调用回调方法,从而可以在空闲时做一些操作。不过更加遗憾的是 Safari 目前只在预览版本中支持这一函数,正式版本还不支持。

既然没有办法得知主线程的空闲状态,又不想占用主线程,那么只有一个办法了,通过 Worker 去新起一个函数来专门做加载就可以了:

worker.js

main.js

然后加一个判断,当支持 prefetch 时使用 prefetch,不支持时使用 Worker:

这样就通过不同方式实现了 Chrome 和 Safari 的大文件预加载,结合CDN的缓存策略,能让用户享受到更流畅的使用体验。

(完)