Saturday, March 30, 2024
PHP 7.3 vs 7.4
Tuesday, March 12, 2024
PHP: Checking if an image is WebP
Let's say you have a WebP image:
$this->image = imagecreatefromwebp('path/to/your/image.webp');
If you want to check if an image is a resource, In PHP 7.3 the following returns true:
is_resource($this->image)
In PHP 8.0, the behavior changes because the GD library's image resources are replaced with GdImage objects. This change means that image resources created with GD functions, like imagecreatefromwebp(), no longer return a resource type. Instead, they return an instance of the GdImage class. In other words, for a WebP image, is_resource($this->image) returns false and for PHP 8, you should update your code as follows:
is_resource($this->image) || $this->image instanceof GdImage
Tuesday, March 5, 2024
Adding WebP preview to dropify.js
My web app uses dropify.js for image uploads. Dropify was last updated 7 years ago on March 19, 2017. I recently updated images from PNG/JPEG to WebP for less memory usage. Although the WebP image format was officially announced by Google on September 30, 2010, I could not preview them with dropify:
To solve this problem, I wrote dropifyPreviewFix.js.If you want to batch convert your PNG/JPEG files to WebP, you can use convertToWebP.php.
Monday, March 4, 2024
Optimizing website speed and memory usage
The web app for the online marketplace I've been maintaining experienced significant slowdowns as the number of products on the site increased. Page load times reached 20 seconds, making the site unusable. Over the past three days, I have used the Chrome browser's built-in Lighthouse tool to analyze the issue and have implemented several optimizations.
I initially aimed to reduce image sizes. On average, WebP format consumes 4x less memory than JPEG for product photos. For PNG images, I've observed file size reductions of up to 100x. In total, converting images to WebP decreased server disk and memory footprint by 7x. This also has a positive effect on client LCP.
I implemented lazy loading to load only the image data visible on the screen, rather than loading all images at once. Additionally, by using infinite scrolling to load only the HTML text of the visible portion, the initial memory usage for the client-side webpage source text was reduced from 1,386,494 bytes to 57,977 bytes, achieving a 24x reduction. These size optimizations decreased load times from 20 to 13 seconds. Almost all of the remaining 13 seconds was initial server response time.
The most significant improvement in page load speed was achieved by eliminating N+1 query issues (using a loop instead of a single query) in the database queries. In my case, the inefficiency was fetching photos for each product in separate queries within a loop instead of fetching all the necessary photos in one query and then map them to their respective products. This enhancement reduced the initial server response time from 13 seconds to 2 seconds and the site became usable again.
I still have a lot of work to do to apply these techniques to other portions of the code, but at least now I know where to focus.