I am developing a website that has some photos to display, divided in albums.
Each photo's path is stored in a database.
I want to display the photos using a jquery gallery plugin. The problem is that the photos are taking forever to load, which sometimes causes the browser to crash.
I have tried lazy loading with galleria, lazyload and jpreloader, but so far the problem remains.
For the development of the site i use CodeIgniter. So far i have tried two methods for loading the photos.
1) By passing them from the controller to the view.
2) By using jquery and ajax.
Which method is better from a performance perspective?
The number of the photos isn't really big, just 17 with total size about 5mb.
If anyone could help me, i would be extremely gratefull.
you need to compress/resize your images on the server side, preferably one thumb at size of your gallery & one between 720 & 960 for the full size,
thumbs will be really lightweight, full size maybe 850kb for the 17
i give you an easy to use php class dealing with all image format :
<?php
class scratch_utils_imgresize
{
static function resize($file_path
,$new_file_path
,$img_width
,$img_height
,$scale) {
$new_width = $img_width * $scale;
$new_height = $img_height * $scale;
$new_img = #imagecreatetruecolor($new_width, $new_height);
switch (strtolower(substr(strrchr($file_path, '.'), 1))) {
case 'jpg':
case 'jpeg':
$src_img = #imagecreatefromjpeg($file_path);
$write_image = 'imagejpeg';
$image_quality = isset($options['jpeg_quality']) ?
$options['jpeg_quality'] : 75;
break;
case 'gif':
#imagecolortransparent($new_img, #imagecolorallocate($new_img, 0, 0, 0));
$src_img = #imagecreatefromgif($file_path);
$write_image = 'imagegif';
$image_quality = null;
break;
case 'png':
#imagecolortransparent($new_img, #imagecolorallocate($new_img, 0, 0, 0));
#imagealphablending($new_img, false);
#imagesavealpha($new_img, true);
$src_img = #imagecreatefrompng($file_path);
$write_image = 'imagepng';
$image_quality = isset($options['png_quality']) ?
$options['png_quality'] : 9;
break;
default:
$src_img = null;
}
$success = $src_img && #imagecopyresampled(
$new_img,
$src_img,
0, 0, 0, 0,
$new_width,
$new_height,
$img_width,
$img_height
) && $write_image($new_img, $new_file_path, $image_quality);
// Free up memory (imagedestroy does not delete files):
#imagedestroy($src_img);
#imagedestroy($new_img);
return $success;
}
}
?>
First of all, you need to define your performance bottleneck.
Is it your database query response?
Is it your PHP script?
Is it your javascript?
Is it your browser?
Is it your image server's upload speed?
If you know it's the server's upload speed, which is usually the case, then you should not output into HTML all of the images at once. This can be solved in many ways, of which I'll only cover 2...
The "long page" format
The "paginated/tabbed" format
1) Use the jQuery plugin LazyLoad properly like so:
// include jQuery and lazyload plugin
<script>
// Make sure $ is still short for jQuery (no conflict exists with other libraries)
$(function() {
$("img.lazy").lazyload();
});
</script>
<body>
<img class="lazy" data-original="img/example.jpg">
2) jQuery UI tabbed method (documentation here)...
<?php
// json_encode the albums you get from your db
$jsonEncoded = json_encode($returned_array_from_db_of_albums);
?>
<!-- include jQuery and jQuery UI -->
<script>
$(function() {
var albums = <?php echo $jsonEncoded; ?>;
// iterate through albums to find the album names and build our tab menu (expressed in HTML already below) and the associated <div>s where the images will ultimately go
// e.g. $('#album-names').html(album_names_html);
// then $('#albums').append(album_names_divs_html);
function displayAlbum (id) {
// id parameter will be the id of the <a> tag you clicked below
// fetch the images from the albums array you defined above associated with the album id
// build the <img> tags and set the associated $('div#'+id).html() to your output
}
$('#albums').tabs();
displayAlbum('first-album'); // first-album should be the id of the first album in your albums array
$('#albums ul li a').click(function() {
displayAlbum($(this).attr('id'));
});
});
</script>
<body>
<div id="albums">
<ul id="album-names">
<!-- following 2 <li>s should be generated by your javascript as explained above -->
<li>Album 1</li>
<li>Album 2</li>
</ul>
<!-- like my comment above, so should these -->
<div id="album-1"></div>
<div id="album-2"></div>
</div>
Also make sure your images are as compressed as possible as one of the other answers suggested. However, I don't recommend compressing the images every time someone hits the page, like in a PHP script. Be sure to compress the images beforehand.
Related
I'm trying to create my own "previous" & "next" buttons on my portfolio that will read from a set or arrays that load static php file. I'm not againsts even doing in js, but I assume php might be easier since all my files are in php.
Looking for a simple loop to call and load the pages...
var pages = [
"index.php",
"project1.php",
"project2.php",
"project3.php",
"project4.php",
];
var Current = 0;
with some sort of function for prev(); and next();
function Prev(){
if(Current == 0){
Current = pages.length - 1;}
else{
Current--;}
}
function next(){
if(Current == 0){
Current = pages.length - 1;}
else{
Current++;}
}
them have my html look something like this...
<a href="prev();" class=“prev”>Previous </a>
<a href="next();" class=“next”>Next </a>
Any help would be greatly appreciated!
There are multiple ways of doing this.
One would be to add an iframe to your page and changing its src attribute to your page URL when one of the buttons is clicked. Another would be to have some container (e.g. a div) and then load the HTML dynamically (e.g. via fetch or AJAX) and insert it as the innerHTML of said container.
I've been trying to utilize the dropzone.js plugin and would be grateful for anyone's thoughts who is more experienced at this one, as documentation on the net seems to be sparse. The below code segment essentially demonstrates what I'm trying to do.
<script>
for (j=1; j<=5; j++) { // set photo boxes, these can be revisited later
picname = './pics/'+pic[j];
// custom function, after php the function, returns true if file exists
if (file_exists(picname)) {
// show picture (possibly dropzone-generated thumbnail?)
$("#photo"+j).html('<img src="'+picname+'"><br>'+name[j]);
} else {
$("#photo"+j).dropzone({
url: 'picupload.php'
});
}
}
</script>
<div id="photo1"></div>
<div id="photo2"></div>
<div id="photo3"></div>
<div id="photo4"></div>
<div id="photo5"></div>
Each div'd photo container should at any time be able to switch back and forth from a dropzone to a display of an uploaded photo if it exists. I've scaled back the configuration parameters of the dropzone and omitted the css for clarity sake.
I would also like to know if it's possible to leverage the thumbnail-generating aspects of dropzone.js to save/show thumbnails of uploaded files (images).
My requirement is to show .tiff image on browser. So currently I'm showing tiff file on Internet Explore using img tag like below.
<img src="myTiff.tif" type="image/tiff" alt="My Tiff">
And it works perfect with the tif file having only single page. In case there would an multiple pages in .tif then the img tag only shows 1st image. User can not get option to view other image.
Sample tiff image
I already tried all the option suggested here
I'm using C# on server side & on front end using AngularJS. Any help would appreciated. Thanks :)
Edit
Would it be better way to go with AltraTiff plugin? I looks like working on Internet Explorer.
Content rendering is always browser's responsibility so you rely in its capabilities.
Maybe there is some plugin for some browser that supports multiple-page tiffs, but, if you can't control software installed in your clients, I think your best option would be to implement some pagination by separating pages server side.
You can achieve that easily with imagemagick.
The only drawback is that, if user try to download it, it will download only the single page he were currently viewing.
But yo can mitigate it by providing separate download link or, simply, linking full version to the displayed image. Example using jQuery:
<div id="tiffPager">
<a href="myTiff.tif">
<img width=200 height=200 data-pageCount=5 src="myTiff_page0.tif" alt="My Tiff">
</a>
<button class="pageBack"><<</button>
<button class="pageForward">>glt;</button>
</div>
<script>
$(function(){
var container = $("div#tiffPager");
var img = $("img", container);
var backBtn = $("button.pageBack", container);
var fwBtn = $("button.pageForward", container);
var pgCount = img.data("pageCount");
var currPage = 0;
backBtn.on("click", function(){
currPage = (currPage + 1) % pgCount; // Cycle though pages.
img.attr("src", "myTiff_page" + currPage + ".tif");
});
fwBtn.on("click", function(){
currPage = (currPage - 1) % pgCount; // Cycle though pages.
img.attr("src", "myTiff_page" + currPage + ".tif");
});
});
</script>
I have a PHP script that connects to an API and grabs around 200 avatars. I want to display 25 of them on my page, but have a "MORE" button for the user to press that will fade those 25 out, and then show the next 25. When it gets to the end of the avatars, I want the "MORE" button to cycle to the start again.
I am not sure the best way to do this, should I load all 200 images but set the last 175 to be invisible, then do it through Javascript and JQuery, does that make sense?
I know I am asking a confusing question. I just basically want to display 25 at a time instead of 200, and I'm not sure of the specific JQuery or Javascript way to do it.
Sounds like you're looking for something that loads data dynamically from a php-based source, so many at a time. You can load images pretty easy from a datasource like:
$.getJSON("http://somewhere.com/feeds/feed.php?id=12345", function(data) {
$.each(data.items, function(index, item) {
$("<img/>")
.attr("title", item.title)
.attr("src", item.src)
.wrap("<a href='" + item.link + "'></a>")
.appendTo("#mybox")
});
});
and then combining the list with something like jCarousel - http://sorgalla.com/jcarousel/ - which has the ability to cycle from the last item back through the first. In fact, jCarousel might be your best solution. Load and build a list from your php-driven json source - check out this demo of loading a carousel from ajax
http://sorgalla.com/projects/jcarousel/examples/dynamic_ajax_php.html
Adding pagination might not be required with a carousel, but if required this link might be helpful to you.
http://www.myphpetc.com/2009/10/easy-pagination-with-jquery-and-ajax.html
Good luck!
I would go with http://masonry.desandro.com/ and it has its infinite scroll method, seems cool.
Let's say your more link has an id: "more-link", and your image container has an id "images". Then it would look something like this:
$(function() {
var avatars = [], position=0;
$.get("/avatars").then(function(list) {
avatars = list;
show_25();
});
function show_25() {
for(var i = position; Math.min(i,list.length) < 25+position; i++) {
$("<img />").attr("src",list[i]).appendTo("#images");
}
position += 25;
if( position > list.length ) {
$("#more-link").hide();
}
}
$("#more-link").click(show_25);
});
I have run into numerous sites that use a delay in loading images one after the other and am wondering how to do the same.
So i have a portfolio page with a number of images 3 rows of 4, what i want to happen is for the page to load,except for the images in img tags. Once the page has loaded i want images 1 of each row to load then say 0.5 seconds later the next image in the row(s) and so no. I'm going to have a loading gif in each image box prior to the actual image being displayed.
I know its doable but cant seem to find the term for doing this. This is purely for looks as it is a design site.
Thanks for the help.
This is very easy to do in jQuery
$('img').each(function(i) {
$(this).delay((i + 1) * 500).fadeIn();
});
Fiddle: http://jsfiddle.net/garreh/Svs7p/3
For fading in rows one after the other in a table it just means changing the selector slightly. Remember to change from div to img -- I just used div for testing
$('tr').each(function(i) {
$('td div', this).delay((i + 1) * 500).fadeIn();
});
Fiddle: http://jsfiddle.net/garreh/2Fg8S/
Here is what you can do, you can load the image tags with out the src and using a custom property:
<img alt='The image' path='image/path.jpg' />
then you can use javascript to load the images when the site is loaded or whenever you please;
// simplified
window.onload = function () {
var images = document.getElementsByTagName('img');
// loop and assign the correct
for (var i =0; i < images.length;i++){
var path = images[i].getAttribute('path');
images[i].src = path;
}
}
I hope you get the concept of how the images are delayed
**please note the path attribute is not a standard one.
The easiest way I can think to do this is to have a table set up that will eventually hold the image tags, but have none on load. Javascript can loop through an array of image urls, and insert those image tags into random locations on the table.
If you want to have the delay, setInterval is the perfect tool. http://www.w3schools.com/jsref/met_win_setinterval.asp
// You can hard-code your image url's here, or better still, write
// a server-side script that will read a directory and return them
// so it is fully dynamic and you can add images without changing code
unpickedImages = array();
// Start loading
loadAllImages = setInterval( insertImage, 600 );
function insertImage() {
if( unpickedImages.length > 0 ) {
var imageUrl = unpickedImages.shift();
// pick empty x, y on your table
// Insert the image tag im that <td></td>
} else {
clearInterval( loadAllImages );
}
}
You really don't need javascript to do this. If you specify the image sizes in the HTML or CSS, the browser will layout and display the page while loading the images, which will likely be loaded in parallel. It will then display them as soon as it can.
That way if users re-visit your site and have the images cached, they all show up immediately. If you have a script to load the images after a delay, you are making visitors wait for content unnecessarily and all their efforts to have a faster browser and pay for a fast internet connection has gone to waste.