GithubHelp home page GithubHelp logo

blog's People

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

blog's Issues

Angular 跨页缓存设计

自去年开始,我将 AngularJS 引入到项目中,并逐渐推动公司产品核心模块进行重构,提升产品稳定性与开发效率。在前端架构演进的过程中,最艰难的不是理解 API,而是思维方式被颠覆后的的适应过程,在基于 AngularJS 的架构下,所有繁杂的事务都被高度抽象化。

这是给团队小伙伴的一次关于 AngularJS 的分享,整理自 PPT:

业务场景

  • 跨页选中操作,此时如何保存选中状态?
  • 分步骤操作,如何保存上一次的操作数据?

问题

  • Angular 跳转页面后,控制器实例被注销,数据也将被清除
  • Angular 没有提供跨页传递临时数据的特性

可选方案

A. 超级单页

使用同一个控制器与同一份实例,保证页面不被刷新

缺点

  • 无历史记录:不支持浏览器前进后退操作(体验差)
  • 无URL:不支持收藏与分享地址(如果应用出BUG,客户无法提供 URL,导致售后成本变高)

B. URL传递数据

通过 URL 查询参数传递数据

缺点

  • 可能引起安全问题
  • 不支持复杂的数据模型(只支持String类型)

D. Ng Service 缓存

使用 Angular Service 构建内存缓存

权衡后,采用此方案。

实践遇到的问题

唯一性难以保证

  • 可能因为意外使用了未清理的缓存引起 BUG

内存泄露

  • 过期的缓存得不到清理
  • 缓存会连同控制器一起被 Ng Service 持有(闭包的缘故)

基于路由缓存设计

保证唯一性

  • 在连续操作的页面 URL 中添加 cache key
  • 在控制器中根据 cache key 匹配缓存

cacheKey

// 取 URL 的 cache key
var cacheKey = $routeParams['cache_key'];

读写缓存

if (!AppCache.cache || AppCache.key !== cacheKey) {

    // 覆盖 service 缓存
    AppCache.cache = createCache();
    AppCache.key = cacheKey || Date.now().toString();
}

发送缓存

// 通过路由传递缓存
$scope.submit = function () {
    var queryParam = angular.extend({
        'cache_key': AppCache.key
    }, $routeParams);

    $location.search(queryParam);
}

解决内存泄露

  • $routeChangeSuccess 事件中清理缓存
  • 避免在控制器中创建缓存(解除闭包)

清理过期缓存

$rootScope.$on('$routeChangeSuccess', function () {
    if ($routeParams['cache_key'] === undefined) {
        AppCache.cache = {};
    }
})

封装 RouteCache 服务

高度抽象,屏蔽实现细节

API 设计(第一版)

// 读缓存
var routeCache = RouteCache(createCache);
var data = routeCache.getCache();
var cacheKey = routeCache.getKey();

// 通过路由传递缓存
$scope.submit = function () {
    var queryParam = angular.extend({
        'cache_key': cacheKey
    }, $routeParams);
    $location.search(queryParam);
}

API 设计(优化后)

// 读缓存
var data = RouteCache(createCache);

// 通过路由传递缓存
$scope.submit = function () {
    var queryParam = angular
         .extend({}, data, $routeParams);
    $location.search(queryParam);
}

问题:如何做到 URL 只显示 cache_key 而不暴露数据?

答案:使用原型继承,angular.extend 不会拷贝原型。

RouteCache 内部:

data = createCache();
data = Object.create(data);
data['cache_key'] = cacheKey;

Object.create(data) 是 ECMA5 增加的方法,原理类似:

Object.create = function (object) {
    function F(){};
    F.prototype = object;
    return new F();
}

RouteCache 服务完整源码

/*
 * 基于路由的缓存服务
 * 可以将任何数据模型缓存在路由参数中,适合处理跨页的数据传递
 *
 *  取缓存:
 *      $scope.data = RouteCache(cacheFactory);
 *  写缓存:
 *      $location.search(
 *          angular.extend(
*               {},
 *              $routeParams,
 *              $scope.data
 *          )
 *      );
 *
 * @author  糖饼
 */
define(['./services'], function (services) {

    services.factory('RouteCache', ['$rootScope', '$routeParams', '$cacheFactory',
        function ($rootScope, $routeParams, $cacheFactory) {

        var cache = $cacheFactory('RouteCache');
        var ROUTE_KEY = '@cache_key';
        var TABLE_NAME = 'CACHE';


        /*
         * @param   {Function}  缓存工厂
         * @return  {Object}    继承自缓存的对象
         */
        function Cache (cacheFactory) {

            var data = cache.get(TABLE_NAME);
            var routeKey = $routeParams[ROUTE_KEY];


            if (!data || cache.get(ROUTE_KEY) !== routeKey) {

                data = cacheFactory();

                // 继承缓存
                data = Object.create(data);

                cache.put(TABLE_NAME, data);
                cache.put(ROUTE_KEY, routeKey || Date.now().toString());
            }


            data[ROUTE_KEY] = cache.get(ROUTE_KEY);

            return data;
        };


        // 自动清理缓存
        $rootScope.$on('$routeChangeSuccess', function () {
            if (typeof $routeParams[ROUTE_KEY] === 'undefined') {
                cache.removeAll();
            }
        });


        return Cache;
    }]);

});

[前端招聘] 在海边写代码

banner

最开始这份招聘广告的标题是《厦门欢乐逛前端招聘》,当准备发出来的时候我突然意识到,我们还是一家“小公司”,这样千篇一律的招聘广告可能没有人想去点开,于是才有了这份看起来不那么正式的招聘广告。

先自我介绍下,我叫糖饼,欢乐逛前端团队的负责人,曾服务于腾讯 CDC 与 Qzone 团队;开源爱好者,也是 art-templatefont-spiderartDialog 等开源项目的作者。

公司大致情况:

  1. 互联网公司、非创业公司;电商系统服务商,旗下有著名的淘宝天猫店铺管理软件“欢乐逛”,2015 年登陆新三板
  2. 团队大概 170 多人,技术团队占了 1/3;管理层来自腾讯、阿里等一线互联网公司
  3. 公司在厦门观音山海边,地理位置得天独厚,午休时间可以步行去海边散步,这篇招聘广告题图就是我在楼顶拍的
  4. 高配 Macbook Air,可自购 Macbook Pro 自用,公司补贴
  5. 配备和鹅厂同款的人体工程学座椅,据行政 MM 说售价 3K+

公司最开始只有一个主打项目“欢乐逛”,后来基于垂直场景孵化了两个创业项目线,目前它们都已经处于盈利状态。我们业务大多数都是以 Web 承载的,如商品管理系统、会员与订单管理系统、图片编辑器、视频编辑器、商品页智能排版系统等等,它们对用户体验、性能要求都极高,因此能够折腾很多有意思的东西,包括业界一些非常前沿的技术。

岗位

我们有急招的几个名额,如果能在 2018-2-1 前入职,我们会补偿你的年终奖损失。招聘为长期需求,你可以随时联系我。

1. 前端工程师

级别:实习生、初级、中高级工程师

具体要求我就不写了,和大多数公司的要求一致。对于新人,面试过程会着重考察基础与学习能力;对于中、高级工程师,会着重考察技术沉淀或业务沉淀。

2. 前端图形图像方向

级别:高级工程师

可选工作内容:

  1. 在线图像编辑器,涉及到 Canvas 操作相关
  2. 在线视频编辑器,涉及到 WebGl、WebAssembly 以及视频剪辑相关技术
  3. 浏览器性能优化

3. Node.js 方向

级别:中、高级工程师

  1. 一年以上后端开发工作经验,计算机相关基础知识扎实
  2. 熟悉 Node.js 或 PHP 开发以及常用框架,并了解其差异及适用场景
  3. 熟悉 MySQL 数据库的使用以及优化

加分项

  1. 熟悉 macOS 或 Linux
  2. 代码洁癖者
  3. 自带其他技能,不限于设计、交互、后端、客户端
  4. 写博客,或者 Github 有超过 100 Star 的开源项目
  5. 有 Canvas、WebGL 或者 WebAssembly 相关技术经验
  6. 学霸

管理团队

王晓龙,来自腾讯 CDC 项目负责人,先后主导过 WebQQ、Global SNS、全平台的 QQ、QQ 群产品设计运营。

姚东旭,前腾讯资深技术,曾参与 QQ 会员在线、微云的核心开发,珠宝社区创业技术合伙人。

严舟,来自腾讯 ISUX,先后负责手 Q 吃喝玩乐的交互设计,腾讯课堂的整体设计团队。

王晶,前腾讯资深产品设计师,曾负责 QQ、QQ 音乐的设计。

前端团队

前端团队照片剪辑

前端团队目前有 18 人,有稀有的 Node.js 程序猿、性能优化狂热分子、Canvas 专家、Vim 信徒等、街舞爱好者、伪民谣歌手、伪设计师、伪摄影师等。

  • 产品经理基本不(敢)变更需求,活儿干完了准点走
  • 两周一次的前端技术分享会,生活委员会准备好一桌子的零食
  • 对于吃这件事情我们普遍比较讲究,按贵的来

我们使用

  • 源码管理:Git | GitLab
  • 框架与库:Vue | React Native | Angular
  • 打包编译:WebPack | Gulp
  • 后端环境:Node.js | PHP
  • 代码发布:Gitlib CI

我们使用的工具大多是主流的开源项目,也会将自己开发的分支回馈到开源社区,如 Webpack 代码压缩的 parallelcache 特性:uglifyjs-webpack-plugin/pull/77

应聘方式

[email protected]

除了高级工程师的岗位之外,第一轮面试题都是网上可以搜索到的基础问题,我不介意你提前准备;外地的同学我们优先采用电话面试。

最后,期待优秀的你能够来厦门这座“小”城市,与我们一起在海边写代码。

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.