前端 ES6 环境下 require 动态引入图片以及问题
ES6 环境中,通过 require 的方式引入图片很方便,一直以来也没有出过什么问题,后来项目中,需要动态引入图片。
require 动态引入也容易实现,百度也能搜到很多博客介绍。
偶然发现项目中 require 引入图片好像对打包体积影响挺大,js 会变大很多,经过测试,终于确定原因,这里记录一下。
本文主要包括:require 引入图片方式、打包体积对比。
import 引入与 require 引入区别
在 ES6 中,import 语句是静态执行的,意味着它们在模块内部的顶层执行,并且在模块内部创建一个局部作用域。
这意味着导入的变量只在模块内部可见,并且不会影响模块外部的变量。因此,使用 import 导入的变量是不会被提升的。
require 函数是动态执行的,这意味着它在运行时执行,并且不会在模块内部创建一个局部作用域。
因此,使用 require 导入的变量是可以被提升的。
如何理解import语句是静态执行的和require函数是动态执行的?
理解 import 语句是静态执行的和require函数是动态执行的,需要先了解这两个概念的含义。
静态执行是指在编译阶段就能够确定其执行结果的代码执行方式。
在 JavaScript 中,import 语句属于静态执行的代码,也就是说,当 JavaScript 引擎执行代码时,会在编译阶段对 import 语句进行静态分析,确定所导入的模块,并在运行时加载这些模块。
动态执行是指在运行时才能确定其执行结果的代码执行方式。
在 JavaScript 中,require 函数属于动态执行的代码,也就是说,当 JavaScript引 擎执行代码时,会在运行时动态地确定所需的模块,并加载这些模块。
因此,可以理解为:
import 语句是静态执行的,因为在编译阶段就能够确定所导入的模块,从而在运行时快速加载这些模块。
require 函数是动态执行的,因为在运行时才能够确定所需的模块,需要动态地加载这些模块。
值得注意的是,由于 import 语句是静态执行的,因此在代码中不能使用变量或表达式作为模块路径,而只能使用字符串字面量。而 require 函数则可以接受变量或表达式作为模块路径,从而动态地确定所需的模块。
详细解释见:一文了解js中导入模块import、import()和require()的区别
require 引入图片方式
1. 静态引入。
静态引入没什么可说的,根据相对位置或者绝对位置引入即可。
require('@/south/assets/image/skybox/sky1/00h+00.jpg')require('../assets/image/skybox/sky1/00h+00.jpg')
2. 动态引入图片
动态引入基本是有两种方式,实际效果相同,但是对体积的效果相差挺大。
第一种方式,变量拼接:
const imgName ="00h+00";require('../assets/image/skybox/sky1/'+ imgName +'.jpg')
第二种方式,占位符:
const imgName ="00h+00";require(`../assets/image/skybox/sky1/${imgName}.jpg`);
打包体积对比
引入图片体积,大概有 100K,0.1M:
1. 未使用 require 的体积。
2. 静态引入后的体积。
assets by status 4.64 MiB [compared for emit]319 assets
+50 assets
orphan modules 13.6 MiB [orphan]1484 modules
runtime modules 7.47 KiB 13 modules
cacheable modules 13.1 MiB
modules by path ./node_modules/.store/563 KiB 25 modules
modules by path ./src/south/12.5 MiB
./src/south/south.js +1408 modules 12.5 MiB [built][code generated]./src/south/assets/image/cluster/mark_red.png 2.48 KiB [built][code generated]data:text/plain;base64,iVBORw0KGgoAAAAN..1.06 KiB [built][code generated]url(ignored)15 bytes [built][code generated]zlib(ignored)15 bytes [built][code generated]https(ignored)15 bytes [built][code generated]http(ignored)15 bytes [built][code generated]WARNINGin asset size limit: The following asset(s) exceed the recommended size limit(244 KiB).
This can impact web performance.Assets:
staticForMap/js/south.cesium.js(4.05 MiB)
staticForMap/sphere/Assets/approximateTerrainHeights.json(268 KiB)
staticForMap/sphere/Assets/Textures/waterNormals.jpg(287 KiB)
staticForMap/js/south.cesium.js.gz(1.07 MiB)WARNINGin entrypoint size limit: The following entrypoint(s) combined asset size exceeds the recommended limit(244 KiB). This can impact w
eb performance.Entrypoints:south(4.05 MiB)
staticForMap/js/south.cesium.js
webpack 5.88.2 compiled with2 warnings in71740 ms
3. 使用 require 拼接变量的体积。
3. 使用 require 占位符的体积。
总结
如果项目本身体积很小,建议尽量不使用 require 方式引入图片。
使用 require 方式引入图片的话,尽量使用静态方式,必须动态引入的话,推荐使用占位符的方式引入。
另外,可以使用
image-webpack-loader
等工具进行压缩,体积会小很多。
另外,使用 webpack 配置
image-webpack-loader
压缩之后,会好很多!
版权归原作者 非科班Java出身GISer 所有, 如有侵权,请联系我们删除。