店铺体验优化总结

Create at 2021 04 2918 min read技术JavaScriptReact阿里巴巴性能优化

本文整理了近两年来国际站店铺在体验优化上做的努力和探索,也取得了不错的成果,分享出来希望对其他类似场景能有帮助。

性能优化大体上可以分为网络性能优化和交互体验优化:

  • 交互体验优化,优化页面的交互体验,滚动是否顺滑,点击反馈是否及时,操作是否有卡顿等
    • 避免 DOM 的重绘和重排
      • DOM 操作尽量减少或者进行操作合并
      • 动画元素尽量采用 absolute 等脱离文档流的定位
    • 确保对用户的操作反馈及时,刷新率保持 60fps
      • 保证每一个 js 任务在 1000/60=16.67ms 执行完毕
      • 复杂计算交给 woker 进程
  • 网络性能优化,大多数情况是要进行首屏性能优化
    • 减少 ttfb 的时间
      • 减少 dns 查询、TCP 握手建链、ssl 建连
      • 避免 302 redirect
      • 减少后端

Rax 代码转换到 React

Create at 2019 08 0129 min read技术JavascriptBabelReactRax

背景

最近接手公司的一个移动端项目,是通过 Rax 作为 dsl 开发的,在发布的时候构建多分代码,在 APP 端编译为能够运行在 weex 上的代码,在 H5(跑在浏览器或者 webview 里面,不管什么技术我们统称 H5) 端使用降级的 weex

这一套开发体系,看起来很完美,一次开发,三端运行。但是真实在开发的时候,就不是这么完美了。由于毕竟是跑在 weex 上的,而不是浏览器。所以在开发方式上也很难直接从 web 端的开发方式平移过去,为了实现跨端运行,所以在样式上只实现了 Css 的子集, DOM API 也是如此,开发的时候,在浏览器里面调试的时候,一切正常,但是等发布到 APP 端用 weex 跑的时候又是各种问题,开发体验很不流畅。

当然,有人会说那是因为你对 weex 的 api 不了解,也对,~~一直以来对与这种自己搞一套非标准体系来实现各种魔法功能的东西都不怎么感兴趣~~ 但是如果了解它的成本大于了它带来的收益,那么对我们来说,

indexedDB 不完全指南

Create at 2017 12 0617 min read技术JavaScriptindexedDB

介绍

引用 MDN 的介绍:

IndexedDB 是一个事务型数据库系统,类似于基于 SQL 的 RDBMS。 然而不同的是它使用固定列表,IndexedDB 是一个基于 JavaScript 的面向对象的数据库。 IndexedDB 允许您存储和检索用键索引的对象; 可以存储 structured clone algorithm 支持的任何对象。 您只需要指定数据库模式,打开与数据库的连接,然后检索和更新一系列事务中的数据。

IndexedDB  是一种低级 API,用于客户端存储大量结构化数据(包括, 文件/ blobs)。该 API 使用索引来实现对该数据的高性能搜索。虽然  Web Storage  对于存储较少量的数据很有用,但对于存储更大量的结构化数据来说,这种方法不太有用。IndexedDB 提供了一个解决方案。

区别

这是我整理的 WebStorage 和 indexedDB 的之

JavaScript 中的类和继承

Create at 2016 03 229 min read技术JavaScriptinherit

我们都知道 JavaScript 是一门基于原型的语言。当我们调用一个对象本身没有的属性时,JavaScript 就会从对象的原型对象上去找该属性,如果原型上也没有该属性,那就去找原型的原型,一直找原型链的末端也就是 Object.prototype 的原型 null。这种属性查找的方式我们称之为原型链。

类的实现

由于 JavaScript 本身是没有的类的感念的。所以我们如果要实现一个类,一般是通过构造函数来模拟类的实现:

function Person(name, age) {
  //实现一个类
  this.name = name
  this.age = age
}
var you = new Person("you", 23) //通过 new 来新建实例

首先新建一个 Person 的构造函数,为了和一般的函数区别,我们会使用 Camel

用ES6重构fullPage

Create at 2016 02 224 min read技术JavaScript

用 ES6 重写了 fullpage-light.js。 主要做了一下修改:

  • 模块化:将整个文件问个成多个独立的模块,每个模块负责一个功能
  • 新语法:替换一些新的语法,比如变量声明的 let,const,Object.assign 等
  • 转码:因为目前浏览器还并不支持 ES2015,所以还需要用 Babel 做一下转码

模块化

根据功能,将整个文件分割成为了五个模块。

-bootstrap.js   //方法和功能
-constant.js    //一些常量
-event.js       //绑定的事件
-index.js       //入口
-utils.js       //工具函数

这样原来一个很大文件就被分割成为了五个独立的模块,每个模块只负责自己的功能就好,维护起来会方便很多。

新语法

做手机商城接到一个需求。 具体大概是这样子的,要求用户点击购买按钮后,直接显示输入密码的弹窗并弹出键盘。 拿到需求一想,这挺简单的。 就麻利的写了个模拟的密码输入框,然后在用户点击购买按钮的时候让他弹出来,并且让焦点 focus 在 input 框上。 Chrome 上一试,完全没问题,觉得自己简直太棒了有没有。可是拿出自己的手机一试,oh no ~,键盘直接把页面给推了上去,导致完全看不到弹窗弹的是个什么东西。 解决前 但是在 Android 上是没有任何问题的。观察了下是因为 Android 和 ios 上键盘弹出的行为是不一样的,Android 上键盘弹出来,直接覆盖在原来的页面上,而 ios 上键盘弹出来的时候会直接把整个页面推上去。 怎么解决呢?其实也挺好解决,就是针对不同系统 hack 一下。

购买页面这个弹窗的定位是这么定位的:

// 后面的遮罩
.dialog-wrap {
  width: 100

react-v2ex

Create at 2015 12 265 min read技术JavaScriptReact

为了练手,用 react 写了个 v2ex 的首页: 页面地址 项目地址

整个项目基础 react 搭建,样式本来打算用 inlineStyle 来写的,但是发现写起来太累,于是还是用回到 sass,最后用 webpack 来编译。本来想着看能不能直接调用 V 站的 API 来做一个纯前端的首页,所有的数据都用 ajax 来调,但是发现因为跨域的问题,前端无法拿到数据,也就放弃了,最终也只能是一个静态页面。

说一下写代码中遇到的一些问题吧,首先整个项目的文件结构如下:

│  .babelrc
│  .editorconfig
│  .eslintrc
│  .gitignore
│  index.html
│  index.js
│  package.js

为什么要搭这么一套框架

公司 Pc 端以前遗留的项目,都是基于 jekyll+ruby-sass 这一套比较老的技术搭建的。不过 jekyll 的模版继承加上 sass 强大预处理能力,同时配合 Grunt 做任务管理,一切还是很得心应手的。

然而随着项目规模的急剧增大,这一套东西的速度是在是太慢了,一至于后来一旦这个项目有需要求要改我就头疼,倒不是说头疼需求怎么改,而是你随便改一个文件,从 jekyll 检测到改动到编译完 sass 到浏览器自动刷新,基本需要 40+ s,这完全不能接受。

于是一直就打算新搭一套开发环境,刚好前段时间有个新项目,我就拿来操刀动手了,目前已经用它做了俩个项目下来,在原有基础上做了一些修改之后,已经完全可以替代原来那一套懂了。

性能

得益于 node-sass 对 ruby-sass 在编译速度上的碾压以及被 jade 完爆的 jekyll。现在项目中从文件变动=>编译完成=>浏览器自动刷新,整个过程在 1s 左右,可以说速度提升了几十倍。 而且整个过程都是全自动的,无论

项目初衷

前段时间接到一个新的项目,是一个整屏滚动的单页应用。

本来打算完全自己写的,但是由于项目时间吃紧,就用了fullpage这个框架。这个框架确实很强大,几乎你想要的 API 它都有,所以用起来也很方便。

但是它也有几个缺点,第一它必须依赖 jQuery,而且文件体积也比较庞大,对于移动端来说不是很友好。于是自己就抽出业余时间,写了这个项目。

项目地址

一个简单的 DEMO

changeList

V1.3.0

  • 修复对 firefox 的支持
  • 添加页面导航控制
  • <

初试 react-router

Create at 2015 10 095 min read技术JavaScriptReactreact-router

react-router 提供简单有强大 API 来方便我们在React搭建的单页面中实现路由功能。 首先看一个简单的例子:

import React from "react"
import { findDOMNode, render } from "react-dom"
import { Link, Route, Router } from "react-router"

let Page1 = React.createClass({
  render() {
    return (
      <div>
        <h1>Page1</h1>Lorem ipsum dolor sit amet, consectetur adipisicing elit.
        Ab accusantium animi dicta dignissimos earum eos esse impedit ipsum iste