zoukankan      html  css  js  c++  java
  • 前端优化

    先看一下网页的加载流程:

    1.解析html结构
    2.加载外部脚本和样式表文件
    3.解析并执行脚本(脚本会阻塞页面的加载)
    4.DOM树构建完成 (DOMContentLoaded)
    5.加载图片等外部文件
    6.页面加载完毕 (load事件)

    THE WAY: 减少请求数量、减小请求大小


    减少请求数量
    1.将小图合并成雪碧图(sprite)或者iconfont字体文件
    2.使用base64减少请求(把图片转换成base64)
    3.图片延迟加载
    4.JS/CSS按需打包
    ......

    减小请求大小
    1.JS/CSS/HTML 压缩
    2.gzip压缩
    3.图片压缩、JPG优化
    4.webp优化
    5.JS/CSS按需加载 (require)
    ......

    NEXT讲一下具体的实现


    减少请求数量-->
    1.sprite图
      可以使用构建工具(gulp.spritesmith插件)自动化生成。
    2.base64
      即把小图,没必要发请求的转成base64格式
    3.图片延迟加载
      图片延迟加载的原理就是先不设置img的src属性,等合适的时机(比如滚动、滑动、出现在视窗内等)再把图片真实url放到img的src属性上。
      (1) 固定宽高的图片
      可以使用lazysizes:  

    // 引入js文件
    <script src="lazysizes.min.js" async=""></script>
    
    // 非响应式 例子
    <img src="" data-src="image.jpg" class="lazyload" />
    
    // 响应式 例子,自动计算合适的图片
    <img
    data-sizes="auto"
    data-src="image2.jpg"
    data-srcset="image1.jpg 300w,
    image2.jpg 600w,
    image3.jpg 900w" class="lazyload" />
    // iframe 例子
    <iframe frameborder="0"
    class="lazyload"
    allowfullscreen=""
    data-src="//www.youtube.com/embed/ZfV-aYdU4uE">
    </iframe>  

      (2) 固定宽高比的图片
      不同设备的宽度不同导致高度也相应的不同,所以单个图片从上往下加载完都会有抖动,每次抖动都会造成reflow(重绘),严重影响性能
      对此有两种解决方案:

      1⃣️第一种方案使用padding-top或者padding-bottom来实现固定宽高比。优点是纯CSS方案,缺点是HTML冗余,并且对输出到第三方不友好。

    <div style="padding-top:75%">
        <img data-src="" alt="" class="lazyload">
    <div>

      2⃣️第二种方案在页面初始化阶段利用ratio设置实际宽高值,优点是html干净,对输出到第三方友好,缺点是依赖js,理论上会至少抖动一次。

    <img data-src="" alt="" class="lazyload" data-ratio="0.75">

      那么,这个padding-top: 75%;和data-ratio="0.75"的数据从哪儿来呢?在你上传图片的时候,需要后台给你返回原始宽高值,计算得到宽高比,然后保存到data-ratio上。

      好奇心日报采用的第二种方案,主要在于第一种方案对第三方输出不友好:需要对img设置额外的样式,但第三方平台通常不允许引入外部样式。

      确定第二种方案之后,我们定义了一个设置图片高度的函数:

    // 重置图片高度,仅限文章详情页
    function resetImgHeight(els, placeholder) {
        var ratio = 0,
            i, len, width;
    
        for (i = 0, len = els.length; i < len; i++) {
            els[i].src = placeholder;
    
            width = els[i].clientWidth; //一定要使用clientWidth
            if (els[i].attributes['data-ratio']) {
                ratio = els[i].attributes['data-ratio'].value || 0;
                ratio = parseFloat(ratio);
            }
    
            if (ratio) {
                els[i].style.height = (width * ratio) + 'px';
            }
        }
    }

      我们将以上代码的定义和调用都直接放到了HTML中,就为了一个目的,第一时间计算图片的高度值,降低用户感知到页面抖动的可能性,保证最佳效果。

      注意事项
      1⃣️、避免图片过早加载,把临界值调低一点。在实际项目中,并不需要过早就把图片请求过来,尤其是Mobile项目,过早请求不仅浪费流量,也会因为请求太多,导致页面加载速度变慢。
      2⃣️、为了最好的防抖效果,设置图片高度的JS代码内嵌到HTML中以便第一时间执行。
      3⃣、根据图片宽度设置高度时,使用clientWidth而不是width。这是因为Safari中,第一时间执行的JS代码获取图片的width失败,所以使用clientWidth解决这个问题。

    4.JS/CSS按需打包
      推荐前端构建工具webpack
      http://webpack.github.io/docs/
      好奇心日报是典型的多页应用,为了缓存通用代码,我们使用webpack按需打包的同时,还利用webpack的CommonsChunkPlugin 插件抽离出公用的JS/CSS代码,便于缓存,在请求数量和公用代码的缓存之间做了一个很好的平衡。

    减小请求大小-->
    1.JS/CSS/HTML压缩
      这也是常规手段,就不介绍太多,主要的方式有:
      (1) 通过构建工具实现,比如webpack/gulp/fis/grunt等。
      (2) 后台预编译。
      (3) 利用第三方online平台,手动上传压缩。

      无论是第二种还是第三种方式,都有其局限性,第一种方法是目前的主流方式,凭借良好的插件生态,可以实现丰富的构建任务。
      在好奇心日报的项目中,使用webpack & gulp作为构建系统的基础。
      1⃣️: JS压缩:使用webpack的UglifyJsPlugin插件,同时做一些代码检测。

    new webpack.optimize.UglifyJsPlugin({
        mangle: {
            except: ['$super', '$', 'exports', 'require']
        }
    })

      2⃣️: CSS压缩:使用cssnano压缩,同时使用postcss做一些自动化操作,比如自动加前缀、属性fallback支持、语法检测等。

    var postcss = [
        cssnano({
            autoprefixer: false,
            reduceIdents: false,
            zindex: false,
            discardUnused: false,
            mergeIdents: false
        }),
        autoprefixer({ browers: ['last 2 versions', 'ie >= 9', '> 5% in CN'] }),
        will_change,
        color_rgba_fallback,
        opacity,
        pseudoelements,
        sorting
    ];

      3⃣️: HTML压缩:使用htmlmin压缩HTML。

    // 构建视图文件-build版本
    gulp.task('build:views', ['clean:views'], function() {
        return streamqueue({ objectMode: true },
                gulp.src(config.commonSrc, { base: 'src' }),
                gulp.src(config.layoutsSrc, { base: 'src' }),
                gulp.src(config.pagesSrc, { base: 'src/pages' }),
                gulp.src(config.componentsSrc, { base: 'src' })
            )
            .pipe(plumber(handleErrors))
            .pipe(logger({ showChange: true }))
            .pipe(preprocess({ context: { PROJECT: project } }))
            .pipe(gulpif(function(file) {
                if (file.path.indexOf('.html') != -1) {
                    return true;
                } else {
                    return false;
                }
            }, htmlmin({
                removeComments: true,
                collapseWhitespace: true,
                minifyJS: true,
                minifyCSS: true,
                ignoreCustomFragments: [/<%[sS]*?%>/, 
                                        /<?[sS]*??>/, 
                                        /<meta[sS]*?name="viewport"[sS]*?>/]
            })))
            .pipe(gulp.dest(config.dest));
    });

    2.gzip压缩
      gzip压缩也是比较常规的优化手段。前端并不需要做什么实际的工作,后台配置下服务器就行,效果非常明显。如果你发现你的网站还没有配置gzip,那么赶紧行动起来吧。
      如果浏览器支持gzip压缩,在发送请求的时候,请求头(request Headers)中会带有Accept-Encoding:gzip。然后服务器会将原始的response进行gzip压缩,并将gzip压缩后的response传输到浏览器,紧接着浏览器进行gzip解压缩,并最终反馈到网页上。
      但需要注意,gzip压缩会消耗服务器的性能,不能过度压缩。
      所以推荐只对JS/CSS/HTML等资源做gzip压缩。图片的话,托管到第三方的图片建议开启gzip压缩,托管到自己应用服务器的图片不建议开启gzip压缩。
    3.JS/CSS按需加载
      webpack的require
    4.图片压缩和JPG优化

      https://tinypng.com/ (近乎于无损压缩)

    参考:http://www.jianshu.com/p/d857c3ff78d6

  • 相关阅读:
    点击劫持漏洞之理解 python打造一个挖掘点击劫持漏洞的脚本
    URL重定向漏洞,python打造URL重定向漏洞检测脚本
    动态链接库(DLL)
    vs不支持通过afxgetmainwnd()获取窗口句柄(转)
    HALCON学习-下载、安装
    HALCON学习-资料
    MFC,ADO方式实现数据库操作
    VS2010 EXCEL2010 表格操作的编程实现
    Git Compare with base,比较大文件时,长时间等待,无法加载
    VS2010编译VS2008工程时,LINK : fatal error LNK1123: failure during conversion to COFF: file invalid or corrupt
  • 原文地址:https://www.cnblogs.com/xinxingyu/p/5754055.html
Copyright © 2011-2022 走看看