В процессе разработки интерфейсов на платформе 1С:Предприятие 8.3 часто возникает задача отображения внешних изображений, хранящихся на веб-серверах или в облачных хранилищах. Типичная проблема, с которой сталкиваются разработчики — это существенные задержки (так называемый «тупняк») при попытке отобразить картинку в стандартном поле картинки, особенно если изображений много. В данной статье мы подробно разберем, как можно эффективно решить эту задачу, избегая лишних операций записи на диск и повышая отзывчивость интерфейса.
Рассмотрим самый простой и логичный способ отображения картинки из интернета — использование элемента формы Поле HTML-документа. Этот метод позволяет платформе делегировать загрузку и отображение встроенному движку браузера (WebKit или Chromium в зависимости от версии платформы), что максимально приближает поведение 1С к обычному браузеру.
Разберем по шагам, как это реализовать:
Строка (неограниченной длины).Поле HTML-документа.Проанализируем пример кода для формирования строки HTML:
&НаСервере
Функция СформироватьHTMLДляКартинки(СсылкаНаКартинку)
ТекстHTML = "<html>
|<head>
|<style>
| body { margin: 0; padding: 0; overflow: hidden; }
| img { width: 100%; height: auto; object-fit: contain; }
|</style>
|</head>
|<body>
| <img src=""" + СсылкаНаКартинку + """>
|</body>
|</html>";
Возврат ТекстHTML;
КонецФункции
Этот способ хорош тем, что мы фактически не скачиваем файл средствами 1С. Браузерный движок сам управляет кешированием и потоками загрузки. Однако, если нам нужно отобразить картинки в списке (например, в каждой строке динамического списка), создание множества полей HTML может негативно сказаться на производительности.
Выясним причину, по которой стандартные функции БСП (Библиотеки Стандартных Подсистем), такие как ПолучениеФайловИзИнтернетаСлужебный.СкачатьФайл(), могут работать медленно. Обычно это связано с большим количеством проверок: настройка прокси, проверка сертификатов SSL, логирование и анализ заголовков. Если вы уверены в источнике картинок, можно использовать «лайфхак» с методом КопироватьФайл.
Как оказалось, функция КопироватьФайл в 1С умеет принимать в качестве первого параметра URL-адрес. Это работает значительно быстрее, так как выполняется на более низком уровне системы. Посмотрим на пример реализации:
&НаСервере
Функция ПолучитьКартинкуПоСсылкеБыстро(URLКартинки)
ИмяВременногоФайла = ПолучитьИмяВременногоФайла(".jpg");
Попытка
// Платформа сама скачает файл по ссылке во временную директорию
КопироватьФайл(URLКартинки, ИмяВременногоФайла);
КартинкаОбъект = Новая Картинка(ИмяВременногоФайла);
АдресХранилища = ПоместитьВоВременноеХранилище(КартинкаОбъект, ЭтаФорма.УникальныйИдентификатор);
УдалитьФайлы(ИмяВременногоФайла);
Возврат АдресХранилища;
Исключение
Возврат Неопределено;
КонецПопытки;
КонецФункции
Важный нюанс: Несмотря на высокую скорость, этот метод всё равно использует дисковые операции (создание временного файла). Если ваша цель — полностью исключить работу с диском для ускорения процесса, стоит рассмотреть работу с двоичными данными в оперативной памяти.
Проанализируем ситуацию, когда нам нужно получить данные картинки напрямую в память. Для этого лучше всего подходят объекты HTTPСоединение и HTTPЗапрос. Это позволяет нам получить ДвоичныеДанные и сразу создать из них объект Картинка, минуя стадию записи временного файла на диск.
Рассмотрим пример кода:
&НаСервере
Функция ПолучитьКартинкуВПамять(URLКартинки)
// Разберем URL на составляющие
СтруктураURL = ОбщегоНазначенияКлиентСервер.РазложитьУРЛ(URLКартинки);
// Настроим защищенное соединение, если это HTTPS
НС = Новый ЗащищенноеСоединениеOpenSSL();
Соединение = Новый HTTPСоединение(СтруктураURL.Хост, , , , , , НС);
Запрос = Новый HTTPЗапрос(СтруктураURL.ПутьНаСервере);
Попытка
Ответ = Соединение.Получить(Запрос);
Если Ответ.КодСостояния = 200 Тогда
ДвоичныеДанные = Ответ.ПолучитьТелоКакДвоичныеДанные();
Картинка = Новая Картинка(ДвоичныеДанные);
Возврат ПоместитьВоВременноеХранилище(Картинка, ЭтаФорма.УникальныйИдентификатор);
КонецЕсли;
Исключение
Возврат Неопределено;
КонецПопытки;
Возврат Неопределено;
КонецФункции
Этот метод является максимально «чистым» с точки зрения архитектуры 1С, так как мы полностью контролируем процесс запроса и не оставляем «мусора» на диске сервера или клиента.
Если мы отображаем список товаров с картинками, даже самый быстрый метод загрузки может заставить интерфейс «замереть» при прокрутке. Чтобы этого избежать, разберем два важных подхода:
Соединение.Получить() можно использовать Соединение.ВызватьHTTPМетодАсинх(). Это позволит форме отрисоваться сразу, а картинки будут «подтягиваться» по мере загрузки.Соответствие, где ключом будет URLКартинки, а значением — АдресВоВременномХранилище.Посмотрим, как можно реализовать простую систему кеширования на форме:
&НаКлиенте
Перем КэшКартинок;
&НаКлиенте
Процедура ПриОткрытии(Отказ)
КэшКартинок = Новый Соответствие;
КонецПроцедуры
&НаКлиенте
Асинх Процедура ЗагрузитьКартинкуДляСтроки(URL, ИдентификаторСтроки)
// Проверим, нет ли ссылки в кеше
Адрес = КэшКартинок.Получить(URL);
Если Адрес = Неопределено Тогда
// Загружаем асинхронно с сервера
Адрес = Ждать ПолучитьАдресКартинкиСервер(URL);
КэшКартинок.Вставить(URL, Адрес);
КонецЕсли;
// Обновляем данные на форме
Элементы.ТаблицаТоваров.ДанныеСтроки(ИдентификаторСтроки).КартинкаПуть = Адрес;
КонецПроцедуры
Подводя итог, можно выделить следующие рекомендации по работе с картинками из интернета:
КопироватьФайл с URL является самым быстрым «коробочным» решением.HTTPСоединение.Используя эти методы, мы сможем добиться мгновенного отображения визуального контента в наших решениях на базе 1С, делая их более современными и удобными для конечного пользователя.