41
55+1 прием для улучшения JavaScript-кода Бабич Татьяна Руководитель Frontend отдела компании SimbirSoft

55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

  • Upload
    ontico

  • View
    260

  • Download
    3

Embed Size (px)

Citation preview

Page 1: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

55+1 приемдля улучшения JavaScript-кодаБабич ТатьянаРуководитель Frontend отдела компании SimbirSoft

Page 2: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

На старт! Внимание! Марш! Проект будет больше, чем предполагается

Состав команды может поменяться

Время реализации сильно ограничено

Page 3: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

Соблюдайте LIFT - принципы 1

locate

identify

flat

try to stay DRY

LIFT

-

-

-

-

Соблюдайте LIFT - принципы.

Page 4: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

Соблюдайте LIFT - принципы.

Спустя парумесяцев

controllers/LoginController.jsRegistrationController.jsProfileController.jsSearchResultsController.jsFeedController.js

directives.jsfilters.jsmodels/

Feed.jsCartModel.jsProfileModel.jsSearchResultsModel.jsUserModel.js

services/FeedService.jsCartService.jsUserService.jsProfileService.js

Page 5: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

Соблюдайте LIFT - принципы.

Спустя полгодаcontrollers/

LoginController.jsRegistrationController.jsProductDetailController.jsSearchResultsController.jsUsersController.jsUsersProfileController.jsOpinionController.jsInstrumentsController.jsFeedController.jsRecoveryController.jsNavigationContoller.js

directives.jsfilters.js

models/CartModel.jsProductModel.jsSearchResultsModel.jsUserModel.jsNavigation.jsRecovery.jsFeed.jsInstruments.jsOpinion.jsUsers.jsUsersProfile.js

services/...

Page 6: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

Модульность

Модульностьproduct/

search/ SearchResultsController.js SearchResultsModel.js

ProductDetailController.jsProductModel.jsProductService.js

user/LoginController.jsRegistrationController.jsRecoveryController.jsUserModel.jsUserService.js

instruments/ InstrumentsController.jsInstrumentsModel.jsInstrumentsService.js

feed/FeedController.js FeedModel.jsFeedService.js

Page 7: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

Принцип единой ответственности

Модульность

2

Page 8: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

/* directives.js */

angular .module('app.project')

.directive('orderCalendarRange', orderCalendarRange)

.directive('salesCustomerInfo', salesCustomerInfo)

.directive('sharedSpinner', sharedSpinner);

function orderCalendarRange() { /* implementation details */}

function salesCustomerInfo() { /* implementation details */}

function sharedSpinner() { /* implementation details */}

/* calendarRange.directive.js */

angular .module('sales.order') .directive('acmeOrderCalendarRange', orderCalendarRange);

function orderCalendarRange() { /* implementation details */}

/* customerInfo.directive.js */ angular .module('sales.widgets') .directive('acmeSalesCustomerInfo', salesCustomerInfo);

function salesCustomerInfo() { /* implementation details */}

/* spinner.directive.js */

angular .module('shared.widgets') .directive('acmeSharedSpinner', sharedSpinner);

function sharedSpinner() { /* implementation details */}

Page 9: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

Применяйте единый codestyle. Используйте анализаторы кода. Включите их в систему контроля версий

4

Модульность

Соблюдайте правила именования переменных3profile.controller.js ProfileController.js

Page 10: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

Создайте константы для всех переменных от сторонних библиотек в вашем проекте

5

Модульность

Оптимизируйте ваши «велосипеды», тестируйте их, а главное документируйте

6

Page 11: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

1 модуль = 1 задача

Модульность

приватностьслабая связность

Модульность

независимость

Page 12: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

Создавайте много небольших независимых модулей

Создавайте ре-используемые модули9

8

Модульность

Создавайте главный модуль и не загромождайте его7

Page 13: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

Модульность

Используйте IIFE10

;(function() { ... var app = angular.module('myApp'); ...})();

console.log(app) // not defined

Page 14: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

Переносите логику из контроллера в фабрики и сервисы12

Контроллеры

Формируйте $scope в определенном месте11

Контроллеры

Page 15: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

Используйте синтаксис controllerAs

Контроллеры

<div ng-controller="UserController as user"> {{ user.name }}</div>

function UserController() { this.name = {}; this.someFuncion = function() { };}

function UserController() { var vm = this; vm.name = {}; vm.sumeFunc = function() { };}

Для шаблонов Для контроллеров

или

13

Page 16: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

function User() { angular.extend(this, {

someVar: { name: 'Name'

},anotherVar: [],doSomething: function doSomething() {

} });}

angular .module('app') .controller('User', User);

Контроллеры

Замена vm синтаксиса

Page 17: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

Задавайте отдельный контроллер для каждого шаблона

// route-config.jsangular .module('app') .config(config);

function config($routeProvider) { $routeProvider .when('/user', { templateUrl: 'user.html', controller: 'UserController', controllerAs: 'vm' });}

<!-- user.html --><div></div>

14

Контроллеры

Page 18: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

Используйте одноразовую привязку данных {{:: ... }}

Не используйте ng-class для установки CSS свойств, если это возможно сделать средствами только CSS

17

16

Минимизация количества $watcher - ов

Правильно используйте $rootScope15

Минимизация количества $watcher-ов

Page 19: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

Минимизация количества $watcher - ов

Переносите манипуляции с DOM в директивы19

Не храните ссылки на DOM элементы в $scope18

Избегайте работы с большими данными21

Создавайте директивы с изолированным $scope20

Page 20: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

Используйте track by для циклов22

Минимизация количества $watcher - ов

Переносите тяжелую логику из фильтров в контроллеры и сервисы

24

Удаляйте ненужные фильтры23

Page 21: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

Используйте $watchCollection вместо $watch (с 3-им параметром).Избегайте установки флага objectEquality в true

$scope.$watch(…, …, true);

26

Минимизация количества $watcher - ов

Откажитесь от использования $watch там, где это возможно25

Page 22: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

Отписывайтесь от watches и event listeners27

Минимизация количества $watcher - ов

var stopFunction = $scope.$on('someEvent', function() { ... }); // Обработчик добавленstopFunction(); // Обработчик удален

Page 23: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

Если это возможно, сокращайте количество вызовов ng-model

ng-model-options=”{debounce: 250}”

Старайтесь избегать использования ng-mouse-over и подобных директив

29

28

Оптимизация $digest вызовов

Оптимизация $digest вызовов

Page 24: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

Избегайте использования сокращенного синтаксиса объявления зависимостей без учета минификации кода

angular .module('app') .controller('Dashboard', Dashboard);

function Dashboard(common, dataservice) {}

30

Аннотация внедрения зависимостей

Аннотация внедрения зависимостей

angular.module('app').controller('Dashboard', d);function d(a, b) { }

Page 25: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

Используйте $inject для задания зависимостей

angular .module('app') .controller('Dashboard', Dashboard);

Dashboard.$inject = ['$location', '$routeParams', 'common', 'dataservice'];

function Dashboard($location, $routeParams, common, dataservice) {}

Используйте ng-annotate с /** @ngInject */32

31

Аннотация внедрения зависимостей

Page 26: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

Архитектура

Замените всплытие событий использованием Медиатора33

Архитектура

Page 27: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

Паттерн «Фасад»скрытие деталей реализации конкретного функционала

Архитектура

Создавайте «врапперы» над вашими библиотеками 34

Page 28: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

Переключайте CSS классы вместо перестроения DOM

Скрывайте элементы перед изменением37

36

Оптимизация CSS

Упрощайте DOM35

DOM - оптимизация

Генерируйте элементы отдельно от страницы 38

Page 29: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

Оптимизация CSS

Клонируйте ваши узлы, изменяйте копии, а затем заменяйте ими оригиналы

Используйте только быстрые обертки над DOM операциями jquery

40

39

Не чередуйте запись и чтение DOM41

Page 30: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

Тестируйте css-transitions43

Оптимизация CSS

Избавляйтесь от тяжелых CSS свойств: border-radius, box-shadow, rotate

42

Оптимизация CSS

Page 31: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

.disable-hover { pointer-events: none;}

Отключайте сложные :hover анимации во время скроллинга44

Оптимизация CSS

Указывайте четкие размеры изображениям, тем самым ускоряя reflow и repaint

45

Page 32: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

Выстраивайте цепочки методов46

Получение данных

Получение данных

Page 33: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

(function(module) {'use strict';module.factory('signUpService', signUpService);signUpService.$inject = ['$ionicLoading', 'firebaseService', '$ionicPopup', '$state',

'$q'];function signUpService($ionicLoading, firebaseService, $ionicPopup, $state, $q) {

return { signUp: function(user, userCred) { var newUser = { user: user, userCred: userCred };

/* Registration chain */ checkUsername(newUser) .then(createUser) .then(authByPassword) .then(pushUserDetails) .then(reserveUsername) .catch(throwError); } }; [...]

}}(angular.module('starter')));

Page 34: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

Используйте объекты вместо массива аргументов

var alert = new Alert(id, { x: 100, y: 75, width: 300, height: 200, title: "Error", message: message, titleColor: "blue", bgColor: "white", textColor: "black", icon: "error", modal: true});

48

Получение данных

Получайте общие данные не блокируя загрузку основных данных47

Page 35: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

Не изменяйте массив arguments. Копируйте его в настоящий, используя [].slice.call(arguments)

49

Получение данных

Не применяйте цикл for in для массивов50

Page 36: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

class ExampleController {

constructor() {

this.controllerName = 'Example Controller';

}

}

export { ExampleController }

ES6

ES6Используйте классы для контроллеров и сервисов51

Page 37: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

Помещайте export в конец модуля

function sumTwo(a, b) {return a + b;

}

function sumThree(a, b, c) {return a + b + c;

}

let api = {sumTwo,sumThree

};

export default api;

52

ES6

Page 38: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

Оставьте декларации VAR внутри унаследованного кода, чтобы обозначить, что он должен быть тщательно переработан

53

ES6

Используйте стрелочные функции

когда вам нужно сохранить лексическое значение thisвместо функциональных выражений, когда это возможно

54

Page 39: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

myModule.component('appFooter', { template: '<footer></footer>',

bindings: { entityName: '=' }, controller: function() {

this.getCurrentYear = function() {};}

});

ES6

Используйте API компонент55

Page 40: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

+1 советПишите тесты.

Page 41: 55+1 прием для улучшения Javascript-кода / Татьяна Бабич (Simbirsoft)

Вопросы?