DEV Community

loading...
Cover image for Three things I learn after fighting with Google PageSpeed

Three things I learn after fighting with Google PageSpeed

Yuki Cheung
I am a self-taught front-end web developer! Jump into this field using freeCodeCamp since 2017. Now mostly focus on front-end technologies, e.g. SASS / ReactJS and some backend like PHP/Laravel.
・3 min read

Recently, I have a chance to maintain a landing page, which has a new design, but with loading performance issue and conversion drops a lot compared to the old page.

What I learn is these:

  1. Optimize images (compress / lazy load)
  2. Optimize CSS/JS loading (critical path rendering)
  3. Code splitting

1. Optimize images

Image is the easiest thing to fix and is the primary factor of loading speed. It is important to use image compression like TinyJPG to compress images, minimize the page size and set image to progressive one.

To make image become progressive image, you can try this if you have Imagemagick on your computer:

for i in ./*.jpg; do convert -strip -interlace Plane $i $i; done

Moreover, it is necessary to use lazy load to prevent loading unneeded image, which is out of screen.


2. Optimize CSS/JS loading

CSS

Pagespeed has a rule called "Optimize CSS Delivery", that means anything which does not included in first render (i.e. out of screen), it is blocking render speed.

To defer loading of out-of-screen CSS, we can use snippet by Google and put it at the end of body tag:

<noscript id="deferred-styles">
      <link rel="stylesheet" type="text/css" href="<your-css-file>.css"/>
    </noscript>
    <script>
      var loadDeferredStyles = function() {
        var addStylesNode = document.getElementById("deferred-styles");
        var replacement = document.createElement("div");
        replacement.innerHTML = addStylesNode.textContent;
        document.body.appendChild(replacement)
        addStylesNode.parentElement.removeChild(addStylesNode);
      };
      var raf = window.requestAnimationFrame || window.mozRequestAnimationFrame ||
          window.webkitRequestAnimationFrame || window.msRequestAnimationFrame;
      if (raf) raf(function() { window.setTimeout(loadDeferredStyles, 0); });
      else window.addEventListener('load', loadDeferredStyles);
</script>

Moreover, we need to put critical CSS (i.e. in viewport) inline and inside <head>. For example:

<head>
    <style>
      .blue{color:blue;}
    </style>
</head>

JavaScript

For JS, you can try to put defer, async or asynchronously inject script into webpage like this:

const script = document.createElement('script');
script.src = "//example.com/widget.js";
document.getElementsByTagName('head')[0].appendChild(script);

For out-of-screen function, you can set the property to "defer" and put it at the end of body, which means it will load after whole page is rendered. For example:


<!--preload js for important func-->
<link rel="preload" href="script.js" as="script"> 

<!--load after rendered-->
<script src="script.js" defer></script>

<!--will load asynchronously-->
<script src="script.js" async></script>

There are some tools which can help you to automatically add inline CSS, like gulp-inline-source for gulp or critters for webpack.


3. Code Splitting

If the script is not critical and harm your functionality in screen (like fixed menu), you can split them into few files and load them when needed. For webpack or React, you can use the "Code Splitting" function in webpack.

For React, it is even easier to use the new lazy or react-loadable.

Remember to delete or trim unnecessary codes inside your page and serve minimized version to users!

Result

alt="Final Result in PageSpeed"

That page finally get nearly 80 on mobile and nearly perfect in desktop version. It is not very perfect, as mobile's score is definitely have room of improvement.

Do you have any thoughts on this? Welcome to let me know your insights! :)

Discussion (9)

Collapse
ben profile image
Ben Halpern

Great things to focus on

Collapse
imthedeveloper profile image
ImTheDeveloper

Ben I find Dev.to so damn fast even on mobile. What's been the secret here?

Collapse
revskill10 profile image
Truong Hoang Dung

The secret is dev.to saved a bunch of assets to cache storage.

Collapse
snowleo208 profile image
Yuki Cheung Author

Thanks for the reply! This is my first post on dev.to, I didn't expect it would have so many responses! :)

Collapse
emadha profile image
Emad Ha

So i took a loot at view-source:dev.to/snowleo208/three-things-i-l... your own page, and i found that inlined all css in

Would you please explain what do you mean by 'inline critical css' ?

Collapse
snowleo208 profile image
Yuki Cheung Author

Inline Critical CSS means writing styles that needed in first view inside HTML <head> tag.

When user first visit your website, some styles are needed as first priority, like styles of nav, header, first section etc. to display the page beautifully. (And let those styles outside of viewport keeping in external CSS files)

For example, you have a nav bar with class .c-menu, you can write this in HTML file:

<html>
<head>
<!-- write your critical css here -->
<style>
.menu {
  width: 100%
  height: auto;
  color: black;
  padding: 0 1em;
}
</style>
</head>
<body>
<nav class="c-menu">
<!-- Lots of items -->
</nav>
</html>

Since those styles inside <style> tag are embedded inside the HTML, browser can load those styles quickly without loading external CSS files. It can be less "render blocking", compared with putting CSS link in head, like <link rel="stylesheet" type="text/css" href="theme.css">.

To learn more about Render Blocking, view here.

Hope this can clearing up your doubts! :)

Collapse
rsedykh profile image
Roman Sedykh

Hi Yuki,

Thanks for your article (surprisingly there are just a few articles about image optimization here)!

If its ok, can you share your opinion on optimizing images on autopilot? We're building a tool for this, and I'm asking developers about their needs. Just posted an article with an example and a question. :-)

Collapse
yunusemreozcan profile image
yunusemreozcan

You can purchase to Screpy lifetime subscription on AppSumo.

Or you can become a standard member for only $ 2 per month on Screpy.

Collapse
_screpy profile image
Screpy • Edited