二、前端性能优化面试篇章

98 阅读3分钟

1 在浏览器输入url并回车后都发生了什么

https://www.baidu.com
url:统一资源定位符,俗称网址,是IP的一个映射。
https: 传输协议,(http和TCP之间加了一层 TSL或者SSL的安全层)。
www:服务器。
baidu.com: 域名。
三次握手:客户端向服务端发送请求,等待服务端的确认;
服务端收到请求,会进行确认,并回复一个指令;
客户端收到回复指令,会再次回复确认。(在吗? 在。好的。)
第一次访问时,浏览器拿到url后,会先解析url,然后到DNS域名系统中匹配真实的IP。
有了Ip后,通过TCP的三次握手与服务端建立连接,
连接成功后,会拿到数据,然后渲染页面。
最后通过四次挥手断开连接。
第一次访问完后会将域名解析的ip存在本地,所以第二次访问时,会读取浏览器的缓存,查看ip有没有过期等等。

image.png

追问: 浏览器拿到数据后,是如何渲染页面的?

image.png

2 日常开发中从哪些方面做性能优化

加载:
1 减少http请求(精灵图,文件的合并)
2 减小文件大小(资源压缩,图片压缩,代码压缩)
3 CDN(大型资源使用第三方库的链接来引入)
4 SSR服务端渲染,预渲染
5 懒加载
6 分包

性能:
1 减少dom操作,避免回流和重绘,比如使用文档碎片

image.png

image.png

3 懒加载原理

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        * {
            margin: 0;
            padding: 0
        }
        img {
            height: 500px;
        }
    </style>
</head>

<body>
    <!--图片懒加载 -->
    <img src="./img/loading.png" data-src="./img/1.jpeg">
    <img src="./img/loading.png" data-src="./img/2.jpeg">
    <img src="./img/loading.png" data-src="./img/3.jpeg">
    <img src="./img/loading.png" data-src="./img/4.jpeg">
    <img src="./img/loading.png" data-src="./img/5.jpeg">

    <script>
        function throttle (fn, delay) {
            let timer = null
            return function(...args) {
                if (timer) return false
                timer = setTimeout(() => {
                    fn.apply(this, args)
                    timer = null
                    clearTimeout(timer)
                }, delay) 
            }
        }
        const displayImg = (function () {
            const viewHeight = window.innerHeight || document.documentElement.clientHeight
            const imgs = Array.from(document.getElementsByTagName('img'))
            const imgsTotal = imgs.length
            let n = 0
            return function() {
                const scrollTop = document.documentElement.scrollTop || document.body.scrollTop
                for (let i = n; i < imgsTotal; i++) {
                    const item = imgs[i]
                    if (item.offsetTop < viewHeight + scrollTop) {
                        item.setAttribute('src', item.getAttribute('data-src'))
                        n++
                        if (n === imgsTotal) {
                            document.removeEventListener('scroll', imgThrottle)
                        }
                    }
                }
            }
        })()
        throttle(displayImg, 200)()
        const imgThrottle = throttle(displayImg, 200)
        document.addEventListener('scroll', imgThrottle)
    </script>
</body>

</html>

4 面试回答:

前端性能优化是为了更好的用户体验,防止因加载慢、卡顿等问题造成的用户流失。
比如,
1 我们在开发时,
随着项目体积的越来越大,项目打包的时间也就会越来越长,此时可以将项目依赖的第三方库通过外链的方式引入,减少项目体积。
2 在下载资源方面,
如下载静态资源时,尽量让用户访问最近的CDN节点,减少网络传输距离;需要下载的图片进肯能进行压缩,如采用webp格式代替png,同时尽量使用svg代替图片。
在网络传输方面,使用dns-prefetch将需要用到的域名提前解析,并缓存起来;将多个小图合并成一张精灵图,减少http请求;写代码时,避免空链接。
在缓存方面,可以使用localStorage对初始数据进行缓存。
3 在运行时,
可以使用服务端渲染(ssr),可以使用骨架屏来解决白屏问题;遇到多张大图可以使用懒加载+节流等。

补充localStorage/sessionStorage/cookie 的区别

共同点: 都是保存在浏览器端、且同源的。

区别:

  1. cookie 数据始终在同源的http请求中携带(即使不需要),而sessionStorage和localStorage 不会自动把数据发送给服务器,仅在本地保存。
  2. 存储大小也不同,cookie最多4k,(因为每次http请求都会携带cookie,所以cookie适合保存很小的数据,如会话标识)。而sessionStorage 和 localStorage可以达到 5M 或更大。
  3. 数据有效期不同,cookie只在设置的过期时间之前有效;sessionStorage仅在当前浏览器窗口关闭前有效;localStorage始终有效,除非手动清除。
  4. 作用域不同,sessionStorage 不在不同的浏览器窗口中共享,而localStorage和cookie在所有同源窗口中都是共享的。