3. Reflection on my level - JeanyDeVries/ilojo-bar Wiki

Web app from scratch

We implemented the knowledge from this course in our project.

Our code structure is structured in multiple folders. Our Javascript code is made in modules. We import our scripts in other code. We also have partials, header and footer, that we include in almost all our pages. To implement the JS in the pages we made use of ejs.

We made use of an API we made in prismic. We use Prismic as a headless CMS. A headless CMS is a content management system (CMS), only used for back-end purposes, built from the ground up to make content accessible and maintainable. In prismic we have multiple structures. For our story pages we used sections with ID's and per section you can add a text paragraph and an image. In our code we grab the data in our app.js. We then map it to get the specific information we want from the data. We then send the mapped array to the html page, so we can display the data.

let stories = await client.getAllByType('story', {
  orderings: {
    field: 'my.story.id',
    direction: 'asc'
  }
})

let discoverList = stories.map(story => {
   return {
     "url": story.url, 
     "collage_image": story.data.collage_image,
     "title": story.data.title[0].text
   }
})
    
res.render('discover', { discoverList })

CSS To The Rescue

I certainly used CSS for this project. We designed our project with multiple css techniques. For the colors we used custom properties, which I love using. I made a wrecking ball that has a before (reflection) and an after (rope) on the element. We also use animations for certain things. We use media queries to make it work for both desktop and mobile.

Progressive Web Apps

The site is for the people in Lagos where sadly the internet connection is poorly and many people do not have the newest phones. To still have to make our site working, so we made some changes to optimise our performance.

Images The first thing we did was optimise our images. Some images took a lot of loading time, where one was even 2mb. This was drastic for our loading time. So we made all our images webp, which create smaller, richer images that make the web faster. Sadly webp is not always supported so we added a fallback.

<picture>
   <source srcset="/images/close.webp" type="image/webp" >
   <source srcset="/images/close.png" type="image/png">
   <img src="/images/close.png" width="477px" height="478px" alt="Close button">
</picture>

Compression We use the compression middleware to improve our performance as well. The middleware will attempt to compress response bodies for all request that traverse through the middleware, based on the given options.

// Compress alle responses
app.use(compression())

Caching Caching is a great way to improve the performance if you visit the site repeatedly. If you visit the site it caches the core, which is our JS, images, fonts and css, plus it caches the HTML pages you have visited. For the caching strategy we chose 'stale while revalidate'. This strategy means that if a request can be loaded from the caching it will be done this way. Otherwise it will run a fetch in the background to save it in the cache, this way your site wil be up to date with a delay of 1 refresh. This way it will load almost instant if you have visited the page before. Another great thing about caching is that if you are offline, but you have visited a page beforehand when you were online, it will still load. This is because it is cached in your local storage.

self.addEventListener('fetch', function(event) {

    if (isCoreGetRequest(event.request)) {
        //Pakt meteen de cache versie
        event.respondWith(
          caches.open(CORE)
            .then(cache => cache.match(event.request.url))
        )
    } else if (isHtmlGetRequest(event.request)) {
        //Pakt cache als die er is, ondertussen nieuwe versie in cache opslaan
        event.respondWith(
        caches.match(event.request.url)
            .then(response => {
                if (response) {
                    event.waitUntil(
                        fetchAndCache(event.request.url, 'html-cache')
                    )
                    return response
                } else {
                    return fetchAndCache(event.request.url, 'html-cache')
                }
            })
            .catch(e => {
            return caches.open(CORE)
                .then(cache => cache.match('/offline'))
            })
        )
    } else if (isOtherGetRequest(event.request)) {
        event.respondWith(
            fetch(event.request)
                .then(response => {
                    return response;
                })
                .catch(e => {
                    return caches.open(CORE)
                        .then(cache => cache.match('/offline'))
                })
        )

    }
});

We also cache everything besides the HTML pages for a year. This is great for our images or other elements on the site, that do not change often. It does not have to load everytime we load the page again. Plus why not cache it if it doesn't change that often.

app.use(function(req, res, next) {
    if (req.method == "GET" && !(req.rawHeaders.toString().includes("text/html"))) {
        res.set("Cache-control", "public, max-age=31536000")
    }
    next()
})

Browser Technologies

We implemented progressive enhancement in our project. As I said before, the site is for the people in Lagos where sadly the internet connection is poorly and many people do not have the newest phones. We needed to add feature detections and fallbacks if the JS is not enabled.

We added fallbacks to our home and discover page. We used GSAP for a scroll animation, but if you disable the JS you cannot scroll further. In case of the home page this makes sure you cannot use the site any further.

To fix this we had the page as default with the picture of the building (which is the end result of the scrolling). We then use fromTo to set the beginning of the scroll page again. It only sets the start of the scrolling page, if ScrollTL is supported. This way it will always have the correct default page if JS is disabled, and if enabled it will show the start of the scrolling effect.

scrollTL.fromTo('.scroll_btn', {opacity: 1, duration: .3}, {opacity: 0} )
        .from('.scroll_cont', {scale: 1},"<")
        .fromTo('#color_building', {opacity: 0}, {opacity: 1},"<")
        .fromTo('#background', {opacity: 1}, {opacity: 0},"-=50%")
        .fromTo('#overlay', {opacity: 1, scale: 1}, {opacity: 0, scale: 1.05}, "<25%")
        .fromTo('.discover_cont',{opacity: 0, zIndex: 0, scale: 0.9, rotation:-3}, {opacity: 1, zIndex: 2, scale: 1, rotation:0}, "<")
        .from('.see_model_cont',{ translateX: "100%", opacity: "0"}, "<")
        .addLabel('end')
       

For feature detection we added a check on our images formatting. We wanted to use webp for our images, because those would improve the sites performance. Sadly this wasn't greatly supported. So we added a picture container where we set our sourceset to webp at first, if it isn't supported it will go to the next line which makes the sourceset a png. This way we have a feature detection and a fallback of setting our images to png's.

<picture>
   <source srcset="/images/close.webp" type="image/webp" >
   <source srcset="/images/close.png" type="image/png">
   <img src="/images/close.png" width="477px" height="478px" alt="Close button">
</picture>

Real-time Web

We didn't add any realtime applications to our site. The main reason is, because the client wasn't particularity looking for something like this. Another reason is, because realtime needs a good connection between both users. Sadly Lagos doesn't have great internet connection.

Human Centered Design

We iterated our design each sprint. We had our talks with the client, which is why we had to change our design a bit. Plus the design reviews gave some insight as well.

⚠️ **GitHub.com Fallback** ⚠️