zoukankan      html  css  js  c++  java
  • JS代码指导原则

    一.什么是平稳退化?

    如果含有JS代码的网页在用户浏览器不支持JS(或者禁用JS)时,用户仍然能够顺利浏览(网站功能正常,只是视觉效果可能差一些),那么这个网页就能够平稳退化

    网页能够平稳退化是很必要的,因为JS向来名声不好(各种广告,各种弹窗,甚至还有XSS等等阴暗的东西),所以有一个用户群是习惯禁用浏览器的JS支持的,这个用户群可能不大,但是作为编码人员应该尽量让自己的代码尽可能的完善(就像培养自己的孩子一样),我们应该考虑到这种情况,给各种用户完美的体验

    如果上面的理由还不够充分,那么可能有一点更值得重视:SEO,也就是搜索引擎优化,想让自己的网站在搜索结果里靠前些,就有必要做好SEO,搜索引擎的搜索机器人无法理解JS代码的含义,所以搜索机器人相当于一个坚持使用老式浏览器(不支持JS)的用户,显然,这个用户很重要

    二.怎样才能平稳退化?

    要平稳退化只需要遵循一个原则:渐进增强

    所谓的“渐进增强”就是用一些原始的可靠的方法去实现最基本最重要的功能,先保证功能的完整,再用一些额外的信息层去包裹原始页面(实现显示特效,实现更好的视觉效果和用户体验),即便衣服被屏蔽了,功能仍然完整,只是可能不好看而已

    把JS代码与HTML代码彻底分离就可以实现“渐进增强”,HTML是功能完整的原始层,外部JS代码是一个华丽的外衣(说起来有点像CSS,不过确实是这样,JS功能很强大,但如果过分依赖于JS代码就颠倒了主次)

    三.什么是向后兼容?

    向后兼容是指JS代码要能够兼容低版本的DOM(有些浏览器可能不支持最新版本的DOM,意味着某些DOM API将无法使用),例如:

    最常用的DOM API可能是这些:

    document.getElementById();
    document.getElementsByTagName();
    document.getElementsByClassName();//HTML5 DOM中的新特性
    

    但可能有的浏览器根本不支持这些方法,或者说只支持一部分,那么页面将因为JS代码出错而无法访问,或者页面功能不再完整

    之前有一种用来保证向后兼容的方法是“浏览器嗅探”技术,也就是通过BOM去问浏览器:“你支持不支持这个DOM API?”,因为浏览器实在太多了,所以一句很简单的JS代码都需要被很多层浏览器嗅探代码包裹起来,导致我们的代码变得非常臃肿

    浏览器嗅探技术其实在CSS中依然存在,当然CSS无法通过BOM获取浏览器特征,所以采用了相对被动的一种方式:

    /*设置透明度为0.75*/
    filter: alpha(opacity =   25); /*支持 IE 浏览器*/
    -moz-opacity: 0.25; /*支持 FireFox 浏览器*/
    opacity: 0.25; /*支持 Chrome, Opera, Safari 等浏览器*/
    

    DOM发展到现在已经不需要用浏览器嗅探技术来保证向后兼容了,我们可以这样做:

    if(document.getElementById){
        document.getElementById();
    }
    if(document.getElementsByTagName){
        document.getElementsByTagName();
    }
    if(document.getElementsByClassName){
        document.getElementsByClassName();//HTML5 DOM中的新特性
    }
    

    这种更好的方式叫做“对象检测”技术,虽然还是不太完美(要想完美,除非浏览器市场被大一统了..),不过已经比浏览器嗅探要好很多了(至少不需要因为市场上出现一种新的浏览器而修改JS代码),对象检测不再依赖BOM,靠DOM自己检测浏览器是否支持指定的DOM API

    四.JS性能优化技巧

    1. 尽量少JS访问DOM
    2. 尽量减少HTML标记
    3. 合并JS脚本
    4. script标签的位置
    5. 压缩JS代码

    1.优化前:

    for(var i = 0;i < document.getElementsByTagName("a");i++){
        if(document.getElementsByTagName("a")[i].getAttribute("title") == "main"){
            //do something
        }
    }
    

    优化后:

    var elems = document.getElementsByTagName("a");
    for(var i = 0;i < elems.length;i++){
        if(elems[i].getAttribute("title") == "main"){
            //do something
        }
    }
    

    每次调用DOM方法获取标签对象内部都是对DOM树做一次完全搜索,这是非常昂贵的操作,尽量减少DOM访问可以提高性能

    2.优化前:

    <div>
        <div>
            <div>
                <div>
                    <div>
                        <p>
                        正文
                        </p>
                    </div>
                </div>
            </div>
        </div>
    </div>
    

    优化后:

    <p>
    正文
    </p>
    

    这个例子可能有些极端了,不过也足够说明问题了,HTML代码应该尽量简洁(能够达到预期的表现效果就好)

    3.优化前:

    <scrpit src="./scripts/A.js" type="text/javascript"></script>
    <scrpit src="./scripts/B.js" type="text/javascript"></script>
    <scrpit src="./scripts/C.js" type="text/javascript"></script>
    

    优化后:

    <scrpit src="./scripts/All.js" type="text/javascript"></script>
    

    浏览器在加载页面时每遇到一个script标签,如果标签指向外部脚本文件,都需要发送请求加载外部文件,如果script标签过多,这笔开销将是无法忽视的,所以应该把JS代码全部放在一个外部文件中,用一个script标签来加载

    4.优化前:

    <head>
        <script></script>
    </head>
    

    优化后:

    <body>
        html code
    
        <script></script>
    </body>
    

    也就是说把script标签放在body的末尾加载最快,而且放在这里并不影响window.onload等事件的触发,至于为什么放在这个位置最快,可能和浏览器解释HTML代码的顺序有关(先加载head部分,如果head太大,会导致用户等待了很久仍然看不到body内容)

    5.优化前:

    var elems = document.getElementsByTagName("p");
    for(var i = 0;i < elems.length;i++){
        //do something
    }
    

    优化后:

    var elems=document.getElementsByTagName("p");for(var i=0;i<elems.length;i++){}
    

    嗯,没错,优化后的代码不是给人读的,不过虽然不易读,但这样的代码体积小,使得外部文件体积缩小,当然能够提高性能

    P.S.这个工作有专门的工具来帮我们做,比如JSMin等等

    参考资料:《JavaScript DOM变编程艺术》

  • 相关阅读:
    java 8 stream sql left join =》 jooq & Flink & Scala
    Maven error: lambda expressions are not supported in -source 1.7
    error C2039: 'SetWindowTextA' : is not a member of 'CString'
    循环队列(循环数组)中元素个数的计算
    数据结构之堆
    理解C语言声明的优先级规则
    内联汇编中的asm和__asm__
    程序启动时的堆栈
    局部变量与堆栈
    BCD码干什么用的?
  • 原文地址:https://www.cnblogs.com/ayqy/p/4115953.html
Copyright © 2011-2022 走看看