• 前端新特性


    css特性

    accent-color修改表单颜色

    • 新增CSS属性accent-color,用于修改表单元素的颜色
    • 表单元素例如 等,它们的样式是由用户代理样式表(user agent stylesheet)决定的,各自浏览器的实现都不一样。
    ::root {
      accent-color: deeppink;
    }
    
    • 1
    • 2
    • 3

    在这里插入图片描述

    aspect-ratio宽高比

    • 值得注意的是aspect-ratio的优先级比较低。当aspect-ratio和其他属性例如width height 、min-width 、min-height产生了冲突的话,会以后者为准。
    .container img {
      width: 100%;
      aspect-ratio: 16 / 9;
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5

    size-adjust调整字体大小,让不同字体获得一致的表现

    @font-face {
      font-family: "Size Adjusted Arial";
      src: local(Arial);
      size-adjust: 150%;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    @layer控制层级权重

    • 未使用层的样式优先级高于使用了层的样式
    • 层的声明顺序代表了层的优先级。越后声明的层优先级越高
    @layer layer_name {
      h1 {
        color: blue;
      }
    }
    //创建匿名层
    @layer {
      h1 {
        color: blue;
      }
    }
    //先声明再定义
    @layer base;
    
    @layer base {
      ...
    }
    //一次性声明多个层
    @layer theme, layout, utilities;
    
    //@import导入文件时创建层
    @import './theme.css' layer(theme);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 示例
    /* 预先建立层顺序,从最低到最高优先级 */
    @layer reset, theme, components, utilities;
    
    /* 重置 */
    @layer reset {}
    
    /* 主题样式 */
    @layer theme {}
    
    /* 组件样式 */
    @layer components {}
    
    /* 功能样式 */
    @layer utilities {}
    
    //===其他文件使用==================================================
    /* 预先定义层的顺序 */
    @layer base,
           theme,
           layouts,
           components,
           utilities;
    
    /* Base */
    @import '../styles/base/normalize.css' layer(base); /* normalize or rest file */
    @import '../styles/base/base.css' layer(base); /* body and base styles */
    @import '../styles/base/theme.css' layer(theme); /* theme variables */
    @import '../styles/base/typography.css' layer(theme); /* theme typography */
    @import '../styles/base/utilities.css' layer(utilities); /* base utilities */
    
    /* Layouts */
    @import '../styles/components/post.css' layer(layouts); /* post layout */
    
    /* Components */
    @import '../styles/components/cards.css' layer(components); /* imports card */
    @import '../styles/components/footer.css' layer(components); /* footer component */
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    css优化

    contain优化回流重绘(页面渲染)

    contain有如下值:
    layout:该元素的内部布局与页面的其他部分完全隔离,内部不受外界任何东西的影响,同时也影响不了外部。
    paint:内部元素的绘制不会超出该元素,超出的部分会不可见。
    size:该元素的渲染不用去检测内部元素,即跟内部元素的尺寸无关。
    style(不常用):设置 counters 和 quotes两个属性不会影响到外部。
    
    还有另外两个值,是其他属性的组合:
    content: layout + paint的结合
    strict: layout + paint + size的结合
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 假如页面中有10000个元素,修改了最后一个元素的内容,如果你给每个元素加上 contain: strict属性,那么浏览器只需要重绘你修改的元素
      在这里插入图片描述

    content-visibility按需渲染

    • 设置content-visibbily属性可以暂时跳过元素的渲染(包括布局和绘制),直到它需要被用到的时候再进行渲染。
    • 通过这个属性,我们可以实现优先渲染首屏内容,页面其他部分先暂停渲染,这样可以极大地加速首屏展示时间,让用户更快体验到页面。
    • 在离屏时只是不会渲染,但是可以通过DOM API或者网页搜索功能找到。
    content-visibility:visible;	默认值,不产生影响,元素正常渲染。
    content-visibility:hidden;	该元素内容会被跳过。
    content-visibility:auto;	当元素不可见(且没有交互操作)时会跳过元素内容的渲染,需要的时候再渲染。
    
    • 1
    • 2
    • 3
    • 和其它隐藏样式的区别:
      • display: none:DOM树中移除该元素,layout和paint都不参与。缺点是切换到展示状态时需要的代价较大。
      • visibility: hidden:DOM树中保留该元素,且会参与layout,只是在图形绘制上隐藏。切换到展示状态需要的代价较低。但是由于该元素需要参与layout,内容变更时会影响到外部,所以总体页面的渲染耗时并没有减少。
      • content-visibility: hidden:DOM树中保留该元素,不参与 layout和paint,页面渲染时会跳过该元素。但是它可以保留渲染状态,切换到展示状态时的代价很低。

    web特性

    dialog原生组件对话框

    <dialog id="dialog">
      <form method="dialog">
        <p>Hi, I'm a dialog.</p>
        <button>OK</button>
      </form>
    </dialog>
    
    <button onclick="dialog.showModal()">Open Dialog</button>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 默认元素是隐藏的,可以通过设置HTML属性open=true,或者使用 .show()和.showModal()来展示对话框内容。
    • 如果元素里有表单元素并且设置了method=dialog,那么提交form表单时会关闭对话框并且把表单内容作为返回值。

    datetime-local原生日期组件

    <input type="datetime-local">
    
    • 1

    在这里插入图片描述

    WebAuthn浏览器上进行认证的 API

    • WebAuthn 采用的是非对称加密的认证方式,服务端储存的是公钥,对应的私钥由客户端保管。
    • 用户不需要记忆密码,可以借助设备的生物认证传感器直接登录。
    • 注册阶段
    const publicKeyCredentialCreationOptions = {
        challenge: Uint8Array.from(
            randomStringFromServer, c => c.charCodeAt(0)),
        rp: {
            name: "Duo Security",
            id: "duosecurity.com",
        },
        user: {
            id: Uint8Array.from(
                "UZSL85T9AFC", c => c.charCodeAt(0)),
            name: "lee@webauthn.guide",
            displayName: "Lee",
        },
        pubKeyCredParams: [{alg: -7, type: "public-key"}],
        authenticatorSelection: {
            authenticatorAttachment: "cross-platform",
        },
        timeout: 60000,
        attestation: "direct"
    };
    
    const credential = await navigator.credentials.create({
        publicKey: publicKeyCredentialCreationOptions
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 认证阶段
    const publicKeyCredentialRequestOptions = {
        challenge: Uint8Array.from(
            randomStringFromServer, c => c.charCodeAt(0)),
        allowCredentials: [{
            id: Uint8Array.from(
                credentialId, c => c.charCodeAt(0)),
            type: 'public-key',
            transports: ['usb', 'ble', 'nfc'],
        }],
        timeout: 60000,
    }
    
    const assertion = await navigator.credentials.get({
        publicKey: publicKeyCredentialRequestOptions
    });
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    Top level await

    • 可以不使用async,直接在顶层使用await
    • 但会存在一个坑:如果顶层文件使用了await,那么像DOMContentLoaded这种写在内部的生命周期可能会因为异步阻塞没有触发,并且很难找到是在其他文件顶层使用了Top level await
    await Promise.resolve(console.log('🎉'));
    
    • 1

    SharedArrayBuffer

    • SharedArrayBuffer即共享内存,可用于Web Worker和WebAssembly的场景。
      • Web worker 与JS主线程的数据都是隔离的,通过postMessage()通信,传递的数据都需要被复制一份,数据量大时通信效率很低。SharedArrayBuffer允许 Worker 线程与主线程共享同一块内存。将数据写入SharedArrayBuffer后只需要传递内存地址即可。
      • 使用WebAssembly时,wasm初始化时会向SharedArrayBuffer申请共享内存,通过传递指针的方式与JS进行数据交换
    • 主线程
    // 新建 1KB 共享内存
    const sharedBuffer = new SharedArrayBuffer(1024);
    // 主线程将共享内存的地址发送出去
    w.postMessage(sharedBuffer);
    // 在共享内存上建立视图,供写入数据
    const sharedArray = new Int32Array(sharedBuffer);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • Worker 线程:
    // Worker 线程
    onmessage = function (ev) {
      // 主线程共享的数据,就是 1KB 的共享内存
      const sharedBuffer = ev.data;
      // 在共享内存上建立视图,方便读写
      const sharedArray = new Int32Array(sharedBuffer);
      // ...
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    web优化

    Back/forward cache页面缓存

    • Chrome浏览器的一项优化。页面在离开时会先被缓存,浏览器前进或者后退操作时能直接使用。Firefox和Safari 也支持
    • 在进入和离开页面时会触发事件pageshow和pagehide,并且加了persisted属性来区分是页面是否使用bfcache

    loading="lazy"懒加载