H5 优化了一段时间, 一直没有一个很好的总结到底做了哪些优化以及分析这些为什么会带来性能优化, 因此总结一下, 也是一个积累和学习的过程
一跨域
之前我们的接口都是在
mainsite-restapi.ele.me
下, 而我们的网址是 h5.ele.me , 这就会导致存在跨域问题, 对于简单请求 (即 GETPOST 和 HEAD 三种请求, 并且不能自定义 HTTP Headers) 会正常发送跨域请求, 但对于非简单请求来说, 例如接口每次会设置 Content-Type 为 application/json, 每次会先发一个 OPTIONS 请求来询问服务器是否支持有权限访问, 服务器通过返回
Access-Control-Allow-Origin
信息来告诉客户端, 然后客户端才会发送真正的请求
很明显的优化手段就是去掉所有 OPTIONS 请求, 利用 Nginx 的反向代理来处理这个问题我们现在的接口都走 h5.ele.me/restapi , 通过 Nginx 我们把请求代理转发到之前的
mainsite-restapi.ele.me
下, 这样仅仅通过 Nginx 配置解决了跨域问题, 从而减少了大量的 OPTIONS 请求
二接口
之前首页的接口每个对应了单独的功能, 例如八大金刚天气热词等虽然对于 HTTP/1.1 和 HTTP/2 来说, 可以建立持久连接, 减少建立和关闭连接的时间, 但是过多的请求还是会影响到页面渲染的时间对于这些请求可以使用一个接口来返回所有的内容, 当然这需要前后端共同做相应的修改
由于首页功能需求繁杂, 为了避免功能相互耦合, 起初我们开发的时候都是把各自的功能放在自己的组件里, 对于部分例如获取用户 ID , 判断是否为新用户, 等一些操作在每个组件里都请求了一次, 这样做是毫无意义的, 后来统一请求然后使用 vuex 传给其它组件
还有一个问题是首页的内容是强依赖于定位的, 所有的接口都要等到定位完成后才会请求但同时定位的逻辑是很复杂的, 会依赖支付宝内部的定位 H5 定位等, 同时为了定位的精确, 我们会请求用户的地址列表, 根据当前用户的定位地址获得最近的用户地址这样就导致了定位过程可能很慢, 因此做了定位的缓存, 对 30 分钟内的再次定位直接使用缓存并且考虑到当前获取到的定位和得到的用户地址理论上来说相隔不远, 这样对于餐厅列表, 这两个地址得到的结果应该相差不大, 我们可以提前用定位的地址请求餐厅列表, 当获取了用户地址后, 再用该地址请求下一屏餐厅列表
三使用 ES6
对于 ios 来说, 已经支持 ES6 语法, 但是对于 Android 来说, 支付宝内的内核是很老的版本, 因此我们在构建上打包两份代码, 通过测试代码检查浏览器是否支持 ES6 来决定下载哪个脚本. 对于 ES6 来说首先打包后的代码体积会明显缩小, 因此对于该脚本解析速度上来说有提升但是执行判断脚本会阻塞该业务脚本的下载与执行, 反而还没直接使用 ES5 来的好, 因此对于首页, 还是打包 ES5 , 其它页面则采用刚才所说的方法
但支付宝马上将会升级内核版本, 对于 ES6 会有比较好的支持, 对于进一步缩短平均渲染时间会有很大的帮助
四脚本加载
之前首页由于需要引用很多 polyfill, 都是先判断是否需要然后通过 document.write 来引入加载脚本, 这样做, 这些脚本都无法同时异步加载, 必须等前一个脚本执行完后, 后一个再加载执行这样无法充分利用浏览器的性能进行预加载和预解析
现在我们将 H5 需要的 polyfill 和 一些小库同时打包成一个, 减少加载的文件数, 并且可以避免 document.write 带来的弊端
五其它
其它的工作比如减少图片体积, 其实一直会注意把图片压缩后再上传然后就是代码层面上的优化比如将一些与首页无关的东西从首页剥离开等等, 当然对于代码上的优化来说对于性能的提升可能是微乎其微, 但是聊胜于无, 之后写代码也应该注意下时间复杂度, 并且避免在首页上堆加过多功能
References
HTTP 访问控制(CORS)
去掉你代码里的 document.write
更快地构建 DOM
来源: https://juejin.im/post/5a98e99b6fb9a028bc2d3035