1. Главная страница » Компьютеры

Javascript оптимизация производительности николас закас

Автор: | 16.12.2019

Библиотека программиста запись закреплена

Николас Закас "JavaScript. Оптимизация производительности" (2012, PDF)

Если вы относитесь к подавляющему большинству веб-разработчиков, то наверняка широко применяете JavaScript для создания интерактивных веб-приложений с малым временем отклика. Проблема состоит в том, что строки с программным кодом на языке JavaScript могут замедлять работу приложений. Эта книга откроет вам приемы и стратегии, которые помогут в ходе разработки устранить узкие места, влекущие за собой снижение производительности. Вы узнаете, как ускорить выполнение, загрузку, операции с деревом DOM, работу страницы в целом и многое другое.

Предисловие

Самый главный совет

Очень важно давать любые советы по производительности в контексте. Оптимизация часто становится навязчивой привычкой, и глубокое погружение в дебри может на самом деле отвлекать от более важных вещей. Нужен целостный взгляд на производительность веб-приложения — прежде чем сосредоточиться на этих советах по оптимизации, стоит проанализировать свой код инструментами вроде PageSpeed и сначала добиться хорошего результата в целом. Это поможет избежать преждевременной оптимизации.

Лучшая стратегия, ведущая к созданию быстрого веб-приложения выглядит так:

  • Продумайте всё заранее, до того как столкнётесь с проблемами.
  • Тщательно разберитесь и проникните в суть проблемы.
  • Исправляйте только то, что имеет значение.

Чтобы придерживаться этой стратегии, важно понимать, как V8 оптимизирует JS, представлять, как всё происходит во время выполнения. Так же важно владеть правильными инструментами. В своём выступлении Дэниел посвятил больше времени инструментам разработчика; в этой статье я в основном рассматриваю особенности архитектуры V8.

Читайте также:  Http pro covers ru podr inst pdf

Скрытые классы

На этапе компиляции информация о типах в JavaScript очень ограничена: во время исполнения типы могут меняться, так что вполне естественно ожидать, что при компиляции трудно делать предположения о них. Возникает вопрос — как в таких условиях можно хотя бы приблизиться к скорости С++? Тем не менее, V8 ухитряется создавать скрытые классы для объектов во время выполнения. Объекты, имеющие один и тот же класс, разделяют один и тот же оптимизированный код.

Пока к p2 не было добавлено свойство " .z ", p1 и p2 внутри компилятора имели один и тот же скрытый класс, и V8 мог использовать один и тот же оптимизированный машинный код для обоих объектов. Чем реже вы будете менять скрытый класс, тем лучше будет производительность.

Выводы:

Числа

V8 следит за тем, как вы используете переменные, и использует наиболее эффективное представление для каждого типа. Смена типа может обойтись довольно дорого, поэтому старайтесь не смешивать числа с плавающей запятой и целые. В общем случае лучше использовать целые числа.

Выводы:

Массивы

V8 использует два вида внутреннего представления массивов:

  • Настоящие массивы для компактных последовательных наборов ключей.
  • Хэш-таблицы в остальных случаях.

Выводы:
  • Не стоит заставлять массивы перепрыгивать из одной категории в другую.
  • Используйте непрерывную нумерацию индексов, начиная с 0 (в точности как в С).
  • Не заполняйте предварительно большие массивы (содержащие больше 64K элементов) — это ничего не даст.
  • Не удаляйте элементы из массивов (особенно числовых).
  • Не обращайтесь к неинициализированным или удалённым элементам. Пример:

Быстрее всего работают массивы чисел с двойной точностью — значения в них распаковываются и хранятся, как элементарные типы, а не как объекты. Бездумное использование массивов может приводить к частой распаковке-упаковке:

Гораздо быстрее будет так:

В первом примере индивидуальные присваивания происходят последовательно, и в тот момент, когда a[2] получает значение, компилятор преобразует a в массив распакованных чисел с двойной точностью, а когда a[3] инициализируется нечисловым элементом, происходит обратное преобразование. Во втором примере компилятор сразу выберет нужный тип массива.

Таким образом:

  • Маленькие фиксированные массивы лучше всего инициализировать, используя литерал массива.
  • Заполняйте маленькие массивы ( add() делает код полиморфным:

Оптимизирующий компилятор

Параллельно с работой базового компилятора, оптимизирующий компилятор перекомпилирует «горячие», то есть такие, которые выполняются часто, участки кода. Он использует информацию о типах, накопленную в инлайн-кэшах.

Оптимизирующий компилятор старается встраивать функции в места вызова, что ускоряет выполнение (но увеличивает расход памяти) и позволяет делать дополнительные оптимизации. Мономорфные функции и конструкторы легко могут быть встроены целиком, и это ещё одна причина, по которой надо стремиться их использовать.

Вы можете посмотреть, что именно оптимизируется в вашем коде, используя автономную версию движка d8:

(имена оптимизированных функций будут выведены в stdout )

Не все функции могут быть оптимизированы. В частности, оптимизирующий компилятор пропускает любые функции, содержащие блоки try/catch .

Выводы:

Если необходимо использовать блок try/catch , помещайте критичный к производительности код снаружи. Пример:

Возможно, в будущем ситуация изменится, и мы сможем компилировать блоки try/catch оптимизирующим компилятором. Вы можете посмотреть, какие именно функции игнорируются, указав опцию —trace-bailout при запуске d8:

Деоптимизация

Код, сгенерированный оптимизирующим компилятором, не всегда оказывается быстрее. В этом случае используется первоначальная, неоптимизированная версия. Неудачно оптимизированный код выбрасывается, и выполнение продолжается с соответствующего места кода, созданного базовым компилятором. Возможно, этот код вскоре снова будет оптимизирован, если позволят обстоятельства. В частности, изменение скрытых классов внутри уже оптимизированного кода приводит к деоптимизации.

Выводы:
  • Избегайте изменения скрытых классов в оптимизированных функциях.

Вы можете посмотреть, какие именно функции подвергаются деоптимизации, запустив d8 с опцией —trace-deopt :

Другие инструменты V8

Перечисленные выше функции могут быть переданы Google Chrome при запуске:

В d8 тоже есть профилировщик:

Сэмплирующий профилировщик d8 делает снимки каждую миллисекунду и пишет в v8.log .

Резюме

Важно понимать, как устроен движок V8, чтобы писать хорошо оптимизированный код. И не забывайте об общих принципах, описанных в начале статьи:

  • Продумайте всё заранее, до того как столкнётесь с проблемами.
  • Тщательно разберитесь и проникните в суть проблемы.
  • Исправляйте только то, что имеет значение.

Это значит, что вы должны убедиться, что дело именно в JavaScript, с помощью таких инструментов, как PageSpeed. Возможно стоит избавиться от обращений к DOM, прежде чем искать узкие места. Надеюсь, что выступление Дэниела (и эта статья) поможет вам лучше понять работу V8, но не забывайте, что часто полезнее оптимизировать алгоритм программы, а не подстраиваться под конкретный движок.

Автор: Закас Н.
Страниц: 256
Масса: 350
Обложка: мягкая
Издана: Июль 2012
Цена: 692 P.

Аннотация

Шестое издание JavaScript. Подробное руководство от Дэвида Флэнагана стало супер бестселлером и самым надежным помощником всех JavaScript-программистов. Но один аспект темы JavaScript автор раскрыл недостаточно широко. Все, что Вы хотели знать об оптимизации производительности, но не знали, где спросить — в новой книге от "Символ-Плюс" и O’Reilly!

Если вы относитесь к подавляющему большинству веб-разработчиков, то наверняка широко применяете JavaScript для создания интерактивных веб-приложений с малым временем отклика. Проблема состоит в том, что строки с программным кодом на языке JavaScript могут замедлять работу приложений. Эта книга откроет вам приемы и стратегии, которые помогут в ходе разработки устранить узкие места, влекущие за собой снижение производительности. Вы узнаете, как ускорить выполнение, загрузку, операции с деревом DOM, работу страницы в целом и многое другое.

Николас Закас (Nicholas C. Zakas), программист из компании Yahoo!, специализирующийся на разработке пользовательских интерфейсов веб-приложений, и пять других экспертов в области использования JavaScript – Росс Хармс (Ross Harmes), Жюльен Лекомте (Julien Lecomte), Стивен Левитан (Steven Levithan), Стоян Стефанов (Stoyan Stefanov) и Мэтт Суини (Matt Sweeney) – представят оптимальные способы загрузки сценариев и другие приемы программирования, которые помогут вам обеспечить наиболее эффективное и быстрое выполнение программного кода на JavaScript. Вы познакомитесь с наиболее передовыми приемами сборки и развертывания файлов в действующем окружении и с инструментами, которые помогут вам в поиске проблем.

Приемы и подходы, обсуждаемые в этой книге, охватывают самые разные аспекты программирования на языке JavaScript, такие как время выполнения, загрузка, взаимодействие с DOM, жизненный цикл страниц и многие другие. Из рассматриваемых проблем лишь малая часть, связанная с производительностью ядра (ECMAScript), может быть устранена за счет усовершенствования интерпретаторов JavaScript, но это еще только должно произойти.

В решении остальных рассмотренных проблем увеличение производительности интерпретаторов JavaScript не решает проблему быстродействия. Это взаимодействие с деревом DOM, сетевые задержки, блокировка и параллельная загрузка сценариев JavaScript и многое другое. Эти вопросы не только не будут сняты в будущем, но станут основным предметом исследований по мере повышения производительности интерпретаторов JavaScript.

Главы в этой книге организованы в соответствии с обычным циклом разработки сценариев на языке JavaScript. Сначала в главе 1 «Загрузка и выполнение» рассказывается о параллельной загрузке JavaScript-файлов одновременно с другими ресурсами.

Плохо написанный программный код, использование неэффективных алгоритмов и утилит являются существенным фактором снижения производительности JavaScript. В главах 2–8 представлены конкретные приемы программирования, которые позволяют максимально увеличить скорость выполнения программного кода.

В главе 2 «Доступ к данным» описывается, как JavaScript-сценарии сохраняют и извлекают данные. Важно не только решить, какие данные хранить, но и где их хранить, и эта глава демонстрирует, как такие понятия, как цепочки областей видимости и цепочки прототипов, могут влиять на производительность сценариев. Здесь рассказывается об ускорении доступа к данным и разрешении идентификаторов, об управлении областями видимости, о динамических областях видимости, об использовании цепочек областей видимости и сохранении данных в замыканиях. Этот материал позволит глубже понять особенности работы областей видимости в языке JavaScript.

В главе 3 «Работа с деревом DOM» объясняется, что из-за особенностей реализации операции с деревом DOM являются самыми медленными в JavaScript. Рассматриваются все аспекты, касающиеся DOM, включая описание того, как перерисовка и реорганизация элементов страниц могут уменьшить скорость выполнения программного кода.

Предлагаются удобные и эффективные приемы чтения и изменения элементов DOM, способы изменения стилей элементов DOM, позволяющие избежать лишних операций перерисовывания и перекомпоновки.

Глава 4 «Алгоритмы и управление потоком выполнения» описывает, как распространенные приемы программирования, такие как циклы и рекурсия, могут работать против вас, снижая производительность во время выполнения. Здесь рассматриваются такие методы оптимизации, как мемоизация, а также некоторые ограничения, накладываемые браузерами.

Многие веб­-приложения выполняют сложные операции со строками, обсуждение которых в главе 5 «Строки и регулярные выражения» ведет Стивен Левитан, эксперт по обработке текстовых данных. На протяжении многих лет веб­разработчики боролись с неэффективной реализацией строковых операций в браузерах, и Стивен объясняет, почему некоторые операции выполняются слишком медленно и как обходить это при разработке.

Глава 6 «Отзывчивые интерфейсы» концентрируется на ощущениях пользователей. В процессе выполнения JavaScript-сценарий может «подвешивать» броузер, вызывая неудовольствие у пользователей. Здесь обсуждаются некоторые приемы, гарантирующие сохранение отзывчивости пользовательского интерфейса в любых условиях. Рассказывается, как решаются проблемы, обусловленные тем фактом, что выполнение JavaScript-сценариев и обновление пользовательского интерфейса производится в одном потоке выполнения. Демонстрируются такие приемы, как применение таймеров, разделение задач и использование фоновых потоков для выполнения программного кода за рамками главного потока управления.

В главе 7 «Ajax» обсуждаются способы реализации быстрых взаимодействий между клиентом и сервером, показывается, как различные форматы представления данных могут влиять на производительность механизмов Ajax и почему применение объекта XMLHttpRequest не всегда является лучшим выбором.

Глава 8 «Приемы программирования» представляет собой коллекцию наиболее эффективных приемов программирования, уникальных для языка JavaScript.

После того как JavaScript-сценарий будет написан и отлажен, наступает момент сделать внесенные изменения доступными всем желающим. Однако недостаточно просто скопировать исходные файлы на действующий сервер. В главе 9 «Сборка и развертывание высокопроизводительных приложений на JavaScript» демонстрируется, как повысить производительность сценариев при развертывании, обсуждаются особенности использования систем сборки, автоматически минимизирующих файлы, и применение функции сжатия в протоколе HTTP при отправке этих файлов броузерам.

Следующий шаг после развертывания JavaScript-сценариев – тестирование их производительности. Глава 10 «Инструменты» охватывает инструменты исследования производительности, способные помочь в поиске проблем, которые могут появиться после развертывания сценариев. Рассказывается об инструментах для профилирования JavaScript-сценариев и анализа сетевого трафика, таких как Firebug, инструменты разработчика в Chrome, dynaTrace, Fiddler, Page Speed, YSlow, веб-инспектор в Safari, инструменты разработчика в IE.

Эта книга адресована веб-­разработчикам со средним и высоким уровнем владения языком JavaScript, желающим повысить производительность интерфейсов веб­-приложений.

Об авторе

Николас Закас (Nicholas C. Zakas) – программист, специализирующийся на проектировании и реализации пользовательских интерфейсов веб-приложений с применением JavaScript, Dynamic HTML, CSS, XML и XSLT. В настоящее время является ведущим специалистом по пользовательскому интерфейсу сайта Yahoo! и одним из разработчиков библиотеки Yahoo! User Interface (YUI), для которой им были созданы модули Cookie Utility, Profiler и YUI Test.

Николас является автором книги «Professional JavaScript for Web Developers» и соавтором книги «Professional Ajax» («Ajax для профессионалов», Символ-Плюс, 2007), а также принимал участие в создании других книг. Им написаны несколько статей для сайтов WebReference, Sitepoint и YUI Blog.

Николас делает регулярные доклады о веб-разработке, JavaScript и наиболее эффективных решениях. Он выступал с докладами в компаниях Yahoo!, LinkedIn, Google и NASA и на конференциях, таких как «Ajax Experience» , «Rich Web Experience» и «Velocity» .

В своих книгах и докладах Николас стремится передать другим ценный опыт, полученный при работе над одними из самых популярных и востребованных в мире веб-приложений.

Дополнительную информацию о Николасе можно найти на сайте http://www.nczonline.net/about/

Мнение специалистов

«Книга «JavaScript. Оптимизация производительности» охватывает все проблемы, связанные с производительностью, о которых должны знать современные разработчики. Она определенно внесла вклад в мою копилку приемов повышения производительности.»

– Стив Содерс (Steve Souders)

«Книга «JavaScript. Оптимизация производительности» представляет собой впечатляющую коллекцию советов и рекомендаций от экспертов в этой области. Это бесценный источник знаний для всех, кто желает писать высокопроизводительные сценарии на языке JavaScript.»

– Венкат Юдайашанкар (Venkateswaran Udayasankar), признанный авторитет в области организации поиска, Yahoo! Search

Мнение читателей

Хорошие, краткие советы, хотя и не отличающиеся новизной, 2 апреля 2010

Миллер Медейрос (Miller Medeiros)

Эта книга представляет собой отличный справочник по оптимизации приложений на JavaScript и также будет интересна тем, кто хочет узнать, «как все это устроено внутри».

Многие из описываемых приемов с успехом могут применяться в других языках программирования (и являются хорошо известными приемами повышения производительности) и не сильно усложняют программный код, что является очень важным, если вы хотите стать не только лучшим разработчиком на JavaScript, но и лучшим разработчиком вообще.

Единственное, что следует учесть, – эта книга НЕ для НАЧИНАЮЩИХ, поскольку она предполагает наличие опыта и навыков программирования на языке JavaScript.

Если вам довелось прочитать книги «Professional JavaScript for Web Developers», «High Performance Web Sites» и «Even Faster Web Sites: Performance Best Practices for Web Developers», вы заметите, что некоторые приемы уже были описаны в них, поэтому если вы знакомы с последними достижениями/инструментами и занимались исследованиями на эту тему, то, скорее всего, вы уже знаете большую часть из того, о чем рассказывается в этой книге. Тем не менее она все же остается замечательной и интересной книгой, потому что описывает, как действуют интерпретаторы JavaScript и почему представленные приемы обеспечивают прирост производительности; при этом краткость изложения является ее большим плюсом.

Я настоятельно рекомендую эту книгу всем разработчикам со средним и высоким уровнем подготовки, желающим узнать, как повысить общую производительность приложений на JavaScript, потому что она представляет собой краткое и точное обобщение передового опыта разработчиков. Даже если вы обладаете обширными знаниями по обсуждаемой теме, вы все равно сможете найти в ней несколько новых приемов.

Отличный обзор приемов программирования на языке JavaScript, 13 апреля 2010

Р. Фризел (R. Friesel Jr.) «found_drama» (Берлингтон, штат Вермонт, США)

Если вы относите себя к середнячкам, то найдете много откровений в этой книге. Махинации с особенностями внутреннего устройства языка переплетаются так, что приемы выглядят совершенно новыми и удивительными, а возможности кажутся безграничными! Результат применения предлагаемых приемов потрясет вас. Ваши страницы стали загружаться на 60% быстрее, время выполнения уменьшилось в среднем на 40%.

Однако немного разочаровывает то обстоятельство, что половину рекомендаций, которые здесь даются, многие уже используют в своей работе. Переместить сценарии в конец документа? Сделано. Минифицировать и сжать? Сделано. Объединить и упаковать? Сделано. Итак, с одной стороны, можно сказать: «Теперь я буду спать спокойнее, узнав, что наша система сборки использует самые передовые приемы, рекомендованные экспертами». Но, с другой стороны, вы будете немного разочарованы, потому что надеялись на какие-то поразительные открытия. Однако не все так плохо, как кажется. Если смотреть с этой точки зрения, ценным качеством этой книги является то, что все эти передовые приемы собраны в одном месте и представлены в логическом порядке. Даже если «вы и так все делаете правильно», все равно стоит лишний раз поразмышлять об особенностях и по-настоящему понять, почему эти приемы играют такую важную роль. Кроме того, в книге представлено большое количество графиков, иллюстрирующих результаты предлагаемых приемов.

Отличные советы по оптимизации, 25 мая 2010

Т. Феррелл (T. Ferrell) (Флорида, США)

Моя компания занимается созданием веб-приложений уровня предприятия. Как и большинство разработчиков, для тестирования приложений мы используем связку Firefox/Firebug, и приложения прекрасно работают в Firefox. Проблема: стандартным для компании является веб-броузер IE7.

При запуске приложения в IE7 приложение становилось абсолютно непригодным к использованию. Интенсивные вычисления, которые в Firefox выполнялись за 2 секунды, в IE7 продолжались до 10 минут (я не преувеличиваю). Какое-то время мы жаловались друг другу на сложности разработки программ для IE, но в конце концов поняли, что должны найти решение этих проблем – они не могли исчезнуть от наших жалоб. Поискав в Google, мы нашли некоторые пути оптимизации нашей программы, и они дали определенные положительные результаты; но самую действенную помощь мы получили от этой книги. Определив, с какими вычислениями связана основная задержка, и познакомившись с альтернативными способами их выполнения, мы смогли заставить наше приложение работать в IE.

Оглядываясь назад, я хотел бы, чтобы я знал обо всех этих приемах чуть раньше и определенно до того, как мы приступили к созданию нашего приложения.

Пишите высокопроизводительные приложения на JavaScript, 9 сентября 2010

Мустафа Фаргхали (Mostafa Farghaly) (Египет)

Если сказать в двух словах, эту книгу должен иметь каждый. Она содержит массу информации о производительности JavaScript-сценариев в броузерах, и я полагаю, что она будет прекрасным дополнением к книгам издательства O’Reilly «High performance web sites» и «Even faster web sites». Она начинается там, где заканчиваются упомянутые книги, содержит некоторые сведения из них, но эта книга не для начинающих – она предполагает знание JavaScript, по крайней мере, на среднем уровне.

В целом книга получилась очень хорошей, и я рекомендую ее всем программистам, занимающимся разработкой пользовательских интерфейсов.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *