предисловие
Стример легко бросать людей, красные вишни, зеленые бананы. Тихо маятник на стене указал на середину 2020 года, и время словно нежная рука спряталась во мраке, между трансом и трансом. 2020 год для человечества крайне ухабистый. Будь то австралийские лесные пожары или охватившая мир чума, они набросили на землю серую пелену. Однако люди не сидели на месте, а давали отпор! Как национальный бренд, JD.com также взял на себя социальную ответственность и всегда был на переднем крае борьбы.
Членство в JD PLUS — это услуга, запущенная JD.com для предоставления основным клиентам лучшего опыта покупок.В период Gengzi, спустя полгода, она сильно выросла: несколько основных страниц каналов были переработаны и обновлены, а фирменная карта также открыла Tencent QQ, Сильный вход в музыку и Mango TV, пересмотр страницы калькулятора и создание собственной системы контроля рисков члена PLUS приложили большие усилия с точки зрения привлечения пользователей и конфигурируемости проекта. , Такие как:
На домашнюю страницу канала добавлена анимация всплывающего конверта, чтобы увеличить удовольствие, и добавлена функция всплывающего окна удержания, чтобы уменьшить ситуацию, когда буддийские пользователи приходят и уходят в спешке, не убирая облако;
Кроме того, в первой половине 2020 года в основном поддерживались следующие потребности в части доработки страниц, новых прав и интересов, оптимизации и улучшения функций, оптимизации НИОКР:
В настоящее время количество официальных пользователей приближается к отметке в 20 миллионов, и все так процветает и бодрит.
Как бы ни запало в душу, будь то модернизация технологий или проекты постоянного совершенствования в«Путь к начальному развитию участников JD PLUS в 2019 году»Оптимизация, упомянутая в этой статье, эквивалентна первому шагу в Великом походе, Нам еще многое предстоит сделать, особенно с быстрой итерацией требований, постепенно выявляются некоторые новые проблемы, и мы постепенно понимаем, что отличный проект A должен быть в состоянии установить надежную архитектуру и окружающие системы для обеспечения непрерывного обновления и итерации проекта и эффективного развития. Это правда, что мы еще многое можем сделать до сих пор, но мы могли бы также остановиться и проанализировать путь, который мы прошли за последние шесть месяцев, взять суть и отбросить шлак.
Далее эта статья начнется с повышения эффективности разработки, оптимизации структуры проекта, улучшения пользовательского опыта и т. д. и поделится с вами нашим опытом в процессе разработки проектов в первой половине 2020 года с целью привлечь других и учиться вместе.
1. Повысить эффективность разработки
В процессе разработки проекта часто незаметная оптимизация всегда может принести неожиданную прибыль. Мы также неустанно стремимся постоянно выявлять проблемы, возникающие при разработке, и способы улучшения процесса и повышения эффективности разработки.
1.1 Автоматически генерировать новые шаблоны
С итерацией спроса предыдущая страница канала постепенно не может удовлетворить текущий спрос, особенно потребности страницы системы управления рисками, созданной участниками PLUS, и пересмотр страницы канала необходимо добавить новые страницы, поэтому сколько шагов это занимает добавить новую страницу? ?
Как показано на рисунке выше, для добавления новой страницы требуется пять шагов:
1. Во-первых, добавьте Html-страницу для загрузки и загрузки статических ресурсов и скелетных экранов;
2. JS-файл новой записи — это файл записи новой страницы, то есть файл записи, упакованный Webpack;
3. Добавлен основной файл Vue для разработки логики новых страниц;
4. Измените файл конфигурации Webpack, добавьте запись и добавьте соответствующую конфигурацию подключаемого модуля HTML, например:
new HtmlWebpackPlugin({
template: './src/template/new-expired.html',
filename: path.resolve(__dirname, 'build/new-expired.html'),
inject: false
}),
5. Измените компонент кода загрузки и добавьте недавно добавленную запись JS;
Таким образом, каждый раз, когда добавляется новая страница, необходимо изменять указанные выше пять конфигураций.Эти шаги громоздки, и один элемент иногда пропускается, что приводит к возникновению ошибок страницы. Так как же упростить шаги по добавлению новых страниц?
Так что учитесь у командыБиблиотека компонентов NutUIИдею добавления новых компонентов и автоматического создания соответствующих конфигурационных файлов мы внедряемinquirer
Библиотеки, инструмент для взаимодействия пользователей с командной строкой. Выполните команду для автоматического создания и изменения вышеуказанных пяти файлов конфигурации.
Во-первых, вводятся инструменты взаимодействия пользователя и командной строки для ввода имени новой страницы:
// 关键代码
inquirer.prompt([
{
type: 'input',
name: 'pageName',
message: '新建页面英文名称:',
validate(value) {
const pass = value && value.length <= 20;
if (pass) {
return true;
}
return '不能为空,且不能超过20个字符';
},
}
])
.then(function (answers) {
createDir(answers);
});
При выполнении файла в командной строке отобразится следующее:
После того, как мы введем английское имя и китайский заголовок нового файла, мы можем продолжить, например, создать новый HTML-файл в указанной папке:
function createHtml(value) {
const htmlCode = templateHtml.replace(/\{template\}/g, value.pageName).replace(/{title}/g, value.pageTitle);
const createHtml = path.resolve(__dirname, `../createTemplate/${value.pageName}.html`);
fs.writeFileSync(createHtml, htmlCode);
}
Кроме того, необходимо автоматически модифицировать файл конфигурации в формате json,
function createJson(value) {
entrys[value.pageName] = `./src/entry/${value.pageName}.js`;
const createJson = path.resolve(__dirname, './entrys.json');
fs.writeFileSync(createJson, JSON.stringify(entrys));
}
Согласно автоматически сгенерированному файлу json, когда локальная служба запускается или код упакован и скомпилирован, Webpack может создать соответствующую запись записи и элементы конфигурации, такие как подключаемый модуль HtmlWebpackPlugin.
const entryConfigs = require('./templates/entrys.json');
Reflect.ownKeys(entryConfigs).forEach( key => { //循环遍历对象
webpackConfig.plugins = (webpackConfig.plugins || []).concat([
new HtmlWebpackPlugin({
template: `./src/template/${key}.html`,
filename: path.resolve(__dirname, `build/${key}.html`),
inject: false
})
])
});
Таким образом, исходная история изменения или создания пяти файлов каждый раз, когда добавляется новая страница, исчезает навсегда, а создание новой страницы может быть завершено одной строкой команды, что не только повышает эффективность, но и снижает риск упущения, вызванный действиями человека.
1.2 Автоматические подсказки перед выходом кода в сеть
Как говорится, большие дары не стесняются идти на маленькие уступки, а успех или неудачу определяют детали. Такова жизнь, такова и программа. Из-за быстрой итерации требований и в среднем пять или шесть требований, которые должны разрабатываться параллельно каждую неделю, мы используем несколько веток для параллельной разработки и обновляем номер версии каждый раз, когда выходим в сеть, чтобы избежать кэширования статических ресурсов пользователей. Однако представьте себе, что если требования разрабатываются упорно, После выхода в интернет с большим нетерпением я вдруг обнаружил, что код предыдущей ветки не был объединен! Или без изменения номера версии! Это должно быть похоже на удар грома, и в моей голове должно быть 10 000 альпак, скачущих мимо. . . Не спрашивайте меня, почему я подумал об этом, это должно быть болезненное воспоминание! Никогда не полагайтесь на искусственную память, чтобы гарантировать необходимые операции перед выходом в эфир, иначе вы будете чувствовать себя так же, как я. Так как же нам избежать подобных проблем? Может ли кто-нибудь сказать мне, прежде чем выходить в эфир и проверить необходимые операции?
Чтобы разобраться, чтобы реализовать эту функцию, необходимо выполнить следующие требования:
-
Функция подсказки срабатывает только тогда, когда разработчик отправляет код в основную ветку;
-
Перехватите процесс отправки кода и предложите разработчику обратить внимание. Если разработчик выберет значение true, продолжите процесс отправки кода, в противном случае завершите процесс отправки кода.
Поэтому я обратил свое внимание на технологию git-hook,
Когда проект хочет использовать git для отправки кода, используйте git-ловушку перед фиксацией, чтобы автоматически выполнять некоторые коды обнаружения скриптов при вызове команды git commit.В нашей локальной сети задачи не будут отправляться в удаленные репозитории.
git-hooks находится в папке .git/hooks репозитория git и содержит много хуков.Эти файлы автоматически генерируются при создании репозитория git.Откройте папку hooks и вы увидите:
Суффикс .sample означает, что значение по умолчанию недействительно, поэтому нам нужно создать файл предварительной фиксации, который будет выполнять код файла при отправке кода, чтобы мы могли поместить код подсказки функция в этом файле development.
Как показано ниже, при повторной отправке кода сначала определите, является ли это основной ветвью.Если это основная ветвь, это означает, что она переходит в режим онлайн, поэтому код в файле предварительной фиксации выполняется, как показано в следующем фигура:
Процесс отправки кода продолжится, только если все ответы равны y.
Так вот еще вопрос, как заставить всю команду пользоваться этой функцией? Вы хотите, чтобы каждый участник добавил этот файл локально? Когда мы запускаем проект, мы обычно запускаемnpm run dev
, который должен запускать службу локально, поэтому мы можем использовать этот необходимый шаг, чтобы поместить код, который изменяет файл предварительной фиксации на этом шаге, чтобы каждый член добавлял файл в хуки при запуске локальной службы. , поэтому я внедрил функцию предварительной фиксации без ведома членов команды и подождал, пока маленькие друзья обнаружат это пасхальное яйцо, прежде чем выйти в сеть~
1.3 Автоматическая проверка перед отправкой кода
Хотя метод в версии 1.2 только перехватывает подсказку перед выходом в сеть, остается ли место для действий в процессе разработки? Вот несколько распространенных сценариев:
1. Во время разработки новых требований основная ветка могла многократно обновляться, поэтому нам необходимо вовремя сливать основную ветку, чтобы поддерживать текущую ветку разработки в актуальном состоянии;
2. Когда разные разработчики используют ветку, они часто забывают скомпилировать и загрузить чужой код, в результате чего чужой код перезаписывается;
3, собственная полная ветка ствола слияния, иногда забывают загрузить;
Цели
Для этих проблем мы можем полагаться на запуск сценария и использовать сценарий для проверки того, все ли проекты завершены один за другим. Сначала рассмотрим метод реализации. Перед обновлением мы должны сначала определить, чего мы хотим достичь: автоматически проверять состояние текущей ветки и локальной ветки.
1,Все файлы должны быть загружены локально
Поскольку только локальная и онлайн-синхронизация может дать правильный результат, эта операция загрузит сервер только на локальный сервер и не объединит его.
git fetch
2,Проверьте основную ветку на наличие незафиксированных или ожидающих обновлений.
В основной ветке мы можем проверить текущий статус с помощью команд.Внизу может быть два статуса, впереди или позади представляют отношения с удаленной ветвью, для обновления или для отправки, на следующем рисунке показан статус для отправки
git status
3.Определить статус текущей ветки и основной ветки
Если текущая ветвь не является основной, это решение требуется.Если обнаружено, что она объединена, пользователю предлагается объединить код. Вы можете использовать следующую команду для просмотра ветвей, которые были объединены в текущей ветви, чтобы определить, следует ли объединять основную ветвь.
git branch --merged
4.Определить, есть ли в текущей ветке незафиксированное или подлежащее обновлению содержимое.
Если текущая ветвь не является основной ветвью, выполняется это содержимое, а логика оценки такая же, как 2.
Блок-схема выглядит следующим образом:
Выполнение
Используйте метод выполнения скриптов для замены ручных операций. Среда скаффолдинга переднего плана - узел. Первым шагом является выбор библиотеки, которая может работать с git в библиотеке npm. Я выбралsimple-git.
1. Первым делом определяем есть ли удалённый, если удалённого адреса нет, то выборка не может быть выполнена, и последующее сравнение некорректно.
const git = require('simple-git');
git().getRemotes(true, (err, res) => {
//do something
})
2. Чтобы решить, нужно ли отправлять ствол, оцените статус ветки ствола по состоянию isBehind и isAhead:
const mainBranch = master;
const behindReg = /behind(?= \d+\])/gi;
const aheadReg = /ahead(?= \d+\])/gi;
git().branch(['-vv'], (err, res) => {
const mainBranchInfo = res.branches[mainBranch]
const isBehind = mainBranchInfo.label.search(behindReg);
const isAhead = mainBranchInfo.label.search(aheadReg);
});
3. Определить, объединена ли текущая ветвь с транком, и проверить, объединена ли она следующими способами.Если объединения нет, пользователю может быть предложено:
const mainBranch = master;
git().branch(['--merged'], (err, res) => {
const isMerged = res.all.includes(mainBranch);
});
4. Чтобы определить, нужно ли отправлять текущую ветку, метод выглядит следующим образом, определяя, нужно ли обновлять переменную Behind:
getCurrentBehind() {
return new Promise((resolve, reject) => {
git().status((err, res) => {
if (err) reject();
else resolve(res.behind);
});
});
}
const Behind = await gitFn.getCurrentBehind();
В итоге формируются следующие подсказки:
1.4 Автоматически генерировать документацию
Проект M-стороны члена PLUS растет, а также растет сложность обслуживания и отладки программ.Иногда функции инструментов или бизнес-логика, которые мы инкапсулируем, не содержат аннотаций, а другим небольшим партнерам труднее понять при использовании или вторичной разработке. Чтобы повысить читабельность и надежность программы, мы добавили в проект документацию API, чтобы члены команды могли быстро запросить и начать разработку проекта.Кроме того, чтобы сэкономить на стоимости обслуживания документации API, мы используемjsDoc
Автоматически генерировать документацию.
JsDoc
Документация по интерфейсу может генерироваться автоматически на основе нормализованных аннотаций, например:
/**
* @description 判断是否在小程序环境中
* @returns {Boolean} result 结果
*/
export function isMiniprogram() {
const plusFrom = getCookie('plusFrom');
return !!~['xcx', 'xcxplus'].indexOf(plusFrom);
}
Такая функция была быjsDoc
Соберите их и занесите в документацию по разработке, а затем мы сможем сами создать рабочий процесс npm-скрипта, который удобно запускать из командной строки:
"docs": "rimraf docs && jsdoc -c ./jsdoc-conf.js && live-server docs"
jsdoc-conf.js
даjsdoc
Файл конфигурации включает в себя некоторые элементы конфигурации документа, после чего мы можем начать автоматическое построение документа!
воплощать в жизньnpm run docs
, или вы можете объединить команду вnpm run dev
в исполнении.
Далее браузер автоматически откроет страницу документации локально:
В левой части страницы находится каталог API. API в разделе Globals — это функция инструмента, которую мы написали в файле JS, а модуль в разделе «Модули» — это модуль компонента Vue. Давайте посмотрим, как добавить комментарии к модулю компонента Vue:
/**
* @module drag
* @description 拖拽组件,用于页面中需要拖拽的元素
* @vue-prop {Boolean} [isSide=true] - 拖拽元素是否需要吸边
* @vue-prop {String} [direction='h'] - 拖拽元素的拖拽方向
* @vue-prop {Number | String} [zIndex=11] - 拖拽元素的堆叠顺序
* @vue-prop {Number | String} [opacity=1] - 拖拽元素的不透明级别
* @vue-prop {Object} [boundary={top: 0,left: 0,right: 0,bottom: 0}] - 拖拽元素的拖拽边界
* @vue-data {Object} position 鼠标点击的位置,包含距离x轴和y轴的距离
*/
//业务代码。。。
Поскольку компоненты Vue не могут быть нативнымиjsDoc
Поддержка, здесь мы используемjsDoc-vue
, поэтому аннотации компонентов тоже разные.Конкретные спецификации можно посмотреть в официальной документации. Затем мы можем увидеть комментарии, относящиеся к этому компоненту, в документации по API.
Спецификацию аннотации компонента vue можно запроситьjsdoc-vue
официальная документация. После того, как мы напишем аннотацию, нам нужно выполнитьnpm run docs
для восстановления документации.
1.5 Оптимизация логики номера версии
Чтобы пользователи могли получать последний код после каждого запуска вместо использования кэшированных ресурсов, необходимо изменить номер версии каждого запуска, например, изменить 4.1.2 в следующей ссылке:
https://static.360buyimg.com/exploit/mplus/4.1.2/v4/js/index.js
Поскольку у нас есть доступ к головной и хвостовой системе компании, нам нужно только изменить номер версии в головной и хвостовой системе.
Что такое система «голова-хвост»? Это можно просто понять так: сервер импортирует файл конфигурации A из этой системы, внешний интерфейс вводит код в файл A и одним щелчком мыши отправляет его на указанный сервер для обновления внешних ресурсов, представленных на сервере. .
Однако мы обнаружили, что каждый раз, когда мы подключаемся к сети, нам приходится запускать десятки серверов в головной и хвостовой системах.Часто всегда возникают сбои при загрузке сервера или обнаруживаются новые проблемы в предварительной версии после выхода в сеть, и нужно срочно откатить номер версии, поэтому повторное проталкивание головных и хвостовых файлов занимает много времени.
Поэтому мы задаемся вопросом, есть ли лучший способ решить эту проблему? Или облегчить такие проблемы. В это время логика сравнения номеров версий снова появляется перед нашими глазами. Причина, по которой используется слово «повторно», заключается в том, что эта логика существовала раньше, но в то время не была решена динамическая генерация скриптов статических ресурсов, что приводило к невозможности гарантировать порядок выполнения, что приводило к проблеме белого экрана. на странице (подробнее об этой проблеме см. в статье:«Путь к начальному развитию участников JD PLUS в 2019 году»), поэтому функция была удалена в то время. Пришло время пересмотреть эту функцию:
1. Поддерживать номер версии V1 в шаблоне Html на стороне сервера;
2. Передняя часть поддерживает номер версии V2 в системе головы и хвоста;
Внешний интерфейс разрабатывает логику сравнения номеров версий в Html и использует большее значение из двух номеров версий для динамического создания соответствующих статических ресурсов.
/*
V1 就是放在 Html 中的版本号
V2 就是前端在头尾文件中放置的版本号
最终使用的是较大的版本号
*/
if (typeof V2 != 'undefined'
&& Number(V2.replace(/\./g, '')) > Number(V1.replace(/\./g, ''))) {
V1 = V2;
}
Имеются две соответствующие ситуации:
1. Только внешний интерфейс должен быть подключен к сети, и внешний интерфейс выдвигает обновленный номер версии в системе head-tail, которая такая же, как и раньше;
2. Если это проект, который необходимо запустить на передней и задней частях, серверная часть изменит номер версии V1 в Html.Согласно логике сравнения номеров версий в Html, больший из двух номеров версий будет используется, и сгенерированные статические ресурсы будут сгенерированы.Используется номер версии, установленный бэкэндом в Html, поэтомуПередний конец сохраняет шаг нажатия файлов головы и хвоста, только задний конец должен перейти в Интернете;
Тем не менее, нажатие на тыквенный совок начинается снова.Хотя фронтальный толчок головных и хвостовых файлов облегчается, необходимо убедиться, что номера версий имеют отношение последовательности размеров. Таким образом, мы указали номер версии каждого требования в соответствии с онлайн-порядком требований.После запуска в течение определенного периода времени пришло срочное требование и срочное требование онлайн-ошибки, и номер версии должен быть вставлен между первоначально отсортированной версией числа. , аналогично упорядоченному массиву. Если элемент вставляется в начало массива, последующие элементы будут изменены соответствующим образом. После обсуждения переходим к следующей стратегии:
1. Только три цифры представляют номер версии, затем используйте первые две цифры в качестве основного номера версии, например: 4.1.0, 4.2.0...4.99.0;
2. Используйте третий номер версии, чтобы указать номер версии срочных потребностей, например, текущий номер версии 4.2.0, а если вставлена срочная потребность, это будет 4.2.1;
Это увеличивает количество основных номеров версий: первые две цифры могут быть расширены до большого числа, а вставленный номер версии срочного запроса не повлияет на ранее отсортированные номера версий, а также может уменьшить количество онлайн-шагов, что может можно охарактеризовать как убийство трех зайцев одним выстрелом!
1.6 Автоматическое сжатие изображения
Сжатие изображений всегда было важной частью оптимизации внешнего интерфейса, и можно также сказать, что это важная часть процесса разработки. Сжатие изображений предыдущего проекта PLUS находилось в состоянии спонтанной и ручной обработки, что является отличной проверкой степени внимательности и сознательности каждого.
Чтобы стандартизировать этот процесс, мы ввелиGaeaФункция автоматического сжатия картинок и конвертации webp в скаффолдинг. Нечего сказать, по коду
const imagemin = require('imagemin');
const imageminWebp = require('imagemin-webp');
const path = require('path');
const fs = require('fs');
const tinify = require("tinify");
const config = require("./package.json");
tinify.key = config.tinypngkey;
const filePath = './src/asset/img';
const files = fs.readdirSync(filePath);
const reg = /\.(jpg|png)$/;
async function compress(){
for(let file of files){
let filePathAll = path.join(filePath,file);
if(reg.test(file)){
await new Promise((resolve,reject)=>{
fs.readFile(filePathAll,(err,sourceData)=>{
tinify.fromBuffer(sourceData).toBuffer((err,resultData)=>{
//将压缩后的文件保存覆盖
fs.writeFile(filePathAll,resultData,err=>{
resolve();
})
})
})
})
}
}
imagemin(['./src/asset/img/*.{jpg,png}'],'src/asset/img/webp',{
use:[
imageminWebp()
]
}).then(()=>{
console.log(chalk.green(`webp转换已完成~`));
})
}
compress();
Как использовать в css:
@mixin webpbg($url, $name) {
background-image: url($url + $name);
background-repeat: no-repeat;
@at-root .webp & {
background-image: url($url + "webp/" + (
str-slice($name, 0, str-index($name, ".") - 1)
) + ".webp");
}
}
str-slice(string, start, end) перехватывает подстроку из строки и устанавливает начальную и конечную позиции через start и end.Если значение конечного индекса не указано, по умолчанию он будет перехватываться до конца строки . str-index(string, substring) возвращает позицию первого вхождения подстроки substring в строку. Возвращает null, если ни одна подстрока не соответствует.
Поскольку этот метод webpbg определен в общедоступном файле common-mixin.scss, а вызовы распределены в каждом компоненте, вызов в компоненте сообщит об ошибке, что функция webpbg не может быть найдена. Если вы хотите использовать этот метод webpbg глобально, вам необходимо импортировать его глобально в webpack.config.js Метод модификации выглядит следующим образом.
@include webpbg("../../asset/img/index-formal/", "formal-title.png");
В результате учитель неблагоприятно, и это неправильно!
Обычно мы помещаем Mixin в текущий файл Sass.Если вы хотите использовать его глобально, вам нужно импортировать его глобально в webpack.config.js.
Ну картинка сжимается, автоматически конвертируется в webp, и стиль поддерживает webp, все идет гладко.
Однако по мере увеличения наших изображений и увеличения количества сжатий проблема возникает снова: Поскольку инструмент tinypng используется для сжатия изображения, нам необходимо зарегистрироваться по электронной почте, чтобы получить ключ при его использовании. Для бесплатных пользователей один и тот же ключ может сжимать только 500 изображений в одном месяце.
Поэтому нам нужно нарушить это ограничение. Помимо подачи заявки на еще несколько ключей, можем ли мы улучшить стратегию оптимизации?
На самом деле, после того, как общая картинка будет вырезана, она не будет часто меняться, особенно та часть, которая была онлайн, возможности изменения меньше. Следовательно, мы можем изменить полное сжатие изображения на добавочное сжатие и сжимать только измененные или новые. Основываясь на этой стратегии, количество сжатых изображений не будет очень большим, а ограничение нарушается вот так~ Рассмотрим конкретные шаги реализации:
Вот фрагмент кода, который генерирует хеш-значение:
let rs = fs.createReadStream(filedir); //打开一个可读的文件流并且返回一个fs.ReadStream对象
let hash = crypto.createHash("md5"); //创建并返回一个 Hash 对象,该对象可用于生成哈希摘要
let hex;
return await new Promise((resolve, reject) => {
//在内部不断触发rs.emit('data',数据);
rs.on("data", hash.update.bind(hash)); // hash.update使用给定的 data 更新哈希的内容
//end事件表示这个流已经到末尾了 ,没有数据可以读取了
rs.on("end", function () {
hex = hash.digest("hex"); //计算传入要被哈希的所有数据的摘要,返回字符串
result[filedir.replace(/\/|\\/g, "/")] = hex; // 统一mac及windows下的文件路径,将其作为key值,生成的hash值为value,存入result中
resolve();
});
//error事件表示出错了
rs.on("error", function (msg) {
console.log("error", filedir);
reject();
});
});
2. Оптимизируйте структуру проекта
Зачем продолжать оптимизировать структуру проекта? Проект подобен законченному зданию, если несущие стены время от времени ломать для украшения и если за ним вовремя не ухаживать, то в конце концов оно будет изрешечено дырами и окажется под угрозой исчезновения. Точно так же, как проект долгосрочного обслуживания, членский проект JD PLUS, с быстрой итерацией требований и вставкой срочных требований, постепенно всплывают проблемы, которые сначала не рассматривались, или проблемы, которые мешают прогрессу разработки проекта. работать в течение длительного времени и избежать более раздутого кода, мы в основном проделали следующую работу:
2.1 Извлечение основных компонентов
В глазах тысячи людей тысячи Гамлетов. Как делить компоненты, видимо у каждого разработчика разное понимание. Так как же разделены компоненты членской программы PLUS?
Например, следующее всплывающее окно:
Сначала мы использовали базовый компонент в библиотеке компонентов NutUI — компонент всплывающего окна Dialog, а затем на основе этого компонента мы разработали компонент всплывающего окна бизнес-калькулятора, чтобы лучше улучшить повторное использование компонента и уменьшить изменения бизнес-логики. Воздействие компонента должно состоять из следующих форм:
Компоненты в нашем текущем проекте также работают в этом направлении, потому что мы обнаружили, что некоторые базовые компоненты NutUI были представлены в проекте PLUS, а затем были внесены некоторые изменения в соответствии с потребностями бизнеса. После долгого периода стабильной работы изменений в этих компонентах немного, поэтому, чтобы уменьшить проект, мы извлекаем эти базовые компоненты и публикуем их в npm, и, наконец, упаковываем их в папку node_modules, чтобы проект Код этих базовых компонентов будет сильно сокращен, и код этих компонентов не нужно будет каждый раз упаковывать и компилировать.
Стоит отметить, что все отлично работает при локальной разработке, но дает сбой при упаковке и развертывании. После расследования выяснилось, что в пакете npm хранится только исходный код компонента, и он не был скомпилирован, поэтому при его непосредственном использовании в проекте будет сообщено об ошибке, и проблема будет раскрыта. Итак, нужно ли нам строить отдельные леса для этих компонентов? Наши остроумные друзья придумали метод использования цыплят для несения яиц — используя в качестве носителя строительные леса библиотеки компонентов NutUI, создавая базовые компоненты PLUS в библиотеке компонентов, а затем компилируя эти компоненты, которые необходимо запаковать через библиотеку компонентов. , экспорт. Таким образом, развертывая скомпилированный код в npm, зависимые пакеты могут быть напрямую установлены и использованы в проекте.Эффект следующий.Видно, что импортированный код в упакованном проекте также сильно упрощается:
2.2 Уменьшение существующей ветки
Проект PLUS должен разрабатывать пять-шесть требований параллельно каждую неделю в среднем.Как мы можем гарантировать, что требования параллельной разработки не будут мешать друг другу?Мы используем многоветвевой метод.При создании новой ветки имя ветки используется аббревиатура пиньинь, необходимая в то время.Например, официальное требование к редакции: zsgb; после завершения разработки она объединяется с основной веткой каждый раз, когда выходит в сеть, как показано ниже:
Не знаю, нашли ли вы какие-нибудь улики? Есть ли риск в названии ветвей таким образом? После полугода работы мы обнаружили, что в кодовой базе появляется все больше и больше веток, многие новые ветки уже не используются после разработки, но их приходится каждый раз вручную удалять, и нужно вручную оперировать. ненадежный. Подумав над этим, мы решили использовать инициалы каждого участника разработки в качестве названия ветки.Например, для одноклассника по имени «Чжан Дафа» вновь созданная ветка будет «zdp».Вы можете развиваться на ней, и преимущества следующие:
-
Количество подветвей в каждой основной ветке фиксировано, и у каждой НИОКР есть соответствующая подветвь для разработки;
-
Избегайте ручного удаления избыточных шагов ветвления в кодовой базе и уменьшайте случайное удаление ветвей;
-
Избегает проблемы увеличения подветвей;
После вышеперечисленных операций десятки подветвей в исходной кодовой базе были сокращены до нескольких веток, что значительно сокращает объем кода и ускоряет загрузку кода.
2.3 Оптимизация каркаса на стороне ПК
По историческим причинам проект членства PLUS на стороне ПК разработан с использованием стека технологий React, и с развитием технологий доля мобильных терминалов увеличивается, а соответствующая доля ПК-терминалов с каждым годом сокращается. , и многие функции также перенимаются.Это приводит к проблеме, и мы вносим меньше изменений на стороне ПК, но исходный каркас на стороне ПК относительно старый, и в процессе компиляции часто возникают проблемы, такие как:
1. Скорость упаковки кода крайне низкая, во время упаковки можно пить чай, есть семечки дыни и взбивать бобы;
2. Генерировать файл, названный по хеш-значению, и заменять каждое хеш-значение по одному для каждой совместной сверки и отката версии, что не способствует комфортному настроению и вызывает у людей раздражение;
3. Не поддерживает горячие обновления, что приводит к необходимости ручного обновления страницы при каждом изменении, а побочный эффект в том, что может исправить обсессивно-компульсивное расстройство Девы;
4. Не поддерживает упаковку файлов по требованию, все файлы будут упаковываться каждый раз, когда они будут упаковываться, и только некоторые из них будут загружены в онлайн;
Не терпится - не надо больше терпеть, исходя из этого, мы в основном сделали следующие оптимизации, обновили Webpack с версии 2 до 4, переделали все конфигурационные файлы и сделали следующие оптимизации:
Эффективность упаковки низка, а разработка и совместная отладка более хлопотны, поэтому строительные леса необходимо оспорить и оптимизировать. А с развитием технологий в наших проектах можно использовать множество новых технологий для повышения эффективности разработки. Из-за огромного количества кода здесь он только указывает направление.Если у вас есть какие-либо вопросы, вы можете оставить сообщение в области комментариев для обсуждения~
2.4 Спецификации отправки кода
Цель стандартизации отправки кода — лучше отслеживать код, фильтровать и быстро определять область действия и функции реализации, задействованные в отправленном коде. Для такого проекта, как PLUS, который постоянно развивается и повторяется, необходимо повысить стандартизацию отправки кода. Как говорится, нет правил и нет кругов. Поэтому мы ввели в проект vue-cli-plugin-commitlint, чтобы ограничить и стандартизировать отправку кода. Это может не только улучшить концепцию спецификации фиксации для членов команды, но и унифицировать стиль отправки нашего кода.Что еще более важно, он может автоматически генерировать автоматический журнал изменений, что удобно для нас, чтобы найти отправленную версию и обеспечить удобство для быстрого позиционирование проблем, возникших позже.
vue-cli-plugin-commitlint
— это стандартная спецификация коммитов git, которая сочетает в себе коммитизен, коммитлинт, обычный-чейнджлог-кли и хаски.
Давайте посмотрим, как это использовать в проекте.
Установить зависимости
npm i vue-cli-plugin-commitlint commitizen commitlint conventional-changelog-cli husky -D
добавить в package.json
{
...
"scripts": {
"log": "conventional-changelog --config ./node_modules/vue-cli-plugin-commitlint/lib/log -i CHANGELOG.md -s -r 0",
"cz": "npm run log && git add . && git status && git cz"
},
"husky": {
"hooks": {
"commit-msg": "commitlint -E HUSKY_GIT_PARAMS"
}
},
"config": {
"commitizen": {
"path": "./node_modules/vue-cli-plugin-commitlint/lib/cz"
}
}
}
Добавьте файл commitlint.config.js
module.exports = {
extends: ['./node_modules/vue-cli-plugin-commitlint/lib/lint']
};
Затем выполните npm run cz, в это время вам будет предложено выбрать, а затем заполнить в соответствии с подсказками, чтобы сгенерировать сообщение фиксации, соответствующее формату.
После завершения отправки в корневом каталоге проекта будет создан файл журнала CHANGELOG.md.Щелкните commitId в файле, чтобы перейти к просмотру соответствующего содержимого отправки.
2.5 Увеличить скорость упаковки строительных лесов
По мере того, как проект продолжает повторяться, количество файлов растет, а проект становится большим, в результате чего сборки Webpack становятся все медленнее и медленнее. Каждая сборка занимает определенное количество времени, и особенно необходимо увеличить скорость сборки.
Как мы все знаем, Webpack работает на Node.js с использованием однопоточной модели, и задачи обработки выполняются последовательно. Несколько задач не могут обрабатываться одновременно и должны быть поставлены в очередь. Есть ли способ разрешить Webpack обрабатывать несколько задач параллельно одновременно?
Для решения этих вопросов у нас есть доступ к HappyPack, он позволяет Webpack делать это, вы можете разбить задачи на несколько параллельных дочерних процессов, чтобы выполнить дочерний процесс, а затем отправить результаты основному процессу. Основной принцип HappyPack заключается в том, что эта часть задачи разлагается на несколько процессов для параллельной обработки, тем самым сокращая общее время сборки.
Далее давайте посмотрим, как получить к нему доступ в проекте.
Установить зависимости
npm install happypack -D
Настройте webpack.config.js
Во всем процессе построения Webpack наиболее трудоемкой является операция преобразования файла с помощью Loader, поскольку необходимо преобразовать большое количество файловых данных, а операцию преобразования необходимо поставить в очередь для последовательной обработки.
Настройте загрузчик, код выше.
module.exports = (env, argv) => {
const webpackConfig = {
//...
module: {
rules: [{
test: /\.js$/,
loader: 'happypack/loader?id=happyBabel',
// 排除 node_modules 目录下的文件
exclude: [
path.resolve(__dirname, 'node_modules'),
path.resolve(__dirname, 'jssdk.min.js')
]
},
//...
]
},
//...
}
}
Мы передаем обработку файлов .js в happypack/loader, а затем используем идентификатор, чтобы определить, какой экземпляр HappyPack выбирает happypack/loader для обработки файла.
Добавьте соответствующий экземпляр HappyPack.
const HappyPack = require('happypack');
const os = require('os');
const happyThreadPool = HappyPack.ThreadPool({ size: os.cpus().length });
//...
module.exports = (env, argv) => {
const webpackConfig = {
//...
plugins: [
new HappyPack({
// 唯一的id标识
id: 'happyBabel',
// 如何处理 .js 文件,用法和 Loader 的配置一样
loaders: [{
loader: 'babel-loader?cacheDirectory=true',
}],
// 共享进程池
threadPool: happyThreadPool,
// 允许 HappyPack 输出日志,默认为 true,可不写
verbose: true
}),
],
//...
}
}
Сначала мы создаем общий пул процессов и с помощью ОС Node.js позволяем пулу процессов содержать дочерние процессы os.cpus().length, затем добавляем соответствующий экземпляр HappyPack, передаем ранее определенный идентификатор и сообщаем happypack /loader для его обработки В файле .js атрибут loaders такой же, как и в приведенной выше конфигурации загрузчика Атрибут threadPool передается в предопределенный параметр happyThreadPool, который указывает экземплярам HappyPack использовать дочерние процессы в одном пул процессов для обработки задач.
Затем запустите пакет, скомпилируйте и соберите.После завершения сборки мы можем увидеть журнал сборки HappyPack.
Мы видим, что HappyPack запускает 8 дочерних процессов для параллельной обработки задач. Восторженные аплодисменты!
Наконец, давайте взглянем на сравнительную диаграмму скорости загрузки, которая сэкономила 1488 мс и увеличилась почти на 20%.
2.6 Анализ результатов строительства
Инструментов визуального анализа ресурсов много, мы выбрали webpack-bundle-analyze, который отображается в графическом виде, он проще и понятнее других инструментов, результаты анализа на выходе позволяют быстро проанализировать проблему. Давайте посмотрим, как получить к нему доступ в проекте.
Установить зависимости
npm install webpack-bundle-analyzer -D
Настройте webpack.config.js
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
...
module.exports = (env, argv) => {
const webpackConfig = {
...
plugins: [
...
new BundleAnalyzerPlugin()
],
...
}
}
Метод настройки также очень прост, обычно параметров по умолчанию достаточно для использования без изменений.
Далее добавляем скрипты в package.json
"analyz": "NODE_ENV=production npm_config_report=true npm run build"
Затем после выполнения npm run analysis браузер автоматически откроется.http://127.0.0.1:8888/для отображения интерфейса представления анализа.
Если вы не хотите каждый раз всплывать автоматически, вы можете изменить значение параметра openAnalyzer на false, а затем открывать его вручную по мере необходимости.
Благодаря представлению вы можете увидеть размер каждого модуля проекта, увидеть реальное содержимое после того, как файлы будут упакованы и сжаты, а затем проанализировать, что некоторые файлы занимают много места.С идеей анализа существует оптимизация Цель.
На диаграмме окончательного анализа обнаружено, что общедоступный файл toast.js составляет относительно большую долю, и файл toast.js можно оптимизировать. Кроме того, сторонние библиотеки Swiper.js и lazyload.js, на которые приходится относительно большая часть, также могут рассмотреть возможность извлечения DLL для дальнейшего увеличения пространства.
2.7 Перераспределение компонентов
В проекте PLUS у нас естьcomponent
Папка, вот некоторые общие компоненты или некоторые подкомпоненты страницы. Из-за исторических проблем папка переработана и страница увеличена, много избыточных компонентов, а директория всей папки раздута. Так что необходимо заново разбить компоненты, давайте посмотрим, как их разбить.
Сначала позвольте мне увидеть, что в нем?
Извините, что не смог сделать скриншот!
Согласно приведенному выше рисунку, мы будем примерноcomponent
Содержимое папок сгруппировано в следующие категории.
1. Исторический унаследованный класс: этот тип файла можно проследить до исходного созданного старшего файла.В то время планирование каталога все еще было в форме одной страницы.Большинство этих файлов являются подкомпонентными файлами для дома страница, а также некоторые подкомпоненты страницы, основанные на статусе пользователя.
2. Класс компонента страницы: при итерации проекта в проект добавляются некоторые новые страницы, а также разбросаны сложные подкомпоненты на этих страницах.component
папка.
3. Функциональные компоненты. Функциональные компоненты, такие как всплывающие окна, высокодоходные компоненты, компоненты калькулятора и другие общедоступные компоненты, также помещаются в эту папку для управления.
Как это разделить?
Прежде всего, для файлов подкачки исторических унаследованных классов они сознательно классифицируются по соответствующим папкам подкачки во время ревизии, что удобно для обслуживания. Для разрозненных подкомпонентов страницы они также классифицируются по соответствующим папкам страницы.
И для некоторых общедоступных компонентов страницы мы создаем общедоступную папку бизнес-компонента.plus-components
Поместите его в единое управление.
Компоненты, подобные упомянутым выше функциональным классам,dialog
,countdown
Когда мы обращаемся к нему в виде npm, он больше не будет занимать локальную папку и будет уменьшенcomponent
содержание. После оптимизации следующим образом:
Из приведенного выше рисунка видно, что оптимизированныйcomponent
Создал в корне папкиplus-components
В папке хранятся общедоступные бизнес-компоненты, а на том же уровне хранятся папки страниц каждой страницы и создается папка в подкаталоге.other-components
файл для управления другими функциональными компонентами. Таким образомcomponent
Структура каталогов выглядит намного понятнее и проще в управлении.
2.8 Оптимизация Vuex
Vuex — это режим управления состоянием в проекте Vue, то есть механизм централизованного управления общим состоянием всех компонентов проекта. Vuex обычно используется в средних и крупных одностраничных приложениях, но не рекомендуется для простых одностраничных проектов, поскольку Vuex может быть громоздким и избыточным для простых приложений.
Для проекта PLUS наличие Vuex очень необходимо, потому что у проекта PLUS слишком много состояний, которыми можно поделиться.
Давайте сначала посмотрим на исходный код Vuex проекта:
import Vue from 'vue';
import Vuex from 'vuex';
Vue.use(Vuex);
export default new Vuex.Store({
state: {...},
getters: {...},
mutations: {...},
actions: {...}
});
Исходный код Vuex записывает все общедоступные состояния в один и тот же индексный файл, а состояние, геттеры, мутации и действия управляются единообразно. Нет ничего плохого в том, чтобы написать это таким образом, и это то, что делают большинство малых и средних проектов. Но для большого проекта общее состояние для всех страниц может привести к тому, что весь файл Vuex будет выглядеть раздутым и неуправляемым. И некоторые общедоступные методы будут генерировать много избыточного кода после повторения и изменения требований, а некоторые общедоступные методы вызовут проблемы с использованием сопряжения для ссылок на разные страницы.
Поэтому для оптимизации Vuex мы пытаемся ввести модули для модульного управления Vuex.
Создаем один в корневом каталоге магазинаmodules
Папка, создать в папкеrefund
документ.
modules
Вы можете поместить в папку любые модули, которыми хотите управлять по-разному, здесь толькоrefund
Например. существуетmodules
После создания модуля js или ts в папке импортируйте его в корневой файл индекса.
import Vue from 'vue';
import Vuex, { StoreOptions } from 'vuex';
import state from './states';
import mutations from './mutations';
import actions from './actions';
import getters from './getters';
import refundModule from './modules/refund';
Vue.use(Vuex);
export default new Vuex.Store({
state,
mutations,
actions,
getters,
modules:{
refundModule
}
});
Приведенный выше код показывает введение в index.ts в корневом каталоге магазина.refund
, и назовите егоrefundModule
звонить. И дляrefund
файл, мы можем записать в него требуемое состояние, действие и мутацию, как мы использовали для написания Vuex.
const state = {
orderId: null,
};
const actions = {
getOrderId: ({ commit }, data) => {
commit("setOrderid", data);
}
};
const mutations = {
setOrderId: (state, data) => {
state.orderId = data;
},
};
export default {
namespaced: true, // module 命名空间,
state,
actions,
mutations
};
Как показано в коде, в этом файле записываются состояние, действия и изменения, связанные со страницей возврата. Кроме того, вы можете видеть, что в коде есть еще одна строкаnamespaced:true
. Код-обертка означает открытие пространства имен.После регистрации модуля все его геттеры, действия и мутации будут автоматически именоваться в соответствии с путем, зарегистрированным модулем. Проще говоря, он используется для различения состояния модуля, геттера, действия и мутаций, которые вы вызываете.
После выполнения вышеуказанной работы, как это назвать?
Если вы написали Vuex на JS, вы можете процитировать это так:
import { mapState, mapActions } from "vuex";
export default {
computed:{
...mapStated('模块名(比如:menuNav/getNavMenus)',{
a:state=>state.a,
b:state=>state.b
})
},
methods:{
...mapActions('模块名(比如:menuNav/getNavMenus)',[
'foo',
'bar'
])
}
На официальном сайте Vuex есть много подобных примеров, Заинтересованные студенты могут обратиться к официальному сайту за питьевым методом модулей.
Если вы используете TS для написания Vuex, вы можете вызывать модули на странице следующим образом:
import {Component, Prop, Vue, Watch} from 'vue-property-decorator';
import {State, Action, Getter,namespace} from 'vuex-class';
const refundMdl = namespace('refundModule')
@Component
export default class Refund extends Vue {
@refundMdl.State(state => state.orderId) orderId;
@refundMdl.Action('getOrderId') getOrderId;
}
Обязательно вводите пространство имен при вызове и вызывайте общедоступное состояние и методы модулей через пространство имен.
После описанной выше модификации модуляризации Vuex мы можем целенаправленно управлять состояниями модулей, которые необходимо различать, и уменьшать вес файлов Vuex.
3. Оптимизируйте пользовательский опыт
В начале 2020 года домашние страницы нескольких каналов участников PLUS по очереди менялись и обновлялись.Команда разработчиков также усердно работала над тем, чтобы предоставить пользователям более дружественный интерфейс и функции.Как фронтенд-команда, помимо выполнения свои потребности, у них также есть своя Xiaojiujiu, и мы являемся одним из них, а также хотим оптимизировать и улучшить пользовательский опыт за счет:
3.1 Сокращение времени ожидания пользователя
После радикального пересмотра страниц нескольких каналов участников PLUS этажи и последовательности этажей, отображаемые каждым человеком, могут отличаться, поэтому интерфейсу необходимо полагаться на данные внутреннего интерфейса для отображения этажей, что приводит к необходимости отображения страницы. Данные могут быть отображены только после ожидания, пока интерфейс конфигурации вернет данные. Когда интерфейс возвращается медленно, для отображения страницы потребуется много времени, что довольно плохо для пользовательский опыт, но мы не можем контролировать скорость возвращения бэкенда в интерфейс.Начиная с фронтенда, мы делаем следующую Работу:
1. Добавьте скелетный экран, отобразите общий стиль страницы перед рендерингом страницы и уменьшите время белого экрана;
2. HTML-страница напрямую размещает данные пользовательской информации, и интерфейсу не нужно запрашивать интерфейс, и он может напрямую отображать некоторые области личной карты;
3. Подтвердите с продуктом этажи, которые будут отображаться на первом экране, такие как этаж с личной картой и этаж с исключительными правами участника.Эти этажи используются в качестве интерфейсных зон занятости, и предварительные стили этих этажей отображаются интерфейс возвращается, чтобы избежать ожидания.После того, как интерфейс конфигурации возвращается, последовательность этажа прерывается;
4. Для этих этажей, в соответствии с форматом данных, возвращаемым серверной частью, передняя часть устанавливает предварительные данные для отображения предварительной страницы этажа, и после того, как интерфейс возвращает данные, заменяет ключевые поля на странице;
Как показано на рисунке выше, когда интерфейс данных не получен, страница уже может отображать базовую структуру, что сокращает время белого экрана страницы и время ожидания пользователя.
3.2 Отображение нескольких гарантированных этажей
Помимо сокращения времени ожидания пользователей, как описано выше, мы также сделали отображение нескольких страниц защиты. Потому что этажи всей страницы настраиваются и отображаются по данным, возвращаемым интерфейсом. Вообще говоря, когда нет интерфейса для возврата данных, страница больше не будет отображаться, и пользователю будет предоставлен скелетный экран. Но для того, чтобы получить лучший опыт, можем ли мы взять несколько страховок, чтобы максимизировать решение проблемы зависания интерфейса? Прежде всего, мы просим серверную часть напрямую поместить информацию о конфигурации этажа на Html-страницу, а внешний интерфейс отображает пол первого экрана в соответствии с полученной информацией, чтобы мы могли напрямую решить, какие этажи отображать на странице на основе на информацию об интерфейсе.Если этот этаж не работает, то чтобы вызвать соответствующий интерфейс конфигурации этажа, сделайте шаг назад, этот интерфейс также вешается, чтобы избежать настроения пользователя поднять стол, мы будем напрямую вызывать интерфейс несколько этажей, которые обязательно запросит первый экран, так что благодаря трехуровневой защите интерфейса снижается риск появления белого экрана из-за проблемы с интерфейсом.
Многократная гарантия отображения пола страницы, сначала получите данные первого экрана прямо, в противном случае получите интерфейс данных этажа, а затем напрямую запросите внутренние данные пола первого экрана, чтобы избежать белого экрана страницы из-за неправильные данные на первом этаже и уменьшить жалобы пользователей;
3.3 Улучшение и оптимизация PWA
Поскольку технология кэширования PWA была добавлена на страницу статуса пользователя управления рисками в прошлом году, я хотел продвинуть железо вперед по полной, но обнаружил, что все запросы под одним и тем же доменным именем будут перехвачены serverWork, поэтому я резко остановился и обсудил долгосрочный план.
Итак, как мы можем контролировать, чтобы PWA вступал в силу в указанном пользовательском состоянии?
Вариант первый
Я предпринял много попыток.В проекте PLUS разные состояния пользователя находятся в разных Html.Можем ли мы отправлять сообщения в serviceWorker в Html?Это работает только в некоторых сценариях в HTML
navigator.serviceWorker.controller.postMessage()
в службеРаботник
self.addEventListener('message', function(e) {
})
Но это решение не работает, потому что после регистрации serviceWorker следующий запуск PWA происходит до того, как Html будет успешно прочитан, поэтому с этим решением есть некоторые проблемы.
Вариант 2
PWA может установить указанную область
navigator.serviceWorker.register('service-worker.js', {scope: './xxx'})
Но доменные имена для наших разных штатов все plus.m.jd.com/index, так что это решение нам не подходит.
третье решение
Перехватывайте выборку сервис-воркера и контролируйте чтение страницы, оценивая определенные флаги. Например, статус пользователя, возвращаемый интерфейсом getUserInfo, используется для определения необходимости включения перехвата выборки, а черный список используется для запрета запуска PWA в определенных состояниях Код выглядит следующим образом:
self.addEventListener('fetch', function (event) {
event.respondWith(
caches.match(event.request).then(
(response) =>
response ||
fetch(event.request.clone()).then(function (httpRes) {
if (/getUserInfo/gi.test(event.request.url)) {
httpRes.json().then((res) => {
//do something
});
}
return httpRes;
})
)
);
});
После вышеописанной обработки получается, что до тех пор, пока вы посещали домашнюю страницу управления рисками, а затем обращались ко всем статусам под одним и тем же доменным именем, он будет перехвачен serviceWorker, как показано на следующем рисунке:
После модификации перехват PWA можно отключить на других страницах статуса пользователя, как показано на следующем рисунке:
3.4 Обработка изображений
В настоящее время в изображениях на веб-странице используется большое количество изображений, что может оказывать более непосредственное визуальное воздействие на пользователей.При входе членов PLUS отображается большое количество изображений продуктов.Как усердно работать над обработкой изображений, мы также использовали некоторые мысли. Все изображения на странице участника PLUS используют систему изображений Jingdong. Что заставляет нас сиять, так это то, что мы можем настроить параметры URL для обработки изображений, например:
http://img30.360buyimg.com/test/s720x540_jfs/t2362/199/2707005502/100242/616257ce/56e66b21N7b8c2be8.jpg
серединаs720x540_jfs
, между названием компании и адресом файла добавлен параметр, указывающий, что изображение масштабируется до ширины 720 и высоты 540;
Добавьте суффикс webp непосредственно к URL-адресу, тогда он будет преобразован в изображение в формате webp, поэтому для доступа к изображению на стороне сервера вы можете сделать следующее:
function imgCut(item, str) {
if (/(((img){1}\d{2})|m{1}).360buyimg.com/.test(item)) {
if (str) {
item = item.replace('jfs', 's' + str + '_jfs');
}
if (check_support_webp()) {
return item + '.webp'; //需要判断支持webp的情况下写上webp后缀
} else {
return item;
}
} else {
return item;
}
}
В соответствии с описанным выше методом запрос изображения с сервера может не только обрезать изображение, чтобы обеспечить тот же размер изображения на странице, но и легко преобразовать изображение в веб-формат, что действительно является отличным инструментом для исследований и разработок! Обратите внимание, что эта функция обрабатывает изображения, запрошенные с сервера, а не изображения, предоставленные локально внешним интерфейсом.
Суммировать
Оглядываясь назад, можно сказать, что членский проект PLUS с самого начала был невежественным, и в мгновение ока были собраны десятки страниц со сложной логикой, были итерированы несколько версий и создано несколько ответвлений. Недавно я оторвался от проекта только для того, чтобы обнаружить, что ему не хватает понимания направления проекта из общей картины и обеспечения того, чтобы проект мог выполнять повторяющиеся требования. Проект члена PLUS еще многое предстоит улучшить. период, я также получил сильную поддержку от некоторых команд.И хорошие предложения, мы будем продолжать полировать его, установить надежный механизм, улучшить качество кода, улучшить пользовательский опыт и сопровождать участников PLUS.
Наконец, я заканчиваю своей любимой фразой: «Хотя я иду один, кажется, что я веду миллион солдат. Я в углу колодца, мое сердце — звездный свет, мои глаза — поэзия, и я на расстоянии! ", полный надежд на жизнь и будущее, Делюсь с вами~