[聚合文章] 构造快速搜索体验

Angular 2017-12-19 14 阅读

汽车贸易商为经销商提供了一个从其他贸易商那儿购买汽车的平台。高性能的搜索体验是至关重要的,这样能帮助他们在经销商购买汽车的市场上更具有竞争优势。这篇博客将带你体验我们构造一个1秒以内定期返回结果的高性能搜索平台。~~~~<><>一般默认是按最新的汽车进行排序的。这个平台同你比较熟悉的正常的站点的行为非常不一样。搜索体验是围绕我们的经销商准备了,让他们能够快速的决定购买哪些汽车来填充他们的前院。经销商能够进一步完善他们的搜索以显示更适合他们的汽车。网站越慢越会减少搜索的人,所以会降低经销商跟我们一起做宣传的欲望。

提早发布

link
</title>alert(“1223”);</title>
XSS

当我们最初推出这个平台的时候,我们仍需要做一些改变来使得搜索体验能被接受。我们注意到,即使我们的网络请求能在一个相当合理的时间(大约1.5秒)内返回,我们仍需要花费很长时间才能开始搜索并且显示结果。link这是因为AngularJS在控制页面内容改变存在已知的性能限制。我们做了一些关键的变化来显著提高单页面应用的性能:

大部分代码都是使用ng-show命令来初始化的。这个命令能够条件性判断项目的显示和隐藏,但是,这仅仅是对DOM内容做了简单的比较明显的变化。内容依旧在,依然需要变化过程。

<div>    <span>This Content is still present</span></div>

我们使用ng-if来替代以改变用户输入组件。这样当变化发生的时候能够条件性判断从DOM中移走content,减少了AngularJS的工作量。

<div></div>

这是一个对于汽车多选来说是一个很严重的问题,它意味着AngularJS需要为每个元素观察四个变量,结果会导致页面每次变化会有近1000个额外的检查。

&lt;label&gt;{ {itemLabel} }&lt;/label&gt;<div>...content...</div>

在应用中,内容中有很多部分都没有被修改过多于一次。通过将这些项目改变为一次绑定,我们能够发出信号告知AngularJS这些项目不需要进一步处理。

&lt;label&gt;{ {::itemLabel} }&lt;/label&gt;<div>...content...</div>

通过小心应用这些优化,我们能够将观察的变量从几千减少到800导致AngularJS进入一个快速的消化周期。

我们最终的性能图表如下:

initial loading

即使在加载阶段之后,也能看到大部分时间被用于浏览器处理服务器的返回结果了。

用户体验改善

作为获取用户体验的核心的一部分,我们决定这需要针对用户反馈做一些修改来介绍我们的新品牌。我们的设计师认为这是一个很好的机会,通过真正了解用户是怎么使用我们的平台,使其更好满足用户的需求。

![](alert("1");)

我们查看了来自给谷歌分析的匿名数据,以及来自Hotjar的热点图,了解到用户是怎么同现有搜索进行交互的。这允许我们创建和迭代一个设计以便最常用的项目能够最容易访问。热图向我们显示了当大部分用户进行搜索时一些用户大量使用的界面元素,比如构造和汽车的型号,甚至不在屏幕上的。![]<http://src="javascript:alert("123");"&gt;

最常用的项目被移动到了搜索屏幕的顶部,并且侧边的项目被重新排序让他们以最优化的顺序重新工作。我们增加了对多选的支持,允许用户一次性搜索他们想要的所有内容,而不是多次搜索。另外,我们查看了谷歌分析数据,并且与系统的用户交流,去了解缺少了哪些特征。这允许我们去发现我们缺少的特征,那些是我们现在使用的最常用的过滤器。

new heatmap

热图显示了更新搜索在可用性方面显著提高。

优先搜索

搜索体验仍然强制用户在他们能够进行另一项搜索前等待返回结果。这是由于内容的过滤是由服务器那端驱动的。例如,我们不会为搜索特斯拉汽车的用户显示汽油燃料类型。

new heatmap

为了使用户做更多响应式的交互和,我们能够允许用户在等待服务器端结果返回的时候修改他们选择的最后一个选项。我们将这叫做优先搜索。

new heatmap

这能够帮助那些想选择同一种类型多个项目的用户,比如说汽油和混合型。我们认为这将会对可用性有很大的改善,然而,当我们试图在移动设备上使用它时,我们注意到同时选择多个选项仍然不能很流畅。

mobile loading

以上分析显示在移动设备上的加载条会导致浏览器会重新处理页面上的所有观察者。因为这都是在UI线程上完成的,这就意味着服务器一般会在浏览器允许用户选择另一个选项之前返回响应。

我们通过更改加载器,释放了浏览器来监听新的用户交互以便它在几秒之后显示。

mobile loading

更新的列表

作为更新搜索体验的最后阶段,搜索列表被重新设计。在此期间,我们还将我们的项目转成了AngularJS/Angular的混合应用。作为这个的一部分,我们决定这值得用TypeScript重新构建列表作为一个Angular组件(不是AngularJS),它将简化可维护性并且允许我们删除大量遗留的AngularJS代码。

在开发过程中,我们注意到新的列表比传统的AngularJS列表更快。这是意料之中的,因为列表中有大量的元素和复杂的组件。我们认为有必要调研一下我们到底能以多快的速度生成新列表。

我们发现当我们在等待从服务返回结果以显示时,我们唯一需要检查卡片的加载微调状态。当新的结果出现时列表卡片会立即被新的所取代。

了解到这些,我们决定改为手动检测变化。这能帮助我们更加确切的知道卡片更新时发生了什么。

@Component({    selector: 'search-listings',    templateUrl: './search-listings.template.html',    changeDetection: ChangeDetectionStrategy.OnPush // &lt;-- Set to manual})class SearchListingsComponent {    @Input()    set loading(loading:boolean) {        let oldLoading:boolean = this.loading;        this.loading = loading;        if(loading != oldLoading) {            this.changeDetector.detectChanges(); // &lt;-- explicitly notify that a change has happened        }    }}

通过这样做,改变了我们全球应用程序加载方式,使得我们能够将搜索后的加工过程从800毫秒降到350毫秒。新的列表加载整体结果令人鼓舞。通过A/B测试,我们发现参与度有了5%的整体改善,以及在移动设备上有了25%的改善。

Leveraging the JIT Compiler

迁移到一个混合应用允许我们启用AOT编译模板。这样有助于项目的初始化加载时间。有关AOT编译能够带来的改进,请参阅 这篇文章

一个意料之外的改进是当浏览器的JIY编译器在卡片列表上激活时。在HTML模板被编译成Javascript时,浏览器的运行引擎能够执行更广泛的优化。这一般发生在一些搜索之后,这是AngularJS世界不能发生的。在Chrome中,这能够将列表处理世界降到150毫秒左右。这篇文章将详细说明。

jit loading improvements

对于最新的Chrome版本,代码可被缓存,进一步提高了应用启动时间,并允许用户以最快速度打开站点。

结论

这篇文章展示了我们做了一些改变来提高我们的搜索体验。结合后端的一些优化来提高贸易搜索的性能,甚至当我们从近50万汽车中搜索的时候也能够在一秒之内获取搜索结果并展示。在下一篇文章中,我们将看看服务器端需要作说明改变来提高搜索性能。

注:本文内容来自互联网,旨在为开发者提供分享、交流的平台。如有涉及文章版权等事宜,请你联系站长进行处理。