Webpack中能否在项目构建阶段获取图片的宽度和高度?
Webpack + 懒加载图片避免爆米花式布局偏移的落地方案
你这套构建期预计算图片尺寸的思路是完全可行的,没有运行时额外开销,是解决这类布局偏移最优的方向之一,具体落地可以按下面的方式做,完全能达到你预期的编译效果:
Webpack构建层实现
- 最省业务代码的方式是写一个极简Babel插件,编译阶段扫描所有
<LazyLightbox>组件的JSX节点:- 拿到
thumbSrc对应的静态图片路径 - 用
fast-image-size在Node构建进程里同步读取本地图片文件的宽高参数 - 直接把你写的
thumbWidth={() => xxx}、thumbHeight={() => xxx}函数式属性,替换成静态字面量值,编译产物和你预期的完全一致,不会残留任何运行时计算逻辑
- 拿到
- 如果你不想写Babel插件,也可以直接调整图片资源的导入逻辑:配置自定义图片loader,在Webpack处理图片资源时同步计算宽高,导入图片时直接拿到带尺寸的对象:
// 业务代码里直接导入,构建时自动替换 import { src: thumbSrc, width: thumbWidth, height: thumbHeight } from './assets/thumb/demo.jpg'; // 组件直接传值即可 <LazyLightbox src={imageSrc} thumbSrc={thumbSrc} thumbWidth={thumbWidth} thumbHeight={thumbHeight} /> - 注意点:如果是响应式页面,不要把宽高写死为
200px这类固定像素值,优先把宽高转成比例值传给组件,用CSS的aspect-ratio属性做占位,适配不同屏幕宽度时不会出现拉伸或者布局错位。
懒加载组件层适配
拿到预计算的尺寸参数后,组件里的占位逻辑可以进一步优化,彻底消除布局抖动:
- 占位容器不要写死固定宽高,设置
width: 100%适配父容器宽度,同时设置aspect-ratio: 宽度值 / 高度值,不管容器尺寸怎么变,占位区域的比例和真实图片完全一致 - 可以提前把体积小于1KB的缩略图转成base64,作为占位容器的模糊背景,加载过程中视觉体验更好,也不会产生额外网络请求
- 真实的
<img>标签一定要带上原生width和height属性,现代浏览器会在资源加载前就根据这两个属性预留好布局位置,哪怕CSS做了响应式适配也不会出现偏移 - 图片加载完成后加150ms左右的淡入过渡,避免资源突然出现带来的视觉跳变。
轻量替代方案
如果不想改构建逻辑,也可以在图片资源命名时直接带上宽高信息,比如demo-thumb_200x120.jpg,Babel插件或者loader里直接用正则从文件名里提取宽高即可,比读取文件头计算尺寸的构建速度更快。
内容的提问来源于stack exchange,提问作者Anthony Cregan
相关产品推荐
相关产品推荐

