我在Medium浏览帖子的时候发现他们的图片加载效果真的很赞诶。首先载入一个低像素的模糊图片,然后逐渐转变为高清大图。这个过程体验真的很好,所以我希望能够明白他们是使用什么方法做到的。
Medium的技术
我使用WebPageTest测试这个页面的载入过程。如果你希望能够测试同样效果,可以打开Medium的页面,禁用cache减慢图片申请加载的过程,所以加载出原图的时间会稍久。这样就可以清楚看到整个图片的加载效果。
具体执行过程
使用div限定好图片展示的区域,Medium使用<div>标签并加入padding-bottom样式设定对应图片的展示尺寸。通过这样占位的方式可以防止在图片加载后出现整体页面回流的情况。这种方法通常被称为intrinsic placeholders
加载小尺寸(像素低)的图片,此时网页会先请求一个像素质量较低的小号缩略图(大小为原图的20%).这个小图片使用<img />标签,因此浏览器会在标签加载完成后,立即请求图片资源。
只要图片加载完成,它就会被“画”到<canvas />中。图片数据会被main-base.bundle.js文件中自定义的Blur()函数重新计算,可以看到它会产生模糊图片的效果。尽管有些不同,不过该函数与StackBlur的模糊函数实现效果是相似的。在模糊图片生成的同时,浏览器也会开始请求高清原图资源。
最后原图被加载到页面上,canvas会被隐藏,只展示原图。
最后的最后,感谢CSS的动画功能,上述所有转变过程会很流畅。
Markup
整个展示图片的结构
XML/HTML Code复制内容到剪贴板- <figure>
- <div>
- <div/> <!-- 这个div用于做图片加载过程中的占位符 -->
- <img/> <!-- 低像素的缩略图 -->
- <canvas/> <!-- 给上面的缩略图加上模糊效果 -->
- <img/> <!-- 展示的高清无码原图 -->
- <noscript/> <!-- fallback for no JS -->
- </div>
- </figure>
- <figure name="7012" id="7012" class="graf--figure graf--layoutFillWidth graf-after--h4">
- <div class="aspectRatioPlaceholder is-locked">
- <div class="aspect-ratio-fill" style="padding-bottom: 66.7%;"></div>
- <div class="progressiveMedia js-progressiveMedia graf-image is-canvasLoaded is-imageLoaded" data-image-id="1*sg-uLNm73whmdOgKlrQdZA.jpeg" data-width="2000" data-height="1333" data-scroll="native">
- <img src="https://cdn-images-1.medium.com/freeze/max/27/1*sg-uLNm73whmdOgKlrQdZA.jpeg?q=20" crossorigin="anonymous" class="progressiveMedia-thumbnail js-progressiveMedia-thumbnail">
- <canvas class="progressiveMedia-canvas js-progressiveMedia-canvas" width="75" height="47"></canvas>
- <img class="progressiveMedia-image js-progressiveMedia-image __web-inspector-hide-shortcut__" data-src="https://cdn-images-1.medium.com/max/1800/1*sg-uLNm73whmdOgKlrQdZA.jpeg" src="https://cdn-images-1.medium.com/max/1800/1*sg-uLNm73whmdOgKlrQdZA.jpeg">
- <noscript class="js-progressiveMedia-inner"><img class="progressiveMedia-noscript js-progressiveMedia-inner" src="https://cdn-images-1.medium.com/max/1800/1*sg-uLNm73whmdOgKlrQdZA.jpeg"></noscript>
- </div>
- </div>
- </figure>
PS:实际图片大小要根据设备尺寸来设定。
尝试重新实现同样效果
我在CodePen重新通过使用CSS替代canvas实现同样的加载效果。下面的图片展示了整个加载过程中,图片的转变效果。
这么做是否值?
很明显,现在有许多种方法来实现同样的效果。要知道在几年前如此高性能的方式实现动画和模糊效果还是不可能的。但事实上,大多数时候延迟瓶颈,并不是设备本身的原因,因此这些技巧值得我们探索。 控制加载图片过程有以下优点:
懒加载:使用JS来请求资源让我们可以灵活控制图片资源选择。小图可以请求同一缩略图,大图则可以根据浏览器视窗大小来选择加载尺寸不同的图片。
更好的占位符: 相比于纯色占位符,使用缩略图添加模糊效果后会有更好的视觉效果,同时图片大小也只有2k左右不会牺牲负载。
裁剪图片大小:Medium根据访问设备的不同,返回不同尺寸的图片,这样可以很好的优化页面的加载速度,同时避免移动设备浪费过多流量。
其他版本
在实现Medium原方法之前,我觉得我可以在我的网站使用其他方法来实现。
内联图片数据
我们可以在img中添加缩略图的URLs来直接请求资源。这样做虽然会增加HTML的内容,但是可以加快占位符的生成速度。浏览器加载好HTML标签就立即下载图片文件资源。加了模糊效果后图片的质量就无所谓了,我测试使用0.5k大小的图片与2k大小的图片得到相似的显示效果。
模糊效果
默认情况下,当浏览器将一个小图像放大,它应用光滑效果处理图像的模糊效果。图像的效果也可以关闭,像QR码。
[…]the browser would render it in a way that didn’t make it look blocky[…] from Google Developers.
它可以在Chrome、Safari和Firefox中有效,尽管光滑效果在Chrome中更有效,你可以在这里看效果。
下面我们看看如何做到光滑效果。图片只有27px宽,并且像素非常低,将它放大会产生很可怕的效果。事实却并没有。如果上述效果能满足你的要求,那你就不需要更复杂的效果替换了。
上述图片模糊效果也可以使用CSS Filter Effects实现,它还支持IE浏览器哦(IE一生黑)。我相信Medium在使用canvas方法之前一定也尝试过使用这个功能更强的方法。但是可能是出于一定原因他们放弃了这一方法。这一方法的优点是你可以设定模糊度,并且可以通过CSS达成其他目的。
也可以使用SVG的filter来达成同样目的,如The “Blur Up” Technique for Loading Background Images 和 Textured Gradients in Pure CSS两篇文章提到的。
他们选择图片的一种主颜色,并用其作为占位块的背景色。这样做会给用户一种图片加载速度更快的体验。
更先进的方法:Facebook的200 byte技术
年初Facebook发表过一篇"The technology behind preview photos"的文章,这篇文章主要说明如何预览一个没有JPEG头的42 * 42px的图片。 使用场景有些不同,这“图片”被用于Facebook的手机端,它知道如何组成一个有效的JPEG图片。此处我们在Web端使用的话需要编写JavaScript代码,这样做同样会增加存储资源。当然我们可以通过在服务器端组成这个图片解决这一问题,但是这样仍需要一些JavaScript代码发送申请图片资源的请求。
无论如何,这个方法对于Web端来说有点大材小用,但我还是希望能够将其作为一个参考。Using WebP for generating this preview images同样可以节省内存,并且不需要使用如此创造性的解决方法。
LQIP: Low Quality Image Placeholders
与其等待最终的图像呈现,我们可以先提供一个高度压缩的图片,然后切换到大图。这就是LQIP方法的思路。这一方法与Medium相似,不过是使用相同尺寸,但压缩更高的图片。
总结
随着页面加载的图片越来越多,需要勤于思考页面的加载过程。因为这会影响加载效率和用户体验。 如果你生成几个缩略图大小的图片,你可以实验使用一个非常小的图片作为背景,等待最终图片被加载出来。
图片显示,优化,前端
《魔兽世界》大逃杀!60人新游玩模式《强袭风暴》3月21日上线
暴雪近日发布了《魔兽世界》10.2.6 更新内容,新游玩模式《强袭风暴》即将于3月21 日在亚服上线,届时玩家将前往阿拉希高地展开一场 60 人大逃杀对战。
艾泽拉斯的冒险者已经征服了艾泽拉斯的大地及遥远的彼岸。他们在对抗世界上最致命的敌人时展现出过人的手腕,并且成功阻止终结宇宙等级的威胁。当他们在为即将于《魔兽世界》资料片《地心之战》中来袭的萨拉塔斯势力做战斗准备时,他们还需要在熟悉的阿拉希高地面对一个全新的敌人──那就是彼此。在《巨龙崛起》10.2.6 更新的《强袭风暴》中,玩家将会进入一个全新的海盗主题大逃杀式限时活动,其中包含极高的风险和史诗级的奖励。
《强袭风暴》不是普通的战场,作为一个独立于主游戏之外的活动,玩家可以用大逃杀的风格来体验《魔兽世界》,不分职业、不分装备(除了你在赛局中捡到的),光是技巧和战略的强弱之分就能决定出谁才是能坚持到最后的赢家。本次活动将会开放单人和双人模式,玩家在加入海盗主题的预赛大厅区域前,可以从强袭风暴角色画面新增好友。游玩游戏将可以累计名望轨迹,《巨龙崛起》和《魔兽世界:巫妖王之怒 经典版》的玩家都可以获得奖励。
更新动态
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]