有货移动Web端性能优化探索实践

发表于:2018-2-28 10:04

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:周奇琪    来源:51Testing软件测试网采编

  浏览器端缓存优化
  当存在缓存,可以减少浏览器的再次请求,大大提升了网页的打开速度,一个优秀的缓存策略可以缩短网页请求资源的距离,减少延迟,并且由于缓存文件可以重复利用,还可以减少带宽,降低网络负荷。那么下面我们就来看看服务器端缓存的原理。
  缓存优化 (max-age)
  页面的缓存状态是由 http 协议的 header 决定的,我们主要使用了 max-age(单位 S),设置缓存的最长有效时间,使用的是时间长短,例如说我设置 max-age=60, 也就是说在请求发出后的 60 秒内,浏览器再次请求时不会再请求服务器,而是从浏览器缓存中读取数据。
  预加载和懒加载
  预加载和懒加载是一对好兄弟,用的好,可以极高提升浏览器端的体验,就是要确定在何时预加载,何时懒加载。我们主要在浏览器首屏结束后,当浏览器相对 idle 的时候,可以预加载下一屏即将展示的内容。
  当用户在即将触发下一屏时,下一屏的数据或 DOM 已经 stay by 了,自然体验会流畅很多,但是在预加载是需要一个度,因为一个页面的 DOM 过多,对于浏览器占有的内存也会过多,预加载最好是用户即将触发需要浏览的内容,如第二屏,轮播后面的内容,tab 页等。
  懒加载的运用场景主要还是为了减少单次 DOM 渲染的大小,对于当前页面的非可视区域,当需要展示或用户事件触发才进行加载。所以懒加载和预加载,在不同的场景下会有不同的运用,前提是保障页面的流畅度。
  DNS 预读取
  DNS 预读取配置的 DNS 的解析,可以减少 DNS 的次数,也可以加速不同域名的资源加载,目前支持的浏览器还是比较多的。
  配置也很简单:
  <link rel="dns-prefetch" href="//cdn.yoho.cn">
  <link rel="dns-prefetch" href="//static.yohobuy.com">
  <link rel="dns-prefetch" href="//img10.static.yhbimg.com">
  <link rel="dns-prefetch" href="//img11.static.yhbimg.com">
  <link rel="dns-prefetch" href="//img12.static.yhbimg.com">
  <link rel="dns-prefetch" href="//img13.static.yhbimg.com">
  <link rel="dns-prefetch" href="//analytics.m.yohobuy.com">
  <link rel="dns-prefetch" href="//search.m.yohobuy.com">
  <link rel="dns-prefetch" href="//list.m.yohobuy.com">
  <link rel="dns-prefetch" href="//guang.m.yohobuy.com">
  当然最好的减少 DNS 的时间是减少站点使用 DNS 的数量, 我们会去掉部分二级域名。
  CSS,JS 的优化
  项目构建主要采用了 webpack 的工具链,对 css,进行依赖管理和构建打包,最小化 css,js,并针对我们现有的多页面项目进行多入口的分包管理。
  多页面 css 和 js 构建
  打包代码如下,便利 js 的源文件目录,构建各个页面模块的 js,所有的页面会包含两个 js 文件,libjs(全局公用的 js),xxx.js(当前页面特有的 js),css 也是一样。这样每个页面的 js 和 css 都会最小化,同时我们也对这些个静态字符串文件进行 gzip 压缩,当然这些文件会按照版本进行静态存储,以及 CDN 的缓存。
     // 构建各模块子页面 JS
      // 新的生成规则 module/page/index.js
      shelljs.ls(path.join(__dirname, '../js/**/index.js')).forEach((f) => {
          const dir = _.slice(f.split('/'), -3); 
          // Important
          // 生成规则:module.page: './js/module/page/index.js'
          entries[`${dir[0]}.${dir[1]}`] = path.join(__dirname, `../js/${dir.join('/')}`);
      });
  DOM 优化
  页面流畅度和 DOM 渲染和操作息息相关,渲染流程大致如下:
  处理 HTML 标记并构建 DOM 树。
  处理 CSS 标记并构建 CSSOM 树。
  将 DOM 与 CSSOM 合并成一个渲染树。
  根据渲染树来布局,以计算每个节点的几何信息。
  将各个节点绘制到屏幕上。
  可以使用 DEVTOOLS 分析整个渲染过程中那块存在性能问题。
  简化 DOM,DOM 操作优化
  简化 DOM 可以减少渲染过程的时间,优化 DOM 操作,可以减少重布局和重绘的时间。简化 DOM 在上面的首屏直出已经介绍过相应的做法。
  这里主要说下 DOM 操作的优化,第一,减少 DOM 操作次数,可以把多次 DOM 操作在 js 的执行过程中生成好结果 HTML,一次插入到 DOM;第二,尽量在使用不在页面 DOM 树里面直接操作,可以脱离文档流的 DOM 中进行操作,可以使用 fragment,一次插入文档流中。
  当然现在的 react 和 vue 都使用虚拟 DOM 的技术,通过 diff 算法进行通用化的 DOM 操作。这个也不失是一种效率高效的做法,但是对于一些不易优化的页面,还是需要人为干预和操作 DOM 使其性能最好。
  减少重布局和重绘
  第一,要减少布局调整,当您更改样式时,浏览器会检查任何更改是否需要计算布局,以及是否需要更新渲染树。对“几何属性”(如宽度、高度、左侧或顶部)的更改都需要布局计算。第二,绘制的复杂度、减小绘制区域:除 transform 或 opacity 属性之外,更改任何属性始终都会触发绘制。绘制通常是像素管道中开销最大的部分;应尽可能避免绘制。
  通过层的提升和动画的编排来减少绘制区域。可以使用 Chrome DevTools 来快速确定正在绘制的区域。打开 DevTools,按下键盘上的 Esc 键。在出现的面板中,转到“rendering”标签,然后选中“Show paint rectangles”。每次发生绘制时,Chrome 将让屏幕闪烁绿色。如果看到整个屏幕闪烁绿色,或看到你认为不应绘制的屏幕区域,则应当进一步研究。
  页面动画优化
  尽量使用 CSS3 的动画,使用 transform 和 opacity 属性更改来实现动画。使用 will-change 或 translateZ 提升移动的元素。避免过度使用提升规则;各层都需要内存和管理开销。此外,需要减少动画的图层,每多一个图层,会多一份内存占有和管理的开销。
  如果一定要使用 js 的动画,建议使用:requestAnimationFrame。此外,能不用页面动画的场景尽量不要使用动画,如果一定要使用,可以简化动画渲染的过程。
  之前我们使用过一个 js 插件,iScroll 就是一个案例,页面内初始化了多个 iScroll 实例,特别在安卓手机上特别卡顿,最后,我们的解决办法是自己使用 css3 动画和 touch 事件简单轻量的实现需要滑动的部分,对于页面滚动部分使用了原生的 scroll,保证了不同终端体验一致。
  总结
  移动 web 端的优化以上每个点如果展开去讲,都可以单独写一篇文章,我们分别在以上方面做了优化,并且,也产生了比较不错的效果,移动端的打开速度和体验都有了不错的提升,普遍打开的时间提升了 30-50%,在网络稳定的情况下,基本上服务端的耗时在 50ms 以内,首屏时间在 500ms 以内,但是优化这件事情是永无止境的,没有最好,只有更好,需要开发者探究根本勇于创新,达到更好的更优的境地。
  我们后续,还可以在 web 的基本技术点上深挖,同时在 PWA 以及 AMP 等现代 web 新思维的多个方面大家积极面对,继续探索,在未来的 web 前端之路可以走的更好,提供更优的用户体验,创造更高社会价值。
22/2<12
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号