Рабочая практика, сделанная в бизнесе [можно назвать воином] - семидневный пунш

JavaScript
Рабочая практика, сделанная в бизнесе [можно назвать воином] - семидневный пунш

У всех возникают некоторые сомнения, когда они видят в названии слово «Воин». Я не буду здесь слишком много объяснять, просто скажу одно: поскольку это старый проект (вы знаете, он старый и очень старый), можно действительно сказать, что он влияет на все тело.

Но очень скоро я молниеносно принял решение и просто выбрал файл.CTRL+A,ПотомDeleteАх, эта волна операций, можно сказать, резвая и предельно уверенная. Хотя позже я заплатил цену в 100 миллионов за свою уверенность в себе, но, к счастью, результат меня радует, а сегодня еще и за поведение этого воина.WorkerЧастично сделать итоговую запись.

Сегодня Worker описывается с трех сторон:

  • что (что такое рабочий?)
  • почему (зачем использовать?)
  • Как (как использовать?)

Что - что такое рабочий?

мы все знаемJavaScriptЭто однопоточный язык, что означает, что все задачи могут выполняться только в одном потоке, и одновременно может выполняться только одна задача, что вызывает проблему.Когда в потоке слишком много задач, он приведет к блокировке задачи. С развитием аппаратного обеспечения (многоядерный ЦП) и интерфейсных систем (сложные требования и множество функций) это вызовет множество неудобств.WorkerИменно для решения этих проблем.

Обзор

WorkerМожно создать отдельный поток от основного потока. пройти черезWorkerСозданная нить работает на заднем плане, основной нить может назначать некоторые задачи к этой независимой потоке для выполнения, а два не мешают друг другу.WorkerПосле выполнения задачи в потоке ее можно пройти черезmessageдля отправки результата выполнения в основной поток.Поскольку Worker — это независимый поток, его глобальный контекст такой же, как тот, который мы обычно используем при его выполнении.windowРазличные объекты можно разделить на два типа в зависимости от глобального контекста Worker:

  1. Worker: Выделенный рабочий процесс, который используется только страницей, на которой в данный момент выполняется скрипт.При закрытии этой страницы текущий рабочий процесс также будет закрыт, и соответствующий контекстDedicatedWorkerGlobalScope
  2. sharedWorker: общий рабочий процесс, который может использоваться несколькими страницами. Текущий рабочий процесс будет закрыт, когда будут закрыты все связанные страницы. Соответствующий контекстSharedWorkerGlobalScope

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

будь осторожен

Сначала давайте посмотрим, как создать простой рабочий объект.

const worker = new Worker( url )

1. ограничение гомологии

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

2. Ограничения доступа к API

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

  • недоступен:
    • window
    • document
    • alert()
    • confirm()
  • Доступный:
    • navigator
    • location
    • XMLHttpRequest
    • fetch

Более подробные разрешения доступа к API можно посмотреть на официальном сайте:Нажмите здесь, чтобы перейти напрямую

3. лимит файлов

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

Зачем - зачем использовать?

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

Для этого проекта, который я принял, моя отправная точка для использования Worker в основном из-за следующих двух моментов:

  • В проекте есть большой визуальный экран, который охватывает множество данных, включая организационные данные, картографические данные и различные статистические данные. Объем этих данных огромен, особенно данные карты и организационной структуры, и есть некоторые операции обхода данных карты и организационных данных. Самое главное, что все запросы к этим интерфейсам запрашиваются после входа в систему, что приводит к очень серьезной проблеме: большой экран должен полностью отображаться примерно за 7-10 секунд, хотя в середине есть эффект перехода загрузки. Но все же неудачный опыт, на мой взгляд.

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

Как - как использовать?

Код товара, потому что компания не выходит для всех, чтобы увидеть. Итак, мы делаем здесь с простой пример, который мы чувствуем

Этапы реализации:

1. Создайтеindex.htmlдокумент

  <script type="module">
    // 引入worker脚本
    import workerScript from './worker.js'
    // 创建worker线程,参数为脚本的url
    // 这里需要注意一下,这里的url是Blob URL,具体原因我们在上文已经说过
    const worker = new Worker(workerScript);
    // 主线程和子线程进行通信
    worker.postMessage('http://juejin.cn')
    // 获取子线程发送来的消息
    worker.onmessage = (msg) => {
      const { data } = msg
      document.body.innerHTML = data
    }
    // 监听worker的错误事件
    worker.onmessageerror = (error) => console.log(error)
  </script>

2. Создайтеworker.jsдокумент

  // 需要在worker中执行的脚本
  const workerScript = () => {
    onmessage = (msg) => {
      if (msg.data) {
      	// 接收到主线程的消息之后,与主线程进行通信
        postMessage(`我接受到你的参数了,我再吐给你${msg.data}`);
      }
    };
  };

  // 将上述执行脚本转换为字符串
  let code = workerScript.toString();
  // 对字符串进行分割,取到onmessage部分的函数声明
  code = code.substring(code.indexOf("{") + 1, code.lastIndexOf("}"));
  // 将字符串转换为Blob URL
  const blob = new Blob([code], { type: "application/javascript" });
  const blobUrl = URL.createObjectURL(blob);
  // 导出生成的Blob URL
  export default blobUrl;

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

Далее мы преобразуем исполняемый код вWorkerузнаваемыйBlob URL

Эффект исполнения

Делайте сетевые запросы с работниками

немного правееworker.jsС помощью нескольких настроек вы можете

  // 需要在worker中执行的脚本
  const workerScript = () => {
    onmessage = (msg) => {
       // 发送网络请求
      const response = await fetch(msg.data, {
        method: "post",
        body: `yes = 1`,
      }).then((res) => res.json);

      if (response) {
      	// TODO 可以在这里对数据进行处理,然后发送给主线程
        postMessage(`我数据处理完成了,给你用吧`);
      }
  };

  // 将上述执行脚本转换为字符串
  let code = workerScript.toString();
  // 对字符串进行分割,取到onmessage部分的函数声明
  code = code.substring(code.indexOf("{") + 1, code.lastIndexOf("}"));
  // 将字符串转换为Blob URL
  const blob = new Blob([code], { type: "application/javascript" });
  const blobUrl = URL.createObjectURL(blob);
  // 导出生成的Blob URL
  export default blobUrl;

Мы видим, что этот запрос немного отличается от запроса, который мы обычно видим на этой панели, перед ним стоит маленькая шестеренка, которая доказывает, что запрос сделан в рабочем потоке, и на этом мы закончили.

Практика в проекте

Благодаря вышеуказанным операциям в этом проекте скорость загрузки большого визуального экрана после входа в систему стабильна на уровне3~5s, скорость увеличилась40%о. Конечно это всего лишь небольшой момент в оптимизации, конечно я тоже использую React'ы в проектеmemo,useMemo,useCallbackи другие методы были оптимизированы соответствующим образом.

надworker.jsЭто пакет, который я сделал в проекте, поэтому вы также можете использовать его непосредственно в своем проекте. Шаги для использования:

  1. Будуworker.jsСкопируйте файл в соответствующую папку текущего проекта.
  2. Ниже комментария TODO вы можете добавить собственную обработку копирования больших данных в проекте, таких как обход, рекурсия и т. д., и передать ее в основной поток через postMessage после завершения обработки.
  3. пройти в основной файлimport xxx from './worker'Представьте сценарий выполнения
    • пройти черезnew Worker(xxx)Создать рабочий поток
    • пройти черезonmessageМетод прослушивает события связи между потоками (обычно для отображения обработанных данных, переданных рабочим потоком).

Суммировать

Мы видим, что на самом деле использование Worker очень простое, вам нужно всего лишь добавить еще несколько строк кода в соответствующий проект, чтобы выполнить некоторые операции, влияющие на производительность страницы, почему бы не сделать это?

и дляОптимизация производительности на уровне кодаС этой точки зрения, я думаю, что как программисты, мы должны думать, когда пишем код каждый день. Мы не можем просто делать это для удовлетворения потребностей. Иногда мы также думаем о том, повлияла ли работа этого кода на то, когда он доходит до взаимодействия со страницей, есть ли способ оптимизировать его на уровне кода? (Кажется, это вопрос, о котором говорят старики, но он действительно имеет смысл! Как говорится, «Если ты не слушаешь стариков, ты будешь страдать перед собой»). Если есть возможность оптимизации, то изучите сопутствующие технологии и сформулируйте планы, которые очень полезны для личностного роста (все QAQ научились у больших парней)

Повседневное мышление важно, но если вы сделаете из размышлений определенный результат, эффект будет очень хорошим~,double up! (делаю сам, поэтому имею личный опыт)

Последнее предложение: xdm, давай!