Как я могу использовать JavaScript или PHP, чтобы определить, когда изображения загружаются, если теги изображений динамически создаются из базы данных? - PullRequest
4 голосов
/ 27 октября 2010

У меня есть страница, которая очень интенсивно использует изображения. Это по запросу клиента - это список продавцов с логотипом для каждого. Список довольно длинный (более 500), и да - клиент настаивает на отображении всех из них. У нас есть поиск по типу ajax, чтобы помочь пользователям найти то, что они ищут, без прокрутки, так что это не полная катастрофа.

Вот в чем проблема: клиент только сейчас осознает, что загрузка этой страницы занимает много времени из-за всех логотипов. Даже если каждый из них занимает всего несколько килобайт, он все равно складывается довольно быстро. Теперь он решил, что хочет, чтобы индикатор выполнения отображался во время загрузки изображений. Я никогда не делал этого раньше, поэтому я начал осматриваться, и большинство из тех, что я видел, полагаются на получение массива тегов img и просмотр цикла для проверки полного свойства. Проблема, с которой я сталкиваюсь (по крайней мере, я думаю, что именно это и является причиной проблемы) заключается в том, что теги изображений генерируются запросом к базе данных, и я думаю, что javascript для получения массива изображений загружается до того, как теги изображений заканчиваются. Очевидно, что это не проблема на страницах, где изображения жестко закодированы.

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

Ответы [ 9 ]

2 голосов
/ 01 ноября 2010

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

Оставьте все почти так же, как оно есть.Все, что вам нужно сделать, это найти или сделать троббер (я использую http://ajaxload.info/, и это не может быть проще), и использовать его как фоновое изображение для селектора CSS, который применяется только к логотипам на странице.

Пользователи (и клиенты, которые делают необоснованные запросы!) Гораздо более разочарованы отсутствием оперативности, чем тем, что требует времени.Этого быстрого бесполезного исправления может быть достаточно, чтобы уговорить пользователей сайта воспринимать проблему скорее как последнюю, чем как первую.

0 голосов
/ 20 января 2011

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

  • Sprite - используйте спрайт, где вы группируете несколько изображений вместе и используете свойство фона css (ФАКТ: одинбольшая картинка быстрее, чем несколько запрошенных картинок).
  • Используйте тег <image/> правильно.Вы можете добавить атрибут lowsrc="", чтобы показывать изображение с низким разрешением до полной загрузки атрибута реального изображения aka src=""
  • Используйте ajax, хотя у вас может быть более 500 изображений, которые пользователи никогда не увидят в полном списке,Таким образом, вы можете загрузить 6 за раз (или Nth за раз), когда документ полностью загружен, вы можете добавить остальное таким образом, чтобы вы могли ускорить время загрузки, так как пользователь увидит только некоторые изображения и к тому времени, когда они нажмут next набор изображений, которые они бы загружали (или меньше ждали) лучше, но чтобы сохранить широкополосный доступ, используйте ajax только тогда, когда это требуется, то есть, только когда они нажимают «Далее» или прокручивают вниз автоматически загружать новые изображения.(посмотрите на изображения Google и AJAX, используемые при проверке)
0 голосов
/ 04 ноября 2010

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

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

Не забывайте также, что индикатор выполнения сам добавит время загрузки.И вам нужно, чтобы код был встроен в ваш настоящий HTML-код;если он находится во внешнем javascript-файле, он сам может быть подвержен задержкам при загрузке, что делает весь упражнение бессмысленным.

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

Существует целый стек методов для ускорения времени загрузки сайта;это целая тема сама по себе.Но я постараюсь дать вам несколько советов.Я предлагаю вам также потратить некоторое время на поиск дополнительной информации и последующей информации.

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

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

  • Lazy Load.Существует плагин jQuery под названием LazyLoad , который сообщает вашей странице, что нужно загружать изображения только по мере необходимости.Изображения, находящиеся за пределами видимой страницы, откладываются до тех пор, пока пользователь не начнет прокручивать страницу.Это означает, что изображения, которые видны сразу, загружаются первыми, в результате чего страница в целом загружается быстрее.

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

Надеюсь, это поможет.

0 голосов
/ 04 ноября 2010

Вот решение только для javascript, которое не требует каких-либо изменений в вашем коде на стороне сервера. Использование jquery:

$(document).ready(function() {
    var loadedSoFar = 0;
    //use jquery to get all image tags you want.
    //The totalImgs is used to calculate percent and is the length of the jquery array
    var totalImgs = $("#imgHolder img").each(function(i, img) {
        //if this image has already loaded, add it to loadedSoFar.
        if (img.complete)
            loadedSoFar++;
        else {
            //otherwise add a load event for the image.
            $(img).load(function() {
                loadedSoFar++;
                console.log("complete: " + (loadedSoFar / totalImgs * 100) + "%");
            });
        }
    }).length;
});

Я написал это, предполагая, что все изображения уже находятся в DOM, когда вызывается document.ready. Если это не так, переместите это в функцию и вызовите ее после загрузки тегов img в dom с сервера (например, с помощью ajax-запроса).

По сути, все, что он делает, - это находит все imgs в imgHolder (измените селектор в соответствии с вашей ситуацией) и связывает событие load, чтобы он мог обновить счетчикloadedSoFar. Если к моменту запуска этого скрипта изображение уже загружено, событие загрузки никогда не сработает, поэтому сразу увеличьте счетчикloadedSoFar. Общее количество загружаемых изображений будет равно длине массива объектов jquery, возвращаемого селектором.

Я оставлю вам написать индикатор выполнения, но я рекомендую этот плагин: http://t.wits.sg/jquery-progress-bar/

0 голосов
/ 31 октября 2010

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

function Iterator() {

  var counter = 0;  
  this.images = 215; // This number comes from the DB and gives you a total number of images
  this.progress = counter / this.images

  this.hasMore = function() { counter < this.images }

  this.getPicture = function() {
    // send a request to the server using counter as a parameter
    // upon receiving this request the server should load only ONE image (LIMIT=1 in SQL)
    // with OFFSET equal to the value of "counter"
    // when the image loads (use whatever JS framework you need for that), 
    // we increment the counter:
    counter++;
  }

  this.loadPictures = function() {
    while this.hasMore() {
      this.getPicture()
      // You can do something with the "progress" attribute here, to be visualizad by your progress bar
    }
  }

);

Вам обязательно нужно создать экземпляр объекта Iterator при загрузке тела и заставить его выполнить функцию loadPictures.

Пожалуйста, дайте мне знать, если у вас есть какие-либо проблемы с реализацией этого.

0 голосов
/ 31 октября 2010

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

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

Это не красиво, но и запрос клиента.

Редактировать. Что касается индикатора выполнения, то при определении местоположения окна (или местоположения с типизированным вводом) определите, сколько списков будет отображаться, и сколько списков будет помещено в буфер выше и ниже представления. Тогда у вас будет общее количество списков, и вы сможете обновлять индикатор выполнения JavaScript / HTML при динамической замене логотипов в этом диапазоне.

0 голосов
/ 27 октября 2010

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

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

Если вы можете свести его к нескольким статическим файлам для каждого логотипа, вы также можете рассмотреть возможность использования CDN и / или нескольких поддоменов, как предлагает Майкл Мао.

0 голосов
/ 27 октября 2010

Я не проверял это, но что-то вроде этого может работать (его jQuery)

<?php // Do your select image stuff from here ?>
<html>
<head></head>
<body>
<script type="text/javascript">
$(document).ready(function () {
    var images = <?php echo json_encode($images); ?>;
    $.each(images, function(i, image) {
        $(new Image()).load(function () {
            $('body').append(this);
            alert('Loaded '+i+' out of '+images.length);
        }).attr('src', image);
    })
});
</script>
0 голосов
/ 27 октября 2010

CSS Sprites определенно станет хорошим началом в вашем случае.Если вы получили 500 отдельных изображений на одной странице, браузер должен будет запустить 500 новых подключений, чтобы извлечь их, и, к сожалению, число одновременных подключений будет около 20 или около того, так что ... это не хорошо.

CSS-спрайты с сайта css-tricks.com

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