Оптимизация веб-производительности: сократите загрузку контента и улучшите скорость ответа страницы.
Оптимизация веб-производительности: сократите загрузку контента и улучшите скорость ответа страницы.

введение

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

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

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

фон

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

Что такое «время загрузки ресурса»

Проще говоря, традиционные веб-страницы имеют несколько различных этапов инициирования запроса:

Если вам интересно узнать каждогоиндивидуальный Полеиз Вы можете уточнить значениекссылкаTiming breakdown phases explained

Здесь мы сосредоточимся на двух частях:

  • Waiting for server response: аббревиатура TTFB представляет собой время, в течение которого браузер ожидает ответа при получении первого ответа от сервера.
  • Загрузка контента: Как следует из названия, это время загрузки контента при передаче по сети.

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

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

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

Нужно ли оптимизировать «загрузку ресурсов»?

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

«Мой интерфейс реагирует очень быстро, так не нужно ли мне его оптимизировать?» Я думаю, большинство студентов зададутся вопросом, важен ли опыт оптимизации в 100 мс?

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

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

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

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

Web Streaming

концепция

привычный NodeJs одноклассники для Streaming изконцепция должна быть вам знакома,существовать Web Среда выполнения также предоставляет набор Stream API позволять JavaScript Возможность доступа к потокам данных из сети.

При передаче по сети HTTP2 Передача данных через уровень двоичного кадрирования поддерживается по умолчанию при передаче данных по сети. Streaming способ прочитать ответ, в HTTP 1.1 Мы можем установить Transfer-Encoding: chunked Заголовок ответа указывает, что «лучшее» передается в формате фрагментов данных.

Проще говоря, Streams API позволяет нам программно получать доступ к потокам данных, получаемым по сети, посредством JavaScript, при этом настраивая обработку возвращаемых потоков данных в соответствии с собственными потребностями.

  1. обработка данных в реальном времени:когдаданныеккусокиз Когда придет форма,Не нужно ждать полногоиндивидуальный Полезная нагрузка может быть обработана。Это можетк Значительно улучшеноданныеизгрузоподъемностьа Также медленное сетевое соединение из-за воспринимаемой производительности.
  2. Детальный контроль:Web Streaming Позволяет нам контролировать, как данные считываются и обрабатываются в соответствии с конкретными потребностями и сценариями.

Здесь мы в основном фокусируемся на ReadableStream а также WritableStream

о Streaming Для получения подробной информации и использования вы можете обратиться к MDN - Web Streaming или Vercel - An Introduction to Streaming on the Web

ReadableStream/WritableStream Пример

  • ReadableStream предоставляет возможности асинхронного чтения.
  • WritableStream Предоставлено для Воли Streaming данные о назначении записи из возможности.

Давайте посмотриминдивидуальныйо ReadableStream а также WritableStream Простой пример:

Язык кода:javascript
копировать
const decoder = new TextDecoder();
const encoder = new TextEncoder();

// Создайте читаемый поток
const readableStream = new ReadableStream({
  // Когда будет создан читаемый поток, он будет выполнен немедленно, и читаемый поток будет поставлен в очередь через метод доступа для Whenfront, когда text
  start(controller) {
    const text = 'hello, Welcome to flow my Github: 19Qingfeng.';
    controller.enqueue(encoder.encode(text));
    controller.close();
  }
});

// Создайте отдельный записываемый поток
const writableStream = new WritableStream({
  // Каждый раз есть что-то новое chunk Доступный для записи поток создается, когда он готов к записи. write метод
  write(chunk) {
    console.log(decoder.decode(chunk));
  }
});

readableStream.pipeTo(writableStream); // hello, Welcome to flow my Github: 19Qingfeng.

В приведенном выше коде мы передаем TextEncoder Воля hello, Welcome to flow my Github: 19Qingfeng. преобразован в stream отисуществоватьсоздавать Читабельный поток Воляон врезается в поток。

В то же время позже мы создали writableStream Записываемый объект потока, содержимое потока, доступное для чтения через pipeTo Перенос метода в записываемый поток.

writableStream Каждый раз будут новые chunk Срабатывает, когда готов к записи write метод, в write В методе,который мы использовали TextEncoder идти Воля stream Раскодируйте, и консоль естественным образом выведет hello, Welcome to flow my Github: 19Qingfeng

о WritableStream/ReadableStream изконцепцияа Также Углубленное использование: друзья, которым интересно узнать больше, могут проверить это самостоятельно. MDN Документация.

Web Fetch

концепция

API Fetch предоставляет интерфейс для получения ресурсов, а Web Fetch больше похож на замену XMLHttpRequest.

Fetch Ядро лежит в HTTP Абстракция интерфейса, включая Request,Response,Headers,Body,а также используется для инициализации асинхронных запросов из global fetch

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

Основное использование

Обычно мы используем Fetch Api с файлом response.json для получения данных, полученных от интерфейса удаленной службы:

Язык кода:javascript
копировать
async function getUserJSON() {
  let url = 'https://api.github.com/users/19Qingfeng';
  try {
    let response = await fetch(url);
    return await response.json();
  } catch (error) {
    console.log('Request Failed', error);
  }
}

fetch Возвращаемое значение метода — это Promise<Response> объект, мы можем использовать fetch вернулся response в объекте json метод из Response Залезай json Форматированный ответ данных.

Streaming Fetch

На самом деле, принеси Api вернулся Response Есть еще один на body свойство.

Мы можем пройти назад response из body Недвижимость Получить индивидуальный ответ из ReadableStream Пример.

Это означает, что мы можем сразу прочитать содержимое ответа с помощью метода json, не дожидаясь загрузки всех ответов во время передачи по сети.

Вместо этого вы можете пройти response.body к методу ReadableStream для пакетного чтения данных из и для повышения скорости ответа данных интерфейса.

Чтение данных res.body напрямую

Далее давайте посмотрим, как использовать Fetch Response из body свойство.

Сначала мы используем экспресс для быстрого создания NodeServer для размещения серверного приложения:

Язык кода:javascript
копировать
// express код степени обслуживания
const express = require('express');
const data = require('./data.json');
const path = require('path');

const app = express();

app.use(express.static(path.resolve(__dirname, '../public')));

app.post('/api/data', (req, res) => {
  res.json(data);
});

app.listen(3000, () => {
  console.log('start server on 3000;');
});

здесь из ./data.json Вы можете разместить любой абзац json содержание.

В то же время нам также необходимо public Поместите один под html Файл взят со страницы отображения Также Выполнить клиентскую часть логики:

Язык кода:javascript
копировать
<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>Document</title>
</head>

<body>
  <div id="root"></div>
  <script src="./index.js"></script>
</body>

</html>
Язык кода:javascript
копировать
// index.js
setTimeout(() => {
  fetchUserDataByStreaming();
}, 100);

async function fetchUserDataByStreaming() {
  const response = await fetch('/api/data', {
    method: 'post'
  });

  const body = response.body;
  // Получите читаемую программу чтения потоковых объектов.
  const reader = body.getReader();

  // создавать TextDecoder декодирование
  const textReader = new TextDecoder();

  function getValueFromReader() {
    reader.read().then((res) => {
      if (res.done) {
        console.log('reader done');
        return;
      }

      if (res.value) {
        const text = textReader.decode(res.value);
        const element = document.getElementById('root');
        element.innerHTML = element.innerHTML + text;

        console.log(textReader.decode(res.value));
        // Если он не закончился, продолжите вызов getValueFromReader Рекурсивное чтение fetch содержание
        getValueFromReader();
      }
    });
  }

  getValueFromReader();
}

В приведенной выше логике мы передаем Express Создал NodeServer, пока Создан /api/data из post интерфейс.

Доступ после запуска приложения localhost:3000 будет загружен позже html файлы, выполняемые одновременно ./index.js из клиентской логики.

Клиент будет внутри 100ms позвони после fetchUserDataByStreaming метод.

fetchUserDataByStreaming Есть несколько основных шагов:

  • Первое использование Fetch Api вызов NodeServer из /api/data интерфейс.
  • когда /api/data При ответе (HTTP Status Code для 200 ), мы будем использовать response.body Получите читаемый поток этого ответа.
  • После этого проходим body.getReader а также new TextDecoder Получен ответ, читаемый потоком объектов из средства чтения и декодирования.
  • наконец,существовать fetchUserDataByStreaming В нашем рекурсивном вызове getValueFromReader Заходите, Воля, реагируйте на возвращенные обновления на странице.

getReader() метод создаст reader,и Воля Stream блокировка. только текущий reader Воля Стрим вышел после других reader можно использовать. в то же время,getReader() Возвращаемое значение методиз используется точно так же, как и функция-генератор.

  • ReadableStream Если есть какие-либо chuck Доступно, вызов reader.read() вернулся promise буду использовать { value: chunk, done: false } done выражать stream Еще не конец, и value На этот раз там написано изсодержание.
  • ReadableStream Если оно закончилось (закрылось), вызовите reader.read() вернулся promise буду использовать { value: undefined, done: true } ,природа done Выразитьreadable закрыто.

Здесь мы напрямую используем res.body Волявернулсяданные безмозглый пропуск innerHTML добавлено на страницу.

На фото выше для Воля network Отрегулируйте slow 3g дело из performance frames。

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

Fetch Api из Response.body вернулся readableStream для Мы предоставляем доступныекшаг за шагомполучатьданныеи Не нужно ждать всехизсодержание Загрузка завершена。

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

существования Если вы будете осторожны, то можете обнаружить, что на странице разбросано множество искаженных слов:

Фактически, это связано с тем, что по умолчанию TextDecoder анализирует Response.body в соответствии с кодировкой utf-8 (один байт представляет 8 бит).

существовать ReadableStream разделит данные в соответствии с минимальной единицей байтов и вызовет body.getReader() вернулся res.value для Uint8Array Тип: Uint8Array это автор 8 битовое беззнаковое целое число(Это одининдивидуальныйбайт)композицияизмножество。

Страница для написана на чистом английском языке (utf-8 Следующий код — индивидуальный английский дляодининдивидуальныйбайт), который, естественно, можно передать напрямую. TextDecoder При прямом чтении не будет искаженных символов.

Но на китайской сцене обычно существуют UTF-8 Китайцы будут оккупированы следующим 3 индивидуальныйбайт,грубыйизиспользовать TextDecoder идтидекодированиевернулся Uint8Array Может привести к частичному обрезанию индивидуального китайского иероглифа «Воляодинизмногобайт», uft-8. Кодировка не может распознать часть китайских иероглифов байт и природа, а также приводит к искажению символов.

Правила синтаксического анализа различных текстов в кодировке utf-8: проблема, нам нужно понять кодировку utf-8:

Проще говоря, utf-8 — это метод кодирования байтов переменной длины.

  • Для определенного индивидуального персонажа из utf-8 Кодировка, если имеется только один индивидуальныйбайт, то его старшая двоичная цифра 0。
  • Если это несколько байтов, то его первый индивидуальный байт начинается со старшего бита, а последующие из значений двоичных битов для 1 Число индивидуальных байтов определяет количество цифр в его кодировке, а остальные байты равны. 10 В начале, когдаран utf-8 Доступно до 6 индивидуальныйбайт。

байт

Пример

1байт

0xxxxxxx

2байт

110xxxxx 10xxxxxx

3байт

1110xxxx 10xxxxxx 10xxxxxx

4байт

11110xxx 10xxxxxx 10xxxxxx 10xxxxxx

5байт

111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

6байт

1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx

Это означает, что каждый раз существование читается stream Нам нужно опираться на Uint8Array из Хвост сам движется вперед, чтобы определить, можно ли из хвостового байта сформировать полноценного индивидуального utf-8 Кодируем, если есть возможность то вызываем TextDecoder руководитьдекодирование,если это невозможнокмы должнысуществовать На этот разиз stream Неполныйизбайт Сноваруководитьдекодирование Предотвратить искажение символов в браузере。

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

Язык кода:javascript
копировать
setTimeout(() => {
  fetchUserDataByStreaming();
}, 100);

async function fetchUserDataByStreaming() {
  const response = await fetch('/api/data', {
    method: 'post'
  });

  const body = response.body;
  // Получить читаемый объект потока
  const reader = body.getReader();

  // создавать TextDecoder декодирование
  const textReader = new TextDecoder();
  // создаватьодининдивидуальный На этот разответизобщая ситуация buffer Используется для сохранения уже полученных изданных
  // Типдля Uint8Array[]
  let buffer = [];

  function getValueFromReader() {
    reader.read().then((res) => {
      if (res.done) {
        console.log('reader done');
        return;
      }

      if (res.value) {
        const chunk = res.value;
        // Воля Эти возвращаемые данные добавляются к возвращаемым данным
        buffer.push(chunk);
        // Отформатированный Uint8Array[] Получите полные изданные
        const completeBuffer = mergeArrays(...buffer);
        // Определите, нужно ли отбрасывать искаженные символы,получать На этот разможет быть полнымдекодированиеизданные
        const finallyBuffer = splitValidBuffer(completeBuffer);
        // декодирование
        const textBufferString = textReader.decode(finallyBuffer);

        const element = document.getElementById('root');
        // Заменить всю сумму
        element.innerHTML = textBufferString;
        // Если он не закончился, продолжите вызов getValueFromReader Рекурсивное чтение fetch содержание
        getValueFromReader();
      }
    });
  }

  getValueFromReader();
}

function splitValidBuffer(buffer) {
  const reg = /^1*/;
  let count = 0;
  let shouldCount = 0;

  for (let i = buffer.length - 1; i >= 0; i--) {
    const byte = buffer[i];
    // Волябайтпреобразован в двоичном формате
    const value = byte.toString(2).padStart(8, '0');
    // Определите, является ли этот байт частью для
    if (!`${value}`.startsWith('10')) {
      // Не для части
      shouldCount = `${value}`.match(reg)[0].length;
      break;
    } else {
      // Начало байт
      count++;
    }
  }

  if (shouldCount === count) {
    return buffer;
  } else {
    return buffer.slice(0, buffer.length - (count + 1));
  }
}

function mergeArrays(...arrays) {
  let out = new Uint8Array(
    arrays.reduce((total, arr) => total + arr.length, 0)
  );
  let offset = 0;
  for (let arr of arrays) {
    out.set(arr, offset);
    offset += arr.length;
  }
  return out;
}

В приведенном выше коде мы существуем Fetch Response После возвращениясоздаватьодининдивидуальныймножествоспасти всехвернулся buffer содержание,Затемсуществоватькаждый раз reader.read() Вызывается в методе decode Воляот response.body 已получатьизвсесодержаниеруководить decode。

При этом мы существуем каждый раз decode методза хвостбайтруководитьсуждение об эффективности,Удаление приведет к искажению символов и неполным байтам.

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

в это время,Пересмотрите каждый кадр страницы.,Искаженный текст на странице исчез:

статьясерединаиз Код, который вы можетексуществоватьСмотрите здесь

Отображение res.body в срезах данных

когда Ран,Часто в традиционных приложениях изданные серверной части, возвращаемые во внешний интерфейс, имеют определенный формат, означающий изданные. Итак, к,Легко пройти res.body Получение сегментированного отображения данных не может удовлетворить большинство форматов данных в бизнес-сценариях.

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

Язык кода:javascript
копировать
{
    "data": "real response Data",
    "error": null,
}

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

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

Язык кода:javascript
копировать
{
  "data": [
    {
      "title": "title1",
      "desc": "desc"
    },
    {
      "title": "title2",
      "desc": "desc2"
    },
    {
      "title": "title3",
      "desc": "desc3"
    }
  ],
  "error": null
}

В приведенном выше формате данных data Массив из каждого элемента, который нам может понадобиться отобразить для одного человека на странице, существует. Карта, естественно пройти не думая TextDecoder rea методполучатьданныедаодинсвоего рода ошибкаиз Способ。

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

Более грубый метод заключается в том, что мы используем TextEncoder/TextDecoder для перехвата возвращенного формата данных json в соответствии с определенными правилами.

Автор: Воля stream серединавернулсябайтпреобразован в json Часть перехвата строксодержаниеиз Способиз Это действительно возможнокудовлетворить насизнуждаться,Но на самом деле это не имеет никакой общности.

Мы можем попробовать другой, более общий способ:

  • Каждый раз, когда сервер (NodeServer) возвращает ответ, мы можем использовать специальный заголовок запроса/ответа для определения ответа.

Если этот запрос содержит специальный заголовок запроса, сервер вернет соглашение о внешнем и внутреннем интерфейсах из специальной структуры «изданные». Если этот запрос не содержит специального заголовка запроса, природа возвращает общий заголовок application/json. Просто отформатируйте.

например,То же самое касается и вышеизданных. Мы можем к Воля вернуть индивидуальный формат, отличный от JSON.,напримермы можемк Волявышеизданныесуществовать Сервер обрабатывает его вдля:

Язык кода:javascript
копировать
   "error": null
   
   
   "data": [
    {
      "title": "title1",
      "desc": "desc"
    },
    
    {
      "title": "title2",
      "desc": "desc2"
    },
    
    {
      "title": "title3",
      "desc": "desc3"
    }
  ]

существуют К серверу можно легко получить доступ через \n (число) Правила и клиент договариваются о том, как анализировать эту структуру данных.

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

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

напримерсуществовать Remix серединаиз Defer Эта идея реализуется путем соответствия SPA Режим перехода под из LoaderData данные, полученные от пользователя, значительно снизили скорость ответа страницы.

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

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

Когда, конечно, вы также можете прочитать это сами Remix readStreamSections метод.

Fetch Steam & Content download

частосуществовать XMLHttpRequest в, для Content download Студенты, изучающие фронт-энд, редко имеют возможность эффективно сократить эту часть времени.

и WebFetch Api из Появляться Сотрудничать chunk из Сетевой метод передачи, для нас из Web Применить сетевой запрос на Content download оптимизация обеспечивает более эффективный способ групповой обратной связи с пользователем.

когда Ран За исключением слабой сетидело из Content download Оптимизация пространства, Fetch Api Также существуют другие места, потому что мы приносим больше возможностей.

Если весь фон изданный можно переключить на streaming (аналогично передаче больших файлов), то теоретически его можно использовать на всех сайтах ваших приложений. Web Fetch Оптимизация отклика интерфейса приводит к задержке отображения. Any data request does not need to wait for the interface to fully respond before it can be displayed !

окончание

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

Хотя в статье упоминается, что взгляды Иза относительно радикальны,,Но в целом,Web Stream изWAYS Действительно для Наша страница предлагает возможность быстрого ответа на данныеиз.

boy illustration
Неразрушающее увеличение изображений одним щелчком мыши, чтобы сделать их более четкими артефактами искусственного интеллекта, включая руководства по установке и использованию.
boy illustration
Копикодер: этот инструмент отлично работает с Cursor, Bolt и V0! Предоставьте более качественные подсказки для разработки интерфейса (создание навигационного веб-сайта с использованием искусственного интеллекта).
boy illustration
Новый бесплатный RooCline превосходит Cline v3.1? ! Быстрее, умнее и лучше вилка Cline! (Независимое программирование AI, порог 0)
boy illustration
Разработав более 10 проектов с помощью Cursor, я собрал 10 примеров и 60 подсказок.
boy illustration
Я потратил 72 часа на изучение курсорных агентов, и вот неоспоримые факты, которыми я должен поделиться!
boy illustration
Идеальная интеграция Cursor и DeepSeek API
boy illustration
DeepSeek V3 снижает затраты на обучение больших моделей
boy illustration
Артефакт, увеличивающий количество очков: на основе улучшения характеристик препятствия малым целям Yolov8 (SEAM, MultiSEAM).
boy illustration
DeepSeek V3 раскручивался уже три дня. Сегодня я попробовал самопровозглашенную модель «ChatGPT».
boy illustration
Open Devin — инженер-программист искусственного интеллекта с открытым исходным кодом, который меньше программирует и больше создает.
boy illustration
Эксклюзивное оригинальное улучшение YOLOv8: собственная разработка SPPF | SPPF сочетается с воспринимаемой большой сверткой ядра UniRepLK, а свертка с большим ядром + без расширения улучшает восприимчивое поле
boy illustration
Популярное и подробное объяснение DeepSeek-V3: от его появления до преимуществ и сравнения с GPT-4o.
boy illustration
9 основных словесных инструкций по доработке академических работ с помощью ChatGPT, эффективных и практичных, которые стоит собрать
boy illustration
Вызовите deepseek в vscode для реализации программирования с помощью искусственного интеллекта.
boy illustration
Познакомьтесь с принципами сверточных нейронных сетей (CNN) в одной статье (суперподробно)
boy illustration
50,3 тыс. звезд! Immich: автономное решение для резервного копирования фотографий и видео, которое экономит деньги и избавляет от беспокойства.
boy illustration
Cloud Native|Практика: установка Dashbaord для K8s, графика неплохая
boy illustration
Краткий обзор статьи — использование синтетических данных при обучении больших моделей и оптимизации производительности
boy illustration
MiniPerplx: новая поисковая система искусственного интеллекта с открытым исходным кодом, спонсируемая xAI и Vercel.
boy illustration
Конструкция сервиса Synology Drive сочетает проникновение в интрасеть и синхронизацию папок заметок Obsidian в облаке.
boy illustration
Центр конфигурации————Накос
boy illustration
Начинаем с нуля при разработке в облаке Copilot: начать разработку с минимальным использованием кода стало проще
boy illustration
[Серия Docker] Docker создает мультиплатформенные образы: практика архитектуры Arm64
boy illustration
Обновление новых возможностей coze | Я использовал coze для создания апплета помощника по исправлению домашних заданий по математике
boy illustration
Советы по развертыванию Nginx: практическое создание статических веб-сайтов на облачных серверах
boy illustration
Feiniu fnos использует Docker для развертывания личного блокнота Notepad
boy illustration
Сверточная нейронная сеть VGG реализует классификацию изображений Cifar10 — практический опыт Pytorch
boy illustration
Начало работы с EdgeonePages — новым недорогим решением для хостинга веб-сайтов
boy illustration
[Зона легкого облачного игрового сервера] Управление игровыми архивами
boy illustration
Развертывание SpringCloud-проекта на базе Docker и Docker-Compose