前端的优化与JQuery懒加载

前端优化

做前端的时候,把实现不了的效果切换成图片还有一些图标也会切成图片,会降低前端页面展示的性能,增加页面资源HTTP的请求负担,甚至有的页面存在几十个imghttp请求 。

1、降低图片的大小

首先我们目前常用的图片格式有png,gif,jpg等
是降低图片的大小kb,有很多方法可以做,压缩图片,选择更小kb的图片格式,以达到最优的显示效果

  • 智图:一个图片优化平台
  • https://tinypng.com/

前端的优化与JQuery懒加载_第1张图片

2、选择适当的图片宽度尺寸(即响应式图片)

不管是pc还是移动端,都会有很多不同尺寸的图片,如果你做的是响应式网站和移动端的话,那么你就更需要考虑图片尺寸的选择问题了

移动端的屏幕分辨率和尺寸太多,所以就可能需要不同的尺寸加载不同尺寸的图片,这样就节省了网站的访问流量,以及页面渲染的效率比如PC的版心都是1200左右,如果在手机上肯定是不需要这么大的,这个时候就。。。。
先展示现在设备的分辨率等的图

3、减少HTTP的网络资源请求

CSSSprites(背景精灵图/雪碧图)

一种网页图片应用处理方式,将一个页面涉及到的所有零星图片或者图标都包含到一张大图里面,这样就只需要加载这个一个图片,而不是很多个图片了,这样就减少了很多http的请求。

4、字体图库代替图标

随着技术的更新和浏览器的更新,字体图库去代替一些图标我认为还是极好的,使用字体图库你不仅可以改变大小,而且还可以改变颜色
比较熟知的的字体图库有很多,

  • font-awesom
  • icoMoon

5、图片延迟加载(懒惰加载)

一、什么是图片滚动加载?

通俗的讲就是:当访问一个页面的时候,先把img元素或是其他元素的背景图片路径替换成一张大小为1*1px图片的路径(这样就只需请求一次),只有当图片出现在浏览器的可视区域内时,才设置图片正真的路径,让图片显示出来。这就是图片懒加载。

二、为什要使用这个技术?

比如一个页面中有很多图片,如淘宝、京东首页等等,如果一上来就发送这么多请求,页面加载就会很漫长,如果js文件都放在了文档的底部,恰巧页面的头部又依赖这个js文件,那就不好办了。更为要命的是:一上来就发送百八十个请求,服务器可能就吃不消了(又不是只有一两个人在访问这个页面)。

我们可以通过给img自定义一个新属性,来存储图片真实的src地址,当需要加载的时候,再将这个真实的地址赋给src,进行图片加载。

  • 能有效的提高页面加载速度
  • 有时候可以帮助减少服务器负载

懒加载

1、整体思路:

所以大体的思路为:

  • 设置个data-src(自定义一个属性)来存放真实地址
  • 当滚动页面时,检查所有的img标签,看是否出现在视野中,如果已经出现在了视野中,那继续再进行判断,看其是否已经被加载过了,如果还没有被加载过,那就进行加载。

想到这一步,整体的大概思路(demo.html):

2、 判断目标标签是否出现在视野中:

此时,判断目标标签是否已经出现在视野中的思路为:
分析标签出现在页面中的两个临界状态:

  • 当页面向上滚动,一直滚到首先出现在页面的下边缘的时候,此时有页面向上滚动的距离,加上浏览器自身的高度就等于目标标签本身在页面中距离页面顶部的距离

  • 页面接着向上滚,当页面出现在了浏览器的上边沿的时候,此时页面向上滚的高度就等于目标标签本身在页面中距离页面顶部的距离

    那么可以checkShow函数可以写为:
    .offset()方法允许我们检索一个元素 (包含其 border 边框,不包括 margin) 相对于文档(document)的当前位置。
    .offset()返回一个包含top 和 left属性的对象 。表示相对于顶部或者左边的坐标。

    // 传入一个img的jq对象
    function checkShow($img) {
        //即页面向上滚动的距离,$(window) 就是你浏览的当前浏览器的窗口 
        var scrollTop = $(window).scrollTop();
        // 浏览器自身的高度
        var windowHeight = $(window).height();
        //目标标签img相对于document顶部的位置
        var offsetTop = $img.offset().top;
        //在2个临界状态之间的就为出现在视野中的
        if (offsetTop < (scrollTop + windowHeight) && offsetTop > scrollTop) { 
            return true;
        }
        return false;
    }

3、判断目标标签是否已经被加载过:

    function isLoaded ($img) {
        //如果data-src和src相等那么就是已经加载过了
        return $img.attr('data-src') === $img.attr('src');
    }

4、加载目标标签

    function loadImg ($img) {
        $img.attr('src',$img.attr('data-src'));
        // 加载就是把自定义属性中存放的真实的src地址赋给src属性
    }

5、优化代码

  • 解决第一次进入页面无加载的问题(第1次优化.html)

首先有个明显的问题,目前页面上,第一次进来的时候如果不滚动滚轮的话什么都看不到,想修复这个问题,可以先进行一次页面检查,调用checkShow(),然后页面上在视野中的标签就会被加载,然后再进行监听window的scroll事件。

<head>
    <meta charset="UTF-8">
    <title>图片懒加载-简单title>
    <script src="../js/jquery-1.8.3.js">script>
    <style>
        ul,li {
            list-style: none;
        }
        .container {
            width: 600px;
            margin: 0 auto;
        }

        .container li {
            float: left;
            margin: 10px 10px;
        }

        .container li img {
            width: 240px;
            height: 180px;
        }

        p {
            float: left;
        }
    style>
head>

<body>
    <ul class="container">
        <li><a href="#"><img src="" data-src="../images/01.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/02.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/03.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/04.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/05.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/06.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/07.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/08.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/09.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/10.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/11.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/12.png" />a>li>
        <li><a href="#"><img src="" data-src="../images/13.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/14.png" />a>li>
        <li><a href="#"><img src="" data-src="../images/15.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/16.jpg" />a>li>

    ul>
    <script> 
        // 必须手动先先进行一次检查才行
        $('.container img').each(function () {
            if (checkShow($(this)) && !isLoaded($(this))) {
                loadImg($(this));
            }
        });

        $(window).on('scroll', function () {
            //当页面滚动的时候绑定事件 
            $('.container img').each(function () {//遍历所有的img标签 
                if (checkShow($(this)) && !isLoaded($(this))) { // 需要写一个checkShow函数来判断当前img是否已经出现在了视野中
                    //还需要写一个isLoaded函数判断当前img是否已经被加载过了 
                    loadImg($(this));
                    //符合上述条件之后,再写一个加载函数加载当前img 
                }
            })
        });

        function checkShow($img) { // 传入一个img的jq对象 
            var scrollTop = $(window).scrollTop(); //即页面向上滚动的距离 
            var windowHeight = $(window).height(); // 浏览器自身的高度
            var offsetTop = $img.offset().top; //目标标签img相对于document顶部的位置 
            if (offsetTop < (scrollTop + windowHeight) && offsetTop > scrollTop) { //在2个临界状态之间的就为出现在视野中的 
                return true;
            }
            return false;
        }

        function isLoaded($img) {
            return $img.attr('data-src') === $img.attr('src'); //如果data-src和src相等那么就是已经加载过了 
        }

        function loadImg($img) {
            $img.attr('src', $img.attr('data-src')); // 加载就是把自定义属性中存放的真实的src地址赋给src属性 
        }
    script>
body>
  • 代码去重(第2次优化.html)

但是此时代码有重复的,进行优化。将重复的代码块写成一个新的函数。进行替换。

<head>
    <meta charset="UTF-8">
    <title>图片懒加载-简单title>
    <script src="../js/jquery-1.8.3.js">script>
    <style>
        ul, li {
            list-style: none;
        }

        .container {
            width: 600px;
            margin: 0 auto;
        }

        .container li {
            float: left;
            margin: 10px 10px;
        }

        .container li img {
            width: 240px;
            height: 180px;
        }

        p {
            float: left;
        }
    style>
head>

<body>
    <ul class="container">
        <li><a href="#"><img src="" data-src="../images/01.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/02.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/03.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/04.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/05.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/06.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/07.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/08.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/09.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/10.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/11.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/12.png" />a>li>
        <li><a href="#"><img src="" data-src="../images/13.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/14.png" />a>li>
        <li><a href="#"><img src="" data-src="../images/15.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/16.jpg" />a>li>

    ul>
    <script> 
        // 先进行一次检查
        //去掉多余的部分,降低耦合性
        lazyRender();

        $(window).on('scroll', function () {
            console.log('运行了一次');
            lazyRender();
        });

        function lazyRender() {
            $('.container img').each(function () {
                if (checkShow($(this)) && !isLoaded($(this))) {
                    loadImg($(this));
                }
            })
        }

        function checkShow($img) { // 传入一个img的jq对象 
            var scrollTop = $(window).scrollTop(); //即页面向上滚动的距离 
            var windowHeight = $(window).height(); // 浏览器自身的高度
            var offsetTop = $img.offset().top; //目标标签img相对于document顶部的位置 
            if (offsetTop < (scrollTop + windowHeight) && offsetTop > scrollTop) { //在2个临界状态之间的就为出现在视野中的 
                return true;
            }
            return false;
        }

        function isLoaded($img) {
            return $img.attr('data-src') === $img.attr('src'); //如果data-src和src相等那么就是已经加载过了 
        }

        function loadImg($img) {
            $img.attr('src', $img.attr('data-src')); // 加载就是把自定义属性中存放的真实的src地址赋给src属性 
        } 
    script>
body>
  • 代码的事件性能优化(第3次优化.html)

代码优化已经很好了,对于性能的优化:

$(window).on(‘scroll’,function () {}这个事件鼠标滚动的时候触发次数非常多。对性能影响大,优化思路是当鼠标滚轮停止滚动的时候,再去判定是否存在在视野中,而不是滚动过程中一直触发。

<head>
    <meta charset="UTF-8">
    <title>图片懒加载-简单title>
    <script src="../js/jquery-1.8.3.js">script>
    <style>
        ul, li {
            list-style: none;
        }

        .container {
            width: 600px;
            margin: 0 auto;
        }

        .container li {
            float: left;
            margin: 10px 10px;
        }

        .container li img {
            width: 240px;
            height: 180px;
        }

        p {
            float: left;
        }
    style>
head>

<body>
    <ul class="container">
        <li><a href="#"><img src="" data-src="../images/01.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/02.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/03.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/04.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/05.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/06.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/07.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/08.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/09.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/10.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/11.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/12.png" />a>li>
        <li><a href="#"><img src="" data-src="../images/13.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/14.png" />a>li>
        <li><a href="#"><img src="" data-src="../images/15.jpg" />a>li>
        <li><a href="#"><img src="" data-src="../images/16.jpg" />a>li>
    ul>
    <script> 
        // 先进行一次检查
        lazyRender();
        //为了不在滚轮滚动过程中就一直判定,设置个setTimeout,等停止滚动后再去判定是否出现在视野中。
        var clock; //这里的clock为timeID, 返回一个 ID(数字),可以将这个ID传递给 clearTimeout() 来取消执行。
        $(window).on('scroll', function () {
            //        lazyRender();
            if (clock) { //只要在300毫秒内触发滚动事件,都会被clearTimeout掉,setTimeout不会执行。
                    //如果有300毫秒外的操作,会得到一个新的timeID即clock,会执行一次setTimeout,然后保存这次setTimeout的ID,
                    //对于300毫秒内的scroll事件,不会生成新的timeID值,所以会一直被clearTimeout掉,不会执行setTimeout.

                clearTimeout(clock);
                // console.log(clock, 1111);
            }

            clock = setTimeout(function () {
                console.log('运行了一次');
                lazyRender();
            }, 300)
        });

        function lazyRender() {
            $('.container img').each(function () {
                if (checkShow($(this)) && !isLoaded($(this))) {
                    loadImg($(this));
                }
            })
        }

        function checkShow($img) { // 传入一个img的jq对象 
            var scrollTop = $(window).scrollTop(); //即页面向上滚动的距离 
            var windowHeight = $(window).height(); // 浏览器自身的高度
            var offsetTop = $img.offset().top; //目标标签img相对于document顶部的位置 
            if (offsetTop < (scrollTop + windowHeight) && offsetTop > scrollTop) { //在2个临界状态之间的就为出现在视野中的 
                return true;
            }
            return false;
        }

        function isLoaded($img) {
            return $img.attr('data-src') === $img.attr('src'); //如果data-src和src相等那么就是已经加载过了 
        }
        function loadImg($img) {
            $img.attr('src', $img.attr('data-src')); // 加载就是把自定义属性中存放的真实的src地址赋给src属性 
        } 
    script>
body>

总结:懒加载是一种独特而又强大的数据获取方法,它能够在用户滚动页面的时候自动获取更多的数据,而新得到的数据不会影响原有数据的显示,同时最大程度上减少服务器端的资源耗用。

你可能感兴趣的:(JavaScript)