京东 PC 首页 2019 改版前端总结

距离上次首页改版,已有2年3个月零五天。相比上次改版对首页总体框架、开发流程的大刀阔斧(前两次改版总结传送门:2016版2017版),此次的改版看起来显得有点像跳水——没什么水花。在站在巨人肩膀上的小巨人的叮咛与期盼下,此次改版在延续17版的框架与流程的基础之上,为首页的稳定性、安全性、视觉体验、无障碍体验方面见缝插针地添了砖加了瓦。javascript

本文将从如下几个方面进行阐述

  • 引入强类型校验
  • 升级资源构建方案
  • 接入自动化测试
  • 完善监控体系
  • 优化页面加载体验:骨架屏
  • 优化信息无障碍体验

引入强类型校验

在性能几近无懈可击的状况下,咱们决定从稳定性入手,为项目引入强类型校验,弥补 JavaScript 这种弱类型语言在不可预测性上的缺陷。前端

强类型语言 TypeScript 已发布6年有余,国内应用的开发者也在慢慢增加。通常来讲,业务开发周期短,迭代频繁,TypeScript 的引入对于很大一部分开发者来讲是一件费时费力的事,用的话业务能够上线,不用的话业务照样能够上线,所以团队极少在业务生产中应用。但秉承着不折腾不凹凸的理念,新版首页不负使命的,进行了基于 TS 的重构。java

作 TS 重构并不难,把 js 后缀改为 ts 就行了。完。小程序

固然是开玩笑的啦!显然,这样的 TS 是没有意义的。只有严格遵循 TS 标准的代码才能最大化 TS 的效用。在项目中,咱们对 TS 的检查开启 strict 模式,每次提交时,都会对代码作一次完整的检查,只要有 TS 报错就禁止提交,旨在向成员传达一个信息——写强类型语言就该有觉悟,不然就是耍流氓浏览器

没有深刻使用过 TS 的同窗在前期可能会感到人生的艰难,但这些都是为你好为了保证代码的健壮性。例如,在以往难以定位、查找的 window 全局变量的管理上,十分令开发者头疼,而引入了 TS 以后,只要对全局变量进行了接口设置,各个组件中不再会出现多余或是未知全局变量的状况。再例如,在写一个拥有 getset 方法的存贮类的时候,TS 能帮助检测获取内容的类型:缓存

interface MemoryState {
  testa: boolean
  testb: string
}

class Controller {
  state: StateType

  constructor() {
    this.state = {
      state: {},
    }
  }

  get<K extends MemoryStateKeys>(key: K) {
    return this.state.memory[key]
  }

  set<K extends MemoryStateKeys>(key: K, value: MemoryState[K]): MemoryState[K] {
    this.state.memory[key] = value
    return value
  }
}

复制代码

当咱们使用 new Controller().get("testb") 的时候,TS 可以在开发阶段检测 testb 是不是 string 类型。经过 TS 的检测插件,咱们能放心的使用 string 类型对象的方法,简化繁复的判断逻辑,同时保证代码在获取到非指望值时能及时经过报错发现,一切的输入和输出都是稳定可预测的,四舍五入就是在写代码的时候自动走了一部分测试,为项目的开发与迭代保驾护航。安全

升级资源构建方案

旧版首页项目使用的构建工具 Athena,推动了开发流程自动化,可是涉及到定制化的构建流程时,因为 Athena 的通用性,不方便直接作改动。首页包含直出、同步、异步三种类型的资源引用,需对资源的打包进行特殊处理,因此咱们此次回归 Webpack,基于 Webpack 4.0 作了如下的方案优化:性能优化

发布流程优化

发版流程

旧版的发布流程中,每次发布须要对改动的文件进行 diff 检查,避免产生不符合预期的误改动。Webpack 默认打包机制的特色,是根据模块的打包顺序为每个模块提供一个按顺序编号的 ID,对文件的包进行依赖管理。旧版首页的入口文件包含依赖包管理的执行环境,所以任何一个包引入顺序发生变更时,入口文件都会发生变更。以上的打包机制会出现一个文件发生引入顺序变更时,可能会影响到编译后的几个甚至十几个文件发生变更的状况,而这些文件中的逻辑代码部分其实并不须要更新,这就下降了 diff 代码的准确性,使得这一中间检查措施失去了本来的意义。首页缓存机制与资源懒加载机制使得静态资源在发布时,须要对发生变更的文件进行 CDN 缓存清除的操做,也就意味着,改动文件越多,须要清除的缓存资源连接就越多,而连接越多,因为缓存清除不一样步引发的资源异步加载出错的几率就越高,每次上线发布都存在必定的风险。markdown

为了减小发布风险,新版首页的打包机制改变了 Webpack 的打包逻辑,经过设置,每一个模块再也不经过顺序编号的 ID 管理依赖包,而是经过文件目录生成哈希编码的专有 ID,并把依赖包的执行环境从入口文件中抽离出来做为一个单独的资源请求,这样每次改动文件时,能够只针对改动的文件 diff,剔除了其余非预期的 diff 状况。经过新的构建方案,使代码改动控制在预期的范围内,保证部署流程的稳定。架构

项目架构优化

旧版页面的性能优化方案中,包含了部分 js 片断直出,这些代码是项目所依赖的基函数,须要在核心 js 代码执行以前启动。但这样的方案也有一些不尽人意的地方:

  • 因为代码须要直出于页面模版中,考虑到兼容性,这些代码不能使用一些高级语法,每次改动都须要确保本身的代码没有兼容问题,致使维护成本巨高。同时,首页页面模版由后台负责管理,直出代码的改动需通过后台发布,迭代成本略高,风险也不小;
  • 因为打包的限制,核心代码与模板代码存在同一套公用代码,代码冗余不说,一旦这部分代码发生变更还须要同时修改与发布两部分的代码,使得代码的维护成本增高。

针对以上问题,新版中咱们将这些代码从新放入核心代码,模板代码中再也不承载任何逻辑代码,迭代发版再也不涉及模版发布,只需进行静态资源的发布便可,开发过程当中统一使用 JS 高级语法,去除人工维护兼容语法代码的过程。

至此,咱们经过加强资源打包的可预测性、以及优化项目资源架构两个方面对资源的发布方案进行了优化。

接入自动化测试

一个页面开发完成后,在对其进行提测以前,对页面进行自测是一个必不可少的环节。一方面,保证页面所开发的功能能正常运做;另外一方面,保证在对一个功能进行开发时,没有影响到页面其余区域功能的正常使用。

通常状况下,自测须要人为手动地进行测试,但这样会有两个缺点,第一,须要测试的区域数量过于巨大,类似的测试操做过于频繁,浪费了人力,也影响了测试的效率;第二,人为的自测因为没有统一的自测规范,所以在测试时很容易有所疏漏,从而忽视了一些看似微小,实则影响巨大的 bug,花费了大量的时间,却得不到自测所须要的效果。针对这种状况,咱们产生了实施自动化测试的想法。以新版首页为例,咱们经过使用 Nightwatch.js,为新版首页建立了一个自动化测试脚本,对新版的首页的73项用例进行自动化测试。

结果显示,经过自动化测试,在不到三分钟的时间内,完成了对新版首页73项用例的测试,这也意味着,若要经过自动化测试,来对任一页面进行自测,自测的时间均可控制在五分钟之内,而且准确性更高。将自动化测试应用在发布前以及上线后5分钟以内,及时检查测试用例,保证每次发版的安全。

完善监控体系

旧版页面的前端监控体系覆盖了浏览器信息、页面加载测速、楼层隐藏方面,但信息通知较为滞后,且仅覆盖了页面 onLoad 时间,收到告警信息时,没法作到快速定位问题。

参考京东购物小程序目前的监控机制,新版首页针对代码报错、接口可用性增长了上报监控。

代码报错监控:BadJS

经过 BadJS 框架捕获页面报错,并分析处理报错信息上报至京东 BadJS 服务。经过上报数据,咱们能够获得报错的详细信息以及发生次数。经过分析上报数据,能够发现一些潜在的问题,及时修复,保证首页代码的健壮性。同时根据上报数,还能够预估出一个问题所形成的影响范围,便于预估损失。

badjs

业务可用性监控

本次改版,在可用率上报系统中为首页补充了特定断定规则,包含调用次数、可用率、和 TP(性能指标)三个维度,在此基础上还能够对这三个维度进行环比,以减小误报的可能性,近期系统还上线了红灯告警-语音通知功能。

可用率上报系统通常被用来监听接口可用性,但对于首页来讲,除了接口,还需关注楼层隐藏的状况。目前的兜底方案中,每一个楼层中的模块接口兜底所有失效的状况下,会隐藏当前楼层。楼层一旦发生隐藏,则意味着出现了比较严重的问题,需快速关注并解决。可用率上报系统可作到触发告警规则时,1分钟以内即推送通知,精确到接口,便于及时发现问题,及时止损。须要注意的是,如何设置一套可以较为精确反映问题发生、减小假报警的阈值尤其重要,毕竟狼来了喊多了,也就等于没有监控。

测速上报

这一部分延用了旧版的 Athena 测速上报方案,并对一些与业务数据上报重复的部分作了减法,同时增长了接口的测速上报,完善故障追溯数据体系。

优化页面加载体验:骨架屏

旧版页面懒加载的占位方案采用了统一区域 loading 动画的方式,这种方式的优点在于复用成本低,适配性强。但若是遇到较大面积的模块或是模块较为密集的状况时,区域 loading 动画的体验有所降低————要么是空白区域过大,要么是 loading 动画过于密集,模块加载过程形成的视觉差别感知较为明显。而对于 PC 首页来讲,空白区域过大是主要存在的问题。

低网速下旧版首页的 loading 体验

此次改版,咱们引入了骨架屏方案,最终目的是以灰色豆腐块的形式尽可能缩小真实模块结构与加载占位之间的视觉差别。执行起来能够按照视觉差别分为两种对应关系:

骨架屏方案

  • 弱对应关系:只对模块进行标题、子项等主要内容进行块化处理,复用性较高,适配性中等;
  • 强对应关系:以视觉效果为基础,对子项进一步做出图片、文案的块化处理,针对占位面积较大、内容更为复杂的子项进行更细化的块化拆分,复用性低,适配性高。

考虑到首页的特殊性,咱们最终选择了强对应关系的骨架屏方案,并为了可扩展性,使用的是使用样式渲染的骨架屏,而不是直接使用图片占位。除了开发成本的上升,页面首屏加载代码量也有所增长。

代码量对比

项目结构

使用骨架屏所要达到的效果包含如下几点:

  • 提早占位,在页面的加载中滚动条不发生较为明显的跳动;
  • 页面快速滚动时也能看到骨架屏样式的占位。

也就意味着骨架屏的内容须要与页面作同步加载处理,结合懒加载组件,骨架屏组件需提早做为 loading 结构传入,并保证样式在页面渲染的第一时间进行加载,不然就失去了骨架屏的意义。

每一个须要骨架屏样式的组件,单独拆分出一个 placeholder 组件。组件内的占位结构包含两类样式——颜色与尺寸定位,加上容器外层的动画效果样式。颜色样式全页公用,尺寸定位样式与正式组件公用:

尺寸定位样式与正式组件公用的目的是为了在未来组件样式发生变化时,保证骨架屏与正式样式的统一修改,避免出现样式修改上的遗漏,但同时增长了样式的维护成本。同时样式编写与拆分的过程当中也须要开发者注意兼容骨架屏的样式,例如须要占位豆腐块的容器间距 padding、margin 的选择都很重要。所以此次首页的骨架屏尝试并不适合快速复用至其余项目。

新版首页骨架屏 loading 体验

优化信息无障碍体验

互联网信息无障碍,即针对视力障碍人士所提供的辅助。系统级别的辅助主要依赖读屏工具,读屏工具能够解决网页端信息无障碍 60%的阻碍,剩余的 40%须要在网页开发的过程当中由开发者进行体验优化。

没有作任何信息无障碍处理的网页,使用读屏工具访问时通常存在如下几个问题:

  • 多余无用信息的播报,例如:跳转连接、图片名称;
  • 弹出浮层没法访问;
  • 懒加载内容直接跳过;

为了造福国内一百一十人中的一个视障人士(数据来自这里),本次改版,咱们决定在 PC 首页开启京东商城桌面端首个信息无障碍实践。

桌面端视障用户的操做主要经过键盘进行。针对刚才提出的几个问题,PC 首页初步的无障碍体验优化方案分为几个阶段。

第一阶段,语义化一切 tab 可及的元素——包含页面外跳转连接的 a 标签统一添加 aria-label 属性,以便读屏软件可以简化读取元素信息;

第二阶段,保证页面主要模块的访问——懒加载内容占位容器将 tab-index 设置为大于 0 的值,使得 tab 键可以遍历到,以便触发页面懒加载,避免 tab 直接跳过;

第三阶段,扩展带弹出浮层等元素的操做——针对无障碍增长弹出浮层交互逻辑,入口增长 aria-haspopup 属性,告诉读屏软件这里是弹出浮层的入口,将 tab-index 设置为大于 0 的数值使得 tab 操做可聚焦到,浮层弹出后焦点自动聚焦至浮层;

第四阶段,为视障用户额外增长快捷跳转——参考 Google 搜索结果页,可在页面的顶部,增长一些隐藏的快捷跳转。PC 首页本次对搜索框以及底部的“为你推荐”位置增长了隐藏跳转连接,只有使用键盘操做的用户可以定位到。

对于商城页面来讲,第一阶段能知足基本的内容访问,而若是能作到第四阶段,才能算一个完整的信息无障碍网站。商城业务中,无障碍体验一直缺少相应的规范与测试流程,所以经过本次 PC 首页的改版实践,输出了一份针对商城频道页的信息无障碍开发规范,内容包含:

  • 访问路径设计规范
  • 语义化规范
  • 读屏测试规范

将来将借由这份规范,陆续实现商城其余业务的无障碍体验优化。

综上,本次改版对于开发者来讲最大的变化,就是本地开发体验更加舒服、发布风险有所下降、故障追溯更加完善,而对用户来讲,页面加载跳动感大大减少,视障用户的体验终于得以照顾到。做为商城桌面端的入口与门面,首页的改进必定不止于此,但愿每一次的改版都能有一丝的优化,使得首页这个项目趋近完美。

相关文章
相关标签/搜索