Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

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

432 views

Published on

В докладе будут рассмотрены приемы, практики и «фишки», которые полезно использовать для создания любого Frontend-приложения.

Мы поговорим об организации модульности и компонентов на примере приложений с Angular, React и Polymer. Обсудим, как использовать особенности JavaScript, и рассмотрим особые случаи, когда фреймворки действительно приходят на помощь.

Published in: Engineering
  • Be the first to comment

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

  1. 1. 55+1 прием для улучшения JavaScript-кода Бабич Татьяна Руководитель Frontend отдела компании SimbirSoft
  2. 2. На старт! Внимание! Марш! Проект будет больше, чем предполагается Состав команды может поменяться Время реализации сильно ограничено
  3. 3. Соблюдайте LIFT - принципы1 locate identify flat try to stay DRY L I F T - - - - Соблюдайте LIFT - принципы.
  4. 4. Соблюдайте LIFT - принципы. Спустя пару месяцев controllers/ LoginController.js RegistrationController.js ProfileController.js SearchResultsController.js FeedController.js directives.js filters.js models/ Feed.js CartModel.js ProfileModel.js SearchResultsModel.js UserModel.js services/ FeedService.js CartService.js UserService.js ProfileService.js
  5. 5. Соблюдайте LIFT - принципы. Спустя полгода controllers/ LoginController.js RegistrationController.js ProductDetailController.js SearchResultsController.js UsersController.js UsersProfileController.js OpinionController.js InstrumentsController.js FeedController.js RecoveryController.js NavigationContoller.js directives.js filters.js models/ CartModel.js ProductModel.js SearchResultsModel.js UserModel.js Navigation.js Recovery.js Feed.js Instruments.js Opinion.js Users.js UsersProfile.js services/ ...
  6. 6. Модульность Модульность product/ search/ SearchResultsController.js SearchResultsModel.js ProductDetailController.js ProductModel.js ProductService.js user/ LoginController.js RegistrationController.js RecoveryController.js UserModel.js UserService.js instruments/ InstrumentsController.js InstrumentsModel.js InstrumentsService.js feed/ FeedController.js FeedModel.js FeedService.js
  7. 7. Принцип единой ответственности Модульность 2
  8. 8. /* 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 */ }
  9. 9. Применяйте единый codestyle. Используйте анализаторы кода. Включите их в систему контроля версий 4 Модульность Соблюдайте правила именования переменных3 profile.controller.js ProfileController.js
  10. 10. Создайте константы для всех переменных от сторонних библиотек в вашем проекте 5 Модульность Оптимизируйте ваши «велосипеды», тестируйте их, а главное документируйте 6
  11. 11. 1 модуль = 1 задача Модульность приватность слабая связность Модульность независимость
  12. 12. Создавайте много небольших независимых модулей Создавайте ре-используемые модули9 8 Модульность Создавайте главный модуль и не загромождайте его7
  13. 13. Модульность Используйте IIFE10 ;(function() { ... var app = angular.module('myApp'); ... })(); console.log(app) // not defined
  14. 14. Переносите логику из контроллера в фабрики и сервисы12 Контроллеры Формируйте $scope в определенном месте11 Контроллеры
  15. 15. Используйте синтаксис 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
  16. 16. function User() { angular.extend(this, { someVar: { name: 'Name' }, anotherVar: [], doSomething: function doSomething() { } }); } angular .module('app') .controller('User', User); Контроллеры Замена vm синтаксиса
  17. 17. Задавайте отдельный контроллер для каждого шаблона // route-config.js angular .module('app') .config(config); function config($routeProvider) { $routeProvider .when('/user', { templateUrl: 'user.html', controller: 'UserController', controllerAs: 'vm' }); } <!-- user.html --> <div></div> 14 Контроллеры
  18. 18. Используйте одноразовую привязку данных {{:: ... }} Не используйте ng-class для установки CSS свойств, если это возможно сделать средствами только CSS 17 16 Минимизация количества $watcher - ов Правильно используйте $rootScope15 Минимизация количества $watcher-ов
  19. 19. Минимизация количества $watcher - ов Переносите манипуляции с DOM в директивы19 Не храните ссылки на DOM элементы в $scope18 Избегайте работы с большими данными21 Создавайте директивы с изолированным $scope20
  20. 20. Используйте track by для циклов22 Минимизация количества $watcher - ов Переносите тяжелую логику из фильтров в контроллеры и сервисы 24 Удаляйте ненужные фильтры23
  21. 21. Используйте $watchCollection вместо $watch (с 3-им параметром). Избегайте установки флага objectEquality в true $scope.$watch(…, …, true); 26 Минимизация количества $watcher - ов Откажитесь от использования $watch там, где это возможно25
  22. 22. Отписывайтесь от watches и event listeners27 Минимизация количества $watcher - ов var stopFunction = $scope.$on('someEvent', function() { ... }); // Обработчик добавлен stopFunction(); // Обработчик удален
  23. 23. Если это возможно, сокращайте количество вызовов ng-model ng-model-options=”{debounce: 250}” Старайтесь избегать использования ng-mouse-over и подобных директив 29 28 Оптимизация $digest вызовов Оптимизация $digest вызовов
  24. 24. Избегайте использования сокращенного синтаксиса объявления зависимостей без учета минификации кода angular .module('app') .controller('Dashboard', Dashboard); function Dashboard(common, dataservice) { } 30 Аннотация внедрения зависимостей Аннотация внедрения зависимостей angular.module('app').controller('Dashboard', d);function d(a, b) { }
  25. 25. Используйте $inject для задания зависимостей angular .module('app') .controller('Dashboard', Dashboard); Dashboard.$inject = ['$location', '$routeParams', 'common', 'dataservice']; function Dashboard($location, $routeParams, common, dataservice) { } Используйте ng-annotate с /** @ngInject */32 31 Аннотация внедрения зависимостей
  26. 26. Архитектура Замените всплытие событий использованием Медиатора33 Архитектура
  27. 27. Паттерн «Фасад» скрытие деталей реализации конкретного функционала Архитектура Создавайте «врапперы» над вашими библиотеками34
  28. 28. Переключайте CSS классы вместо перестроения DOM Скрывайте элементы перед изменением37 36 Оптимизация CSS Упрощайте DOM35 DOM - оптимизация Генерируйте элементы отдельно от страницы38
  29. 29. Оптимизация CSS Клонируйте ваши узлы, изменяйте копии, а затем заменяйте ими оригиналы Используйте только быстрые обертки над DOM операциями jquery 40 39 Не чередуйте запись и чтение DOM41
  30. 30. Тестируйте css-transitions43 Оптимизация CSS Избавляйтесь от тяжелых CSS свойств: border-radius, box-shadow, rotate 42 Оптимизация CSS
  31. 31. .disable-hover { pointer-events: none; } Отключайте сложные :hover анимации во время скроллинга44 Оптимизация CSS Указывайте четкие размеры изображениям, тем самым ускоряя reflow и repaint 45
  32. 32. Выстраивайте цепочки методов46 Получение данных Получение данных
  33. 33. (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')));
  34. 34. Используйте объекты вместо массива аргументов 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
  35. 35. Не изменяйте массив arguments. Копируйте его в настоящий, используя [].slice.call(arguments) 49 Получение данных Не применяйте цикл for in для массивов50
  36. 36. class ExampleController { constructor() { this.controllerName = 'Example Controller'; } } export { ExampleController } ES6 ES6 Используйте классы для контроллеров и сервисов51
  37. 37. Помещайте 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
  38. 38. Оставьте декларации VAR внутри унаследованного кода, чтобы обозначить, что он должен быть тщательно переработан 53 ES6 Используйте стрелочные функции когда вам нужно сохранить лексическое значение this вместо функциональных выражений, когда это возможно 54
  39. 39. myModule.component('appFooter', { template: '<footer></footer>', bindings: { entityName: '=' }, controller: function() { this.getCurrentYear = function() {}; } }); ES6 Используйте API компонент55
  40. 40. +1 совет Пишите тесты.
  41. 41. Вопросы?

×