Как обновить систему фонового управления компании (часть 1) — оптимизация производительности

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

написать впереди

Это время золота, серебра и серебра. Многие компании начали первый раунд набора в этом году. Хотя в этом году холодная зима в Интернете, если у вас всегда есть энтузиазм в отношении технологий и отличная сила, даже холодная зима не будет мешать вам, шаг вперед. Во время собеседования, часто со второй и третьей стороны, интервьюер задаст несколько вопросов о пунктах вашего резюме на основе вашего резюме, и следующий вопрос будет задан много раз.

在这个项目中你有遇到什么技术难点,你是怎么解决的?

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

И многие скажут, что мой проект не большой, сложности нет, или он не сложный, можно сказать только какие-то ямки, просто погуглите и это решаемо, спросить у коллег реально невозможно , эти проблемы давно меня не беспокоили . На самом деле, я тоже столкнулся с такой ситуацией: нехорошо рассказывать интервьюеру, как решить эти подводные камни через поисковые системы, чтобы интервьюер думал, что вы просто API Caller, но нет никаких сложностей проекта, о которых стоит говорить. .

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

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

Стек технологий представляет собой одностраничное приложение Vue + Element.

источник

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

Благодаря тому, что вся система управления фоном была разработана мной самостоятельно, у меня есть глубокое понимание недостатков проекта, и я могу более свободно его модифицировать.vue-element-admin, я решил открыть новый проект, чтобы переписать весь предыдущий код

Структура проекта

Раньше я планировал написать скаффолдинг на основе Webpack4 для упаковки файлов, но на тот момент Vue-cli3 только выпустил официальную версию и тоже был запакован на основе Webpack4, поэтому я подумал и решил использовать новый Vue-cli3 строительных лесов, и, наконец, я разделил проект на следующую иерархию

├─api                                 //api接口
├─assets                              //项目运行时使用到的图片和静态资源
├─components                          //组件
│  ├─BaseEllipsis                     //业务组件 (Base开头都是全局组件)
│  ├─BasePagination                   //分页器组件   
│  ├─BaseIcon                         //svg图标组件
│  ├─BaseToggle                       //业务组件
│  ├─BaseTable                        //表格组件
│  ├─FormPanel                        //业务组件(Form开头是围绕表单相关的小组件)
│  ├─TableOptions                     //业务组件(Table开头是围绕表格相关的小组件)
│  ├─TheBreadcrumb                    //面包屑组件(The开头是每个页面组件只会引入一次的无状态组件)
|  ├─TheSidebar                       //侧边栏组件
│  ├─TransitionSildeDown              //业务组件(Transition开头是动画组件)
│  └─index.js                         //全局组件自动注册的脚本
│  
├─directives                          //自定义指令
├─element                             //elementui
├─errorLog                            //错误捕获
├─filters                             //全局过滤器
├─icons                               //svg图标存放文件夹
├─interface                           //TypeScript接口
├─mixins                              //局部混入
├─router                              //vue-router
│  ├─modules                      
│  └─index.js           
├─store                                //vuex
│  ├─modules                      
│  └─index.js                      
├─style                                //全局样式/局部页面可复用的样式
├─util                                //公共的模块(axios,cookie封装,工具函数)
├─vendor                              //类库文件
└─views                               //页面组件(所有给用户显示的页面)

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

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

До того, как я переписал всю систему, каждый пакет занимал несколько минут, а упакованный проект превышал 17M.

Однако после того, как я оптимизировал систему, упакованный объем составил всего 2М, что было уменьшено8 раз

Здесь я поделюсь, как я улучшил производительность системы в проекте из следующих 4 аспектов и заставил систему «летать»

  • связанный с сетевым запросом
  • построить связанные
  • Статическая оптимизация ресурсов
  • Связанные с кодированием

связанный с сетевым запросом

Эта часть направлена ​​на минимизацию накладных расходов на HTTP-запросы или сокращение времени отклика при условии выполнения требований.

CDN

Размещение сторонней библиотеки классов в CDN может значительно сократить объем проекта в производственной среде.Кроме того, CDN может в режиме реального времени интегрировать такую ​​информацию, как сетевой трафик, подключение каждого узла, статус загрузки, расстояние до пользователя и время отклика.Запрос пользователя перенаправляется на ближайший к пользователю сервисный узел

Кроме того, поскольку доменные имена CDN и сервера, как правило, не совпадают, это может снизить ограничение на количество одновременных HTTP-запросов для одного и того же доменного имени, эффективно отклонить трафик и уменьшить отправку избыточных файлов cookie (статические запросы ресурсов в CDN не должны содержать файлы cookie)

С точки зрения непрофессионала, использование CDN в определенной степени улучшит скорость передачи статических файлов в проекте.В vue-cli3 элемент конфигурации externals можно использовать для указания ссылочного адреса сторонней библиотеки классов из local на предоставленный вами адрес CDN.

externals работает только с импортом модуля ES по умолчанию

Здесь CDN включается только путем оценки производственной среды через переменные среды.Помимо включения CDN, вам также необходимо внедрить доменное имя CDN в index.html, поэтому я использую html-webpack-plugin для динамического внедрения тегов скрипта в соответствии с к доменному имени cdn. Объявляйте циклические массивы и вводимые элементы с помощью синтаксиса шаблона в index.html.

index.html перед упаковкой:

Упакованный index.html:

Видно, что с помощью этого плагина доменное имя cdn может быть динамически внедрено в упакованный index.html.

Еще один момент, на который следует обратить внимание, это то, что свойства объекта externals являются для вас именами импортированных пакетов, а значения свойств — соответствующими именами глобальных переменных (файлы библиотеки классов, представленные CDN, будут автоматически монтироваться под объектом окна , и свойства во время монтирования. Имя нужно перейти в соответствующий CDN, чтобы найти в исходном коде. Как правило, в начале строки будет оператор. Кроме того, его трудно импортировать. Вы также можете прочитайте этот блог.Глубокое понимание внешнего вида веб-пакета)

这里还是建议尽量放到公司专用的CDN上,不推荐使用公共的CDN,因为容易挂,生产环境还是以稳定为主吧

Разумная стратегия кэширования

Установите стороннюю библиотеку классов или статический ресурс, который не будет изменяться в течение длительного времени, на сильный кеш, установите максимальный возраст на очень долгое время, а затем добавьте путь доступа плюс хэш к хеш-значению, чтобы гарантировать, что получено последнее обновление Ресурсы (vue-cli3 будет собран автоматически, а созданный вами скаффолдинг веб-пакета требует самостоятельной настройки contentHash, chunkHash)

Стратегия кэширования в CDN, вы можете видеть, что значение max-age очень велико, поэтому при следующем доступе будут считываться только ресурсы, кэшированные на локальном диске/памяти:

Для мультимедийных ресурсов, таких как index.html и некоторые изображения, вы можете согласовать кеш (max-age

Хорошая стратегия кэширования может помочь снизить нагрузку на сервер и значительно улучшить взаимодействие с пользователем.

gzip

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

    #开启和关闭gzip模式
    gzip on;
    #gizp压缩起点,文件大于1k才进行压缩
    gzip_min_length 1k;
    # gzip 压缩级别,1-9,数字越大压缩的越好,也越占用CPU时间
    gzip_comp_level 6;
    # 进行压缩的文件类型。
    gzip_types text/plain application/javascript application/x-javascript text/css application/xml text/javascript ;
    #nginx对于静态文件的处理模块,开启后会寻找以.gz结尾的文件,直接返回,不会占用cpu进行压缩,如果找不到则不进行压缩
    gzip_static on
    # 是否在http header中添加Vary: Accept-Encoding,建议开启
    gzip_vary on;
    # 设置gzip压缩针对的HTTP协议版本
    gzip_http_version 1.1;

Но здесь мы хотим поговорить о том, что внешний интерфейс выводит файлы gzip и использует сжатие-webpack-плагин, чтобы позволить веб-пакету выводить сжатые файлы с суффиксом .gz при упаковке.

Таким образом, мы уже можем получить gzip-файл без активного сжатия сервером.Эту строку можно найти в пункте конфигурации nginx выше.

 #nginx对于静态文件的处理模块,开启后会寻找以.gz结尾的文件,直接返回,不会占用cpu进行压缩,如果找不到则不进行压缩
    gzip_static on

Просто поместите файл .gz на сервер и запустите gzip_static, чтобы позволить серверу сначала вернуть файл .gz.В условиях высокого трафика это также может в определенной степени снизить нагрузку на сервер.Это относится к использованию места за время (файл .gz будет занимать дополнительное место на сервере)

Обнюхивание ресурсов

засовременный браузерНапример, в тег ссылки можно добавить атрибуты preload, prefetch, dns-prefetch.

preload

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

Кроме того, использование предварительной загрузки для предварительной загрузки стилей CSS, необходимых для первого экрана, также является хорошим выбором.critical

без предварительной загрузки

использовать предварительную загрузку

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

В проекте с помощью некоторых предварительно загруженных плагинов веб-пакета можно легко внедрить предварительно загруженные теги ресурсов в упакованный index.html.Заинтересованные друзья могут попробовать поискать похожие плагины.

prefetch

Prefetch позволяет браузеру заранее загружать ресурсы, которые могут понадобиться следующей странице. vue-cli3 по умолчанию добавляет атрибут prefetch ко всем маршрутам с отложенной загрузкой, чтобы вы могли ускорить загрузку при посещении страниц, использующих маршруты с отложенной загрузкой. скорость

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

dns-prefetch

dns-prefetch позволяет браузерам заранее разрешать доменные имена, снижая стоимость поиска DNS.Если ваши статические ресурсы и внутренний интерфейс не являются одним и тем же сервером, вы можете поместить в ссылку доменное имя, которое учитывает ваш внутренний интерфейс. тег и добавьте атрибут dns-prefetch

Домашняя страница Jingdong также использует технологию dns-prefetch.

http2

Прошло четыре года с тех пор, как в 2015 году появился http2, и сейчас он имеет более 50% покрытия в Китае.Благодаря фреймовой передаче http2 он может значительно снизить накладные расходы на запросы http(s)

Сравнение различий в производительности между http2 и http1.1

Если первому экрану системы необходимо загрузить много статических ресурсов одновременно, но количество tcp-подключений браузера к одному и тому же доменному имени ограничено (6 для chrome) превышает заданное количество tcp-подключений, вы должен ждать, пока не будет получен предыдущий запрос.Только после ответа можно продолжать отправку, в то время как http2 может одновременно иметь несколько запросов в tcp-соединении без ограничений, и улучшение производительности http2 особенно очевидно в некоторых средах с плохой сетью.

Настоятельно рекомендуется использовать протокол http2 на сервере, поддерживающем протокол https, который можно настроить через веб-сервер Nginx, или разрешить серверу напрямую поддерживать http2.

Для nginx очень просто открыть http2.В nginx.conf вам нужно только добавить http2 после исходного порта прослушивания.Предпосылка заключается в том, что ваша версия nginx не может быть ниже 1.95, а https включен.

listen 443 ssl http2;

Через протокол в сети можно посмотреть по какой версии http протокола передается текущий ресурс.

h2 означает http2

построить связанные

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

Отложенная загрузка маршрута

Традиционные компоненты роутинга статически упаковываются в проект через импорт. Недостаток этого в том, что все компоненты страницы упаковываются в один и тот же файл скрипта, в результате получается первый экран в продакшн-окружении.Объем загруженного кода будет очевиден. (белый экран)

Через import() модули ES6 имеют возможность динамической загрузки.Когда URL-адрес соответствует соответствующему пути, компоненты страницы будут загружаться динамически, так что количество кода на первом экране будет значительно уменьшено, а веб-пакет разделит динамически загружаемые компоненты страницы в отдельный файл chunk.js

Конечно у ленивой загрузки есть и минусы, то есть будет добавлен дополнительный http запрос.Если проект очень маленький, можно рассмотреть возможность не использовать маршрутизацию ленивой загрузки

предварительный рендеринг

Поскольку браузеру необходимо загрузить и проанализировать соответствующие файлы html, css и js перед рендерингом страницы, будет период белого экрана.Как максимально уменьшить влияние белого экрана на пользователя, в настоящее время я выбираем В шаблоне html вводим анимацию загрузки, вот беруD2-AdminПример загрузки анимации в

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width,initial-scale=1.0">
    <link rel="icon" href="<%= BASE_URL %>icon.ico">
    <title><%= VUE_APP_TITLE %></title>
    <style>
      html, body, #app { height: 100%; margin: 0px; padding: 0px; }
      .d2-home { background-color: #303133; height: 100%; display: flex; flex-direction: column; }
      .d2-home__main { user-select: none; width: 100%; flex-grow: 1; display: flex; justify-content: center; align-items: center; flex-direction: column; }
      .d2-home__footer { width: 100%; flex-grow: 0; text-align: center; padding: 1em 0; }
      .d2-home__footer > a { font-size: 12px; color: #ABABAB; text-decoration: none; }
      .d2-home__loading { height: 32px; width: 32px; margin-bottom: 20px; }
      .d2-home__title { color: #FFF; font-size: 14px; margin-bottom: 10px; }
      .d2-home__sub-title { color: #ABABAB; font-size: 12px; }
    </style>
  </head>
  <body>
    <noscript>
      <strong>
        很抱歉,如果没有 JavaScript 支持,D2Admin 将不能正常工作。请启用浏览器的 JavaScript 然后继续。
      </strong>
    </noscript>
    <div id="app">
      <div class="d2-home">
        <div class="d2-home__main">
          <img
            class="d2-home__loading"
            src="./image/loading/loading-spin.svg"
            alt="loading">
          <div class="d2-home__title">
            正在加载资源
          </div>
          <div class="d2-home__sub-title">
            初次加载资源可能需要较多时间 请耐心等待
          </div>
        </div>
        <div class="d2-home__footer">
          <a
            href="https://github.com/d2-projects/d2-admin"
            target="_blank">
            https://github.com/d2-projects/d2-admin
          </a>
        </div>
      </div>
    </div>
  </body>
</html>

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

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

Кроме того, предварительный рендеринг также может использовать рендеринг на стороне сервера (SSR) для вывода шаблона домашней страницы через бэкэнд или использовать схему скелетного экрана.У меня нет глубокого понимания здесь, и заинтересованные друзья могут попрактиковаться Это

Обновите до последней версии веб-пакета

По сравнению с webpack3, webpack4 имеет очевидный прирост производительности при оптимизации упаковки.Если вы чувствуете, что настройка скаффолдинга сложна, вы можете использовать vue-cli3 для создания своего проекта, который также основан на webpack4.

DllPlugin

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

DllPlugin является встроенным подключаемым модулем веб-пакета и не требует установки, но для внедрения упакованного index.html в эти упакованные сторонние библиотеки классов требуется дополнительная установка.add-asset-html-webpack-pluginплагин

Когда вам нужно внедрить несколько библиотек классов в index.html, вам нужно создавать экземпляры несколько раз.add-asset-html-webpack-plugin, здесь мы можем использовать модуль fs nodejs для обхода упакованного каталога DllPlugin и определения того, сколько экземпляров необходимо создать в соответствии с количеством библиотек классов.Это очень гибко.Для конкретных элементов конфигурации вы можете проверить ссылку на дне меня

Разумное использование сторонних библиотек

Если в проекте есть какие-то требования к работе с датами, вы можете переключить свое внимание с момента наday, по сравнению с громоздким моментом, он всего 2кб, апи дня и момента точно такие же, и китайская документация тоже дружелюбная

Кроме того, для таких библиотек, как lodash, если требуется только часть функций, нужно вводить только часть из них, так что вебпак будет вводить только эту часть кода в продакшн-окружение после древовидной тряски

Для UI библиотеки (element-ui) упакованный объем тоже будет очень большим.Попробуйте использовать загрузку по требованию.Также в официальной документации есть подробные туториалы.

Сжатый объем element-ui оказывается объемом Vue.десять раз

Общие пути для создания псевдонимов файлов

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

Конфигурация и использование в vue-cli3 (документация по цепочке webpack)

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

С помощью плагина webpack-bundle-analyzer я могу более интуитивно анализировать объем упакованных модулей после каждой упаковки, а затем оптимизировать более крупные модули.

Это объем моего модуля до оптимизации:

Из-за бизнес-требований внешний интерфейс требуется для экспорта файлов pdf и excel.Я представил два пакета, xlsx и pdf.js, но после упаковки обнаружил, что только два файла составляют половину объема проекта.Кроме того, elementui и момент тоже очень большой

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

Статическая оптимизация ресурсов

Эта часть направлена ​​на уменьшение влияния запроса некоторых ресурсов изображения.

Ленивая загрузка изображения

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

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

getBoundingClientRect

Элемент DOM содержитgetBoundingClientRectМетод, выполните этот метод, чтобы вернуть коллекцию границ CSS, связанную с текущим узлом DOM.

Среди них есть атрибут top, представляющий высоту текущего DOM-узла от верхней части окна браузера.Вам нужно только оценить, меньше ли значение top высоты текущего окна браузера (window.innerHeight). Если оно меньше, значит, оно попало в поле зрения пользователя, а затем заменить его реальным изображением.

Кроме того, при использовании getBoundingClientRect для ленивой загрузки изображений необходимо обратить внимание на 3 момента.

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

IntersectionObserver

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

При этом в callback-функцию передается параметр вхождений, который записывает некоторую пороговую информацию (объекты) всех элементов, наблюдаемых данным экземпляром.Атрибут intervalRatio указывает процент попадания картинки в видимый диапазон, и если он больше 0, это означает, что некоторые детали попали в поле зрения пользователя.

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

пример кода

Для студентов, которых смущает отложенная загрузка, я написал DEMO здесь для справки.исходный код

в заключении

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

Или вы можете напрямую использовать стороннюю библиотеку компонентовvue-lazyload

Используйте svg-иконки

По сравнению с использованием изображения для представления значка, svg имеет лучшее качество изображения, меньший размер и не требует открытия дополнительных HTTP-запросов. svg — это будущая тенденция. Библиотека значков Ali iconfont поддерживает экспорт значков в формате svg. Однако компонент который поддерживает svg, должен быть инкапсулирован в проекте. Конкретное руководство по инкапсуляции см. в статье о цветочных штанах. Здесь я не буду вдаваться в подробности.Прикоснитесь к своей руке, чтобы элегантно использовать значок, или вы можете обратиться к моемуgithub

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

Изображение webp было первоначально выпущено в 2010 году с целью уменьшить размер файла, но добиться того же качества изображения, что и формат JPEG, в надежде сократить время, необходимое для отправки файлов изображений по сети. Средний размер изображения без потерь в формате webp на 20–40% меньше, чем размер изображения без потерь в формате png, и невооруженным глазом почти нет разницы в качестве изображения.

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

Здесь нам нужно использовать адаптивные изображения. HTML предоставляет тег изображения, чтобы мы могли использовать разные форматы изображений на разных устройствах.

MDN:

Элементы HTML определяются как содержащие ноль или более элементов иэлемент для предоставления версий изображения для различных сценариев отображения/устройства. Браузер выберет дочерний элемент, который соответствует лучше всего, и если совпадения нет, он выберетURL-адрес в атрибуте src элемента. Затем выбранное изображение отображается вв пространстве, занимаемом элементом.

В проекте мы можем использовать это

Тег picture заключает в себе два исходных тега, один предоставляет изображения webp и позволяет браузеру выбирать поддерживаемые форматы изображений сверху вниз с помощью атрибута srcset.Если браузер не поддерживает изображения webp, будет использоваться только второй источник, и он вернется к изображению png, если браузер не поддерживает тег изображения, будет использоваться тег img внизу, и также будет сгенерировано изображение png

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

Сжать изображения

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

Так же есть загрузчик для сжатия изображенийimage-webpack-loader, сжимать изображение до определенной степени в случае, если пользователь не может различить его невооруженным глазом

Связанные с кодированием

Этот аспект кодирования в основном предназначен для уменьшения доступа к DOM, уменьшения перекомпоновки/перерисовки браузера, доступ к DOM — очень дорогая операция, поскольку задействованы 2 разных потока (поток JS и поток рендеринга пользовательского интерфейса) и сам DOM. Еще один очень громоздкий объект , вот несколько предложений

  • Если есть необходимость в динамическом создании DOM, вы можете создать фрагмент документа (DocumentFragment), работать с фрагментом документа, поскольку он не находится в текущем потоке документов и не вызовет перекомпоновку/перерисовку, и, наконец, вставить узел DOM в один раз.

  • Избегайте частого получения информации о представлении (getBoundingClientRect, clientWidth, offsetWidth).Когда происходит операция переупорядочивания/перерисовки, браузер будет поддерживать очередь и ждать, пока не будет превышено максимальное значение или не пройдет указанное время (1000 мс/60 = 16,6 мс). Очистите очередь для выполнения операции за один раз, что может снизить производительность, а получение информации о просмотре немедленно очистит очередь для выполнения переупорядочения/перерисовки.

  • Используйте функцию anti-shake/throttle для высокочастотных событий прослушивания (можно использовать функцию дросселя из библиотеки lodash, но сначала рекомендуется понять принцип)

  • Специальные эффекты могут запускать слой рендеринга отдельно (преобразование CSS3 будет запускать слой рендеринга), а анимация может использовать абсолютное позиционирование, чтобы оторваться от потока документа.

Советы в процессе разработки

Использование require.context, API-интерфейса веб-пакета, позволяет избежать необходимости явно импортировать с помощью import каждый раз, когда вводится файл.Он может сканировать указанные вами файлы, а затем импортировать их все в указанные файлы.Его можно использовать в

  • маршруты vue-router автоматически импортируются
  • автоматический импорт модуля vuex
  • Автоматический импорт иконок svg
  • Автоматический импорт глобальных компонентов

векс:

Таким образом, при создании нового модуля вам не нужно импортировать его в index.js и снова объявлять в модулях.

Глобальные компоненты и иконки svg:

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

Заинтересованные друзья могут взглянуть на мою другую статью, посвященную этому API.блог

исходный код

Часть оптимизированного решения размещена у меня на гитхабе, если интересно, можете глянуть

Адрес источника

Следующая статья здесь:

Как обновить систему фонового управления компании (ниже) — компоненты пакета

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

vue-element-admin

D2 Admin

Привет, отправить вам карту оптимизации веб-производительности

Проект Vue-cli3 от оптимизации сборки до развертывания докера

Оптимизация производительности интерфейса не завершена