The purpose of this project is to optimize a provided website with a number of optimization- and performance-related issues so that it achieves a target PageSpeed score and runs at 60 frames per second. In order to accomplish the required target page speed score and ability to run 60 frames per second the following was completed. Pagespeed Insight
Part 1: Make Optimization to page index.html so that a score of 90 can be achieved for desktop and mobile on Pagespeed Insights.
Part 2: Make optimizations to views/main.js so that views/pizza.html renders consistently at 60 frames per second. Also resize pizzas on views/pizza.html is less than 5ms on browser developer tool.
-
Grunt plugins used:
-
uglify used to minify javascript files
-
imagemin used to minify images
-
cssmin used to minify css files
- Clone github reposititory
- Open git bash application, go to directory where clone was downloaded
- Make sure Node.js is installed by typing: node --version
- Install npm by typing the following: npm install
- Start the local http server by typing: http-server
- Open Chrome Browser with ip address listed by local server
- Hosting the website was done on github pages to test on Page Speed Insights
- Chrome Devtools used to measure frame per second and resize speed of 5ms
- Directories used for source src and production dist files:
src dist views/src views/dist
|-img |-img |-images |-images
|-css |-css |-css |-css
|-js |-js |-js |-js
- Minimized style.css then inlined styles sheet on html
- Used web font loader to load google fonts asynchronously using javascript
- Minimized images with extension -min.jpg, -min.png using grunt imagemin
- Prioritizing visible content preload in to preload images
- Minimized javascript perfmatters.js to perfmatters.min.js using grunt uglify
- Used asynchronous on javascript files for google analytics and perfmatters-min
- Minimized style.css using grunt grunt cssmin and inlined it on html
- Minimized bootstrap-grid.css and added extension to name as follows: bootstrap-grid.min.css
- Minimized images using grunt imagemin and added file name extension of -min.jpg and -min.png
- Used preload in to preload images
- Minimized javascript main.js and added file name extension: main.min.js
-
On function resizePizzas, I replaced querySelector with getElementById to improve performance.
-
On the function changePizzaSizes I used Udacitys Cameron Pittmans video Stop FSL (Forced Synchronous Layout) to solve the problem of FSL. The offsetWidth being called before the style.width was causing the FSL, therefore I removed offsetWidth, combined determinDX with changePizzaSizes and set the newwidth based on the size and set the style.width = newwidth. I also optimized the code by removing function determineDx.
-
Line 504, creating a new variable in the loop can be very expensive so I move the creation of pizzaDiv outside the loop
-
On function updatePositions I used "Website Optimization Project webcasts: Tips - Increasing Framerate (FPS)" to optimized the function. I used transform = translateX to keep layouts from retriggering and removed items.style.left and moved variables not required in for loop out: items, cacheScrollTop and phaseNumber. len variable created to keep track of the items array length.
-
On Function updatePositions creating a variable in a loop can be very expensive, so I moved the creation of phase variable outside the for loop. Doing Math.sin calculations in loop can also be very expensive so I move the calculation into a phase array. I created a phase array that contains 5 calculations outside the loop, because the modulus 5 returns only 5 values, 0-4. On translateX I removed items[i].basicLeft from the equation to correct problem with background pizzas only showing 50% or less of most screens.
-
I replaced window.addEventListener('scroll', updatePositions) with window.addEventListener('scroll', onScroll, false) using code optimization called "Debouncing Scroll Events" by Paul Lewis this keeps requestAnimationFrame from causing reflow and repaint which increases the frame rates per second. onScroll and requestTick are used to with requestAnimationFrame to avoid reflow-repaint loops and is only call when requestAnimationFrame updates are needed.
-
I replaced document.addEventListener('DOMContentLoaded', function() with document.readystatechange this checks when the document has loaded and prevents the asynchronous javascript file main.min.js from loading before the document causing background pizzas to disappear. The solution came from this site: I also reduced number of pizzas from 200 to 31 which is all that is needed to fill window. This reduces the time it takes to load pizza images. I moved the creation of variable elem outside the loop. I replaced querySelector with getElementById. Because translateX is being used in updatePositions, a required change was need to elem.basicLeft to elem.style.left = (i % cols) * s + 'px'. I created variable movingPizza so I could move call to document.getElementsById outside the loop.
- added backface-visibility: hidden to improve framerate by making each indiivdual pizza a composite layer and keep from having to repaint a whole layer which takes more time. Hack credit goes to Mark N from Website Optimization Project Webcasts: Tips - Increasing Framerate (FPS)