本文做者:ziven 郑成忠前端
原创声明:本文为阅文前端团队 YFE 成员出品,请尊重原创,转载请联系公众号 ( id: yuewen_YFE ) 获取受权,并注明做者、出处和连接。程序员
前端重构程序员是一个关注代码同时还要留意体验的异类。代码的优化虽然难,可是有比较多的性能测试工具去证实优化的成果。然而体验这种东西,咱们又要如何去证实它的好与坏呢?web
1、视觉体验优化chrome
2、数据证实体验效果浏览器
今天我着重会基于「webnovel」PC站点从以上两点给你们介绍,如何从体验的角度去作重构的优化,并如何用数据去证实你的优化是有效果的。缓存
咱们要作体验的优化,首先要咱们要知道什么才是好的体验。服务器
不知道哪里听过这么一句话,「 好的体验,就是感受不到在体验 」。这句话听起来很矛盾,可是却和业界公认的体验小红书「 Don’t make me think 」的理念同样。你想用户来「 webnovel 」是来看小说的,不是来称赞咱们网页体验作得多么优秀的。当用户开始关注到咱们网站体验的时候,那正是说明咱们的体验很差的时候。框架
那用户在什么地方容易感觉到咱们网站的体验呢?工具
第一个地方就是页面加载的时候。这里咱们明显能够看到「 webnovel 」的 Logo 和三个小图标在页面刷新的时候,会有一瞬间从无到有的过程。性能
咱们「 webnovel 」站点是面向全球海外用户的,跳出了国内兼容 IE 浏览器的怪圈,因而在小图标这块咱们选择了浏览器兼容性要求高,可是呈现效果却更好的SVG图标「 SVG 属于矢量图标,在能保证体积更小的状况下,还能在放大缩小的时候不失真 」。咱们将 Iconfont 「来自阿里的在线图标管理工具 」自动帮咱们生成的 JS 代码引用到页面中,结果就出现了上面的呈现效果。
这个原理其实很简单,咱们 SVG 图标的 DOM 结构是在 JS 执行以后动态添加到咱们的标签内部的。因此就会出现先呈现页面,再呈现图标的效果。因而咱们很天然的想到,直接将 JS 生成的 DOM 结构放到咱们的内部,来解决这个问题。
可是很傻很天真,在拷贝 DOM 结构的时候咱们发现,这个 SVG 代码量也太多了,直接放到页面内部会大大增长咱们 HTML 的代码量,影响整个页面呈现的速度,这个感受是捡了芝麻丢西瓜。
最后咱们采用的解决方案是,把 SVG 图标作了拆分,首屏的显示的图标咱们采用直接添加 DOM 的方式,其它剩余的图标仍是选择 JS 动态加载老方法。这样首屏以外的图标即便有闪动用户也很难看到。因而咱们解决了首屏图标闪动的问题,也避免了 SVG 图标代码量的问题。用户感知不到图标的闪动,也就不会花时间去思考咱们页面加载是快是慢的体验问题了。
提早加载首屏数据,能必定程度上加强咱们用户刷新和跳转页面时候的体验。
第二个地方的就是咱们数据请求的时候。当咱们切换TAB的时候,能明显看到一个 Loading 的效果。用户的动做触发数据请求,在等待的过程咱们用 Loading 来告知用户这一状态,以减弱用户等待的焦虑。这实际上是一个对于数据加载,加强体验常规的作法。
但是无论咱们的数据请求多么的快,用户都仍是能明显能看到这个 Loading 的效果。这并非咱们想要的。
咱们这边处理的办法是,在用户鼠标放到这个按钮的时候,咱们认为用户是有了点击的意愿,因而咱们就提早发起了数据请求的操做。当用户按下这个按钮的时候,咱们的数据请求的整个过程可能已经结束,而这也就意味着咱们的 Loading 状态已经消失。此时用户就能直接看到咱们加载好的数据了。也就是说颇有可能,在整个过程当中用户是看到不到咱们的 Loading 状态的。这不就是咱们想要的体验上的优化吗?
利用用户操做的空闲时间,提早作一些预处理,不失为一个加强数据请求体验的好办法。
咱们都知道,图片和图标都是属于展现性的元素,特别是像咱们 「 webnovel 」网站设计师很用心制做的书封,咱们天然会愿意选择体积更大可是质量更高的高清图。为了不影响正文的展现,咱们又不得不选择了相似图片 Lazyload 的机制,让这个图片延迟加载。
可是能够明显看到这和以前的数据加载的 Loading 逻辑同样,须要一个表示 Loading 态的占位图。等图片加载完成,占位图会一瞬间被咱们的高清书封替换,因而此时就出现了咱们不指望的闪动。
当用户一看到闪动,他们就会去思考你这个加载是快仍是慢。可是咱们要的是 「Don’t make me think 」。咱们不但愿让用户去思考除开咱们产品以外的东西。因此咱们得想个办法弱化甚至去除这种闪动。
讲到这里呢就不得不科普如下咱们浏览器自己就有的图片缓存机制了。在必定时间段内你浏览器访问过的图片,会被浏览器缓存。当你再一次看到这个图片的时候,这个图片就直接读取浏览器缓存的内容一瞬就打开,不会有闪动问题。
因而咱们就想是否是能够利用这个机制,解决以前闪动的问题。可是如今难点是,咱们详情页的书封是比首页的书封大的。由于尺寸不同因此是不一样的图片,因而就没有缓存这个概念。
若是咱们让详情页也用首页的书封,详情页小图被拉伸就会看起来很模糊。若是首页用详情页的大书封,首页的图片数据加载开销又太大。
咱们这边采用的解决方案是,三层叠加法。咱们把占位图,小书封,大书封,按照上图的层级完美的叠在了同一个位置。当用户从首页进入到咱们详情页的时候,咱们占位图和小书封都是直接使用浏览器缓存瞬间呈现的,由于小书封是叠在占位图之上的,因此用户是看不到占位图的。而此时大书封正在加载,当大书封加载好了以后,就会盖在小书封之上。等用户仔细看这个书封的时候,这个大书封其实颇有可能已经加载完成。
从上图的GIF能够看出,整个过程就从以前的占位图到大书封的闪现,变成了如今的小书封到大书封的渐变。其实这是很难被用户发现的。
看到这里可能有同窗会问说,既然这里都看不到占位图,为何还须要加载这个图呢?其实缘由很简单,由于不是每一个人都是从首页进入到详情页的。有可能用户是直接打开的这个连接。那么此时占位图就回到了最初的逻辑。先看到占位图而后再看到书封。固然我也得认可对于这样的用户,咱们实际上是多加载了一个小书封的资源的。可是对于体验上的优化来讲,这一点资源的消耗我我的认为仍是能够接受的。
还有一个好玩儿的点是,在这个地方由于同时加载了,占位图,小书封,大书封,它们做为图片也都会被浏览器缓存,当用户跳转到其它页面的时候,若是有相同的图片,那又是瞬开的。这样咱们就充分的利用了浏览器缓存,让用户在咱们网站上的体验获得了进一步的提高。
图片缓存,让网站体验比好更好。
视觉层的体验优化是所见即所得的,你能够很快的看到优化的成果。可是有不少由于浏览器差别,或者用户差别引发的体验问题,咱们无法直观和快速的去证实体验优化的效果。咱们就得靠数据去证实了。
要用数听说话,首先咱们得有数据,而这个数据的收集工具咱们海外 PC 站用的则交给了来自 Google 的 Analytics。这边给你们讲关于这个的一个有趣故事。
有一天我在用 webpagetest 「 一个全球知名的测试网站加载速度的工具 」测试咱们 「 webnovel 」页面的时候我看到了这样一个结果。
你们注意看那个最长的绿色,看到了吧,一个 DNS 加载怎么比后面的 SSL + CSS 加载 + CSS渲染还要长?CSS 但是强制阻塞咱们页面渲染的重要元素,它要是慢了,你网站作再多优化都没有用。这个你让人怎么忍?
怎么办呢?咱们选择了一个暴力可是有效的办法,直接把 CSS 合并到咱们的 HTML 文件中 「 CSS 内联到 HTML 内部 」。CSS 文件都没有了,看你还怎么 DNS、SSL … 哇!好棒,我拿着这个去找老大邀功。老大啪啪给我提了两个点就把我打懵了。
第一, 你这个明显是首次加载页面时候的效果,对于大多数这个 CSS 文件已经有缓存的用户,你如何证实,这个优化对他们是又用的?
第二,「 webnovel 」是面向全球的网站,你又如何证实,这个优化对全部地区的用户的优化力度 ?
是啊我要怎么证实?「 webnovel 」全球这么多的用户,我就用一份 「 webpagetest 」 的测试报告去涵盖全部的终端和用户群体,显示是不具备公信力的。而且我又要如何证实这个优化的力度是多少?
此时中国好同事出现了,个人前端逻辑小伙伴帮我在框架机内部作了一个随机预处理的AB样本输出。道理很简单,就是让 50% 的用户是用原始的方式加载咱们的 CSS ,另外 50% 的用户使用咱们 CSS 内联到 HTML 内部的方式。这样我只须要加个标识符区别一下这两个样本,上报到 GA 「 Google Analytics 」 ,而后 GA 会自动帮咱们统计和处理这些样本,最后我只须要将这两个样本的平均值作一个 10 之内的减法,就知道了咱们的优化力度具体是多少了。
然而另外一个问题出现了,咱们应该把什么做为数据上报给 GA 呢?显然用整个网页的加载时间去证实 CSS 的加载是不对的。那我用 CSS 加载完成以后的那个时间去证实?但是我又怎么能证实 CSS 加载完成以后页面就已经渲染好了呢?咱们不是在作体验的优化吗?又怎么能仅凭借 CSS 文件的加载来证实用户体验变好了呢?
此时我是凌乱的。不行,整个场面我要HOLD住,不能慌。
体验,体验,CSS都没有加载,用户连页面都没有看到又怎么能叫体验?因而用户刚看到页面的时间,被我认定是必定程度上能够证实体验优劣的。
怎么去获取这个时间呢?其实利用 performance API,就能够获取到上图所示的浏览器各个阶段的时间。
Chrome浏览器 能够用 window.chrome.loadTimes().firstPaintTime; IE8+ 浏览器能够用 window.performance.timing.msFirstPaint;
来获取页面开始渲染的时间。最后你们一致的意见是,将这个 「 firstPaintTime - navigationStart 」的时间近似理解为用户从访问页面到看到页面的时间。
因而,我很开心的把这个这个时间上报到 GA,而后版本上线,等待数据收集。最后得出以下的统计结果:
看到以上的数据结果,这个优化的时间和总时间比起来比预想的差太多了。感受不该该啊?
当咱们仔细分析这个数据,发如今这整个的时间段内,服务端的时间占了 1.1s 。我在这拼命的优化体验,但是最后发现体验的瓶颈并不在咱们前端这边。这充分的说明,有的东西仍是得靠数听说话,而不是你觉得你觉得的就是你觉得的。固然除开这个瓶颈时间咱们能够得出以下的结论。
至此咱们有理有据的证实了优化体验的成果,虽然结果出乎了咱们的预料,可是却证实,数据上报是可以证实咱们体验成果的一个有理证据。
固然咱们也把这个瓶颈问题,反馈给力服务端的同窗。而后获得的答复是,「 webnovel 」还属于咱们海外站的新项目,不少海外服务器有待跟进。相信在后续设备以后,会解决这个痛点。
数据上报,让你的体验优化有理有据。
篇幅有限,这边我只是零散的列举了,我我的认为能够从用户体验角度去作的几点重构优化,以及如何利用数据去证实你优化的力度。但愿对于你们有必定的启发和帮助,有什么问题,也请给我留言,咱们能够深刻的交流。