当我把前端条件加载做到极致

各位网友晚上好,相信大家都对使用type="module"和nomodule这种技巧有所耳闻。今天我将为大家分享我把这种技巧应用到极致的经验:4 条件加载方案。

什么是分条件加载

在前端构建中,我们通常需要进行 Babel 语法降级和 polyfill 插入等操作以兼容低版本浏览器。但这会导致一个问题:在现代浏览器中也会加载大量兼容性代码,无法享受浏览器原生支持的新特性带来的性能优势。

分条件加载的核心思想是:为不同能力的浏览器提供差异化的构建产物。最基础的实现就是利用 HTML5 标准中的type="module"和nomodule属性进行区分:

html 复制代码
<!-- 仅供参考 -->
<script type="module" src="modern-bundle.js"></script>
<script nomodule src="legacy-bundle.js"></script>

这样在支持 ES Module 的浏览器中会加载type="module"的脚本,而不支持的浏览器会忽略这个标签并加载带有nomodule属性的脚本。通过这种方式,现代浏览器就能直接运行原生 class、ES Module、解构赋值等新特性,无需加载冗余的兼容性代码。

3 个条件的分条件加载

由于IE8与IE9之间有巨大的差异,因此在上述2个版本的构建产物之上,使用条件注释在分出第3个版本专用于IE8及以下。

html 复制代码
<!-- 仅供参考 -->
<!--[if gte IE 9]><!-->
<script type="module" src="modern-bundle.js"></script>
<script nomodule src="legacy-bundle.js"></script>
<!--><![endif]-->
<!--[if lte IE 8]>
  <script src="ie8-bundle.js"></script>
<![endif]-->

这样IE8及以下加载特制兼容包可以更加精简,其他版本也能避开恶心的兼容代码。

为什么需要分4条件加载

分3个版本似乎己经够用了,但是随着top-level-await的出现,变得不够用了。使用type="module"和nomodule分版本的一个目的就是能使用原生esmodule 。而top-level-top出现后,无法用旧有的esmodule实现top-level-await。因此只能使用传统方式,比如构建成AMD格式 ,用AMD加载器加载。因此我们可以进一步细分出一个版本。 现在我们有4个版本了

  • IE8及以下
  • 不支持原生esm的版本(chrome4~chrome60)
  • 支持原生esm但不支持top-level-await(chrome61~chrome89)
  • 原生支持top-level-await的浏览器(chrome90+)

注意哦,上面最新的版本是chrome90,现在都chrome130+了,随着浏览器的更新,我希望用新浏览器的用户能够直接运行新特性,因此我需要用一个较新的特性做区分,于是我选择了Promise.try。现在的4个版本改变为

  • IE8及以下
  • 不支持原生esm的版本(chrome4~chrome60)
  • 支持原生esm但不支持Promise.try(chrome61~chrome127)
  • 原生支持Promise.try的浏览器(chrome128+)

这里我选择了Promise.try 是因为我还没有在公司推开es2025的使用,业务人员是不允许使用es2025的特性,代码中也必然不存在es2025的代码。等我在公司构建工具链中做完了es2025的降级处理,就会把用Promise.try判断,改成用更新的特性来判断。

html 复制代码
<!-- 仅供参考 -->
<!--[if gte IE 9]><!-->
<script type="module">
if(Promise.try){__import__("xxxx")}else{__import__("yyyy")}
</script>
<script nomodule src="legacy-bundle.js"></script>
<!--><![endif]-->
<!--[if lte IE 8]>
  <script src="ie8-bundle.js"></script>
<![endif]-->

最后我们看看打包后的运行效果。我们发现在最新浏览器中没有polyfill引用,也可以原生运行top-level-await。

总结

通过多条件加载,可以在全浏览器兼容的前提下,减少新式浏览器的加载内容大小。分4版本条件加载,是做到极致的水平。

相关推荐
加班是不可能的,除非双倍日工资3 小时前
css预编译器实现星空背景图
前端·css·vue3
wyiyiyi4 小时前
【Web后端】Django、flask及其场景——以构建系统原型为例
前端·数据库·后端·python·django·flask
gnip4 小时前
vite和webpack打包结构控制
前端·javascript
excel4 小时前
在二维 Canvas 中模拟三角形绕 X、Y 轴旋转
前端
阿华的代码王国5 小时前
【Android】RecyclerView复用CheckBox的异常状态
android·xml·java·前端·后端
一条上岸小咸鱼5 小时前
Kotlin 基本数据类型(三):Booleans、Characters
android·前端·kotlin
Jimmy5 小时前
AI 代理是什么,其有助于我们实现更智能编程
前端·后端·ai编程
ZXT5 小时前
promise & async await总结
前端
Jerry说前后端5 小时前
RecyclerView 性能优化:从原理到实践的深度优化方案
android·前端·性能优化
画个太阳作晴天5 小时前
A12预装app
linux·服务器·前端