整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          Web前端性能優化:html、css、js篇

          我想死你們啦~

          今天給大家帶來前端面試必會問到的前端性能優化問題,暫定分三期給大家帶來,第一期講述基本的代碼優化,后續還有網絡傳輸層優化和頁面加載速度優化,敬請期待,也歡迎點擊查看原文了解更多前端小知識。

          點關注,不迷路,我們一起咸魚翻個身兒。

          正文

          為什么要進行性能優化?

          • 用戶: 提升用戶體驗,改善頁面性能。
          • 開發者: 體現公司意志和開發人員技能。

          性能優化的總體方向

          • 高效 :合理安排資源
          • 快速 :減少等待時間
          • 標準 :
          • 首次有效繪制(First Meaningful Paint,簡稱FMP,當主要內容呈現在頁面上)
          • 英雄渲染時間(Hero Rendering Times,度量用戶體驗的新指標,當用戶最關心的內容渲染完成)
          • 可交互時間(Time to Interactive,簡稱TTI,指頁面布局已經穩定,關鍵的頁面字體是可見的,并且主進程可用于處理用戶輸入,基本上用戶可以點擊UI并與其交互)
          • 輸入響應(Input responsiveness,界面響應用戶輸入所需的時間)
          • 感知速度指數(Perceptual Speed Index,簡稱PSI,測量頁面在加載過程中視覺上的變化速度,分數越低越好)

          1.1、HTML/CSS優化

          1、能用html/css解決的問題就不要用js,更快的開發速度,更小的維護成本。

          適用場景:

          //導航高亮
          nav li {
           opacity: 0.5;
          }
          nav li:hover {
           opacity: 1;
          }
          //鼠標懸停顯示模塊
          .menu {
           display: none;
          }
          .nav:hover + .menu {
           display: inline-block;
          }
          .menu:before {
           content: '';
           position: absolute;
           top: -20px;
           left: 0px;
           width: 100%;
           height: 20px;
          }
          

          2、自定義radio/checkbox樣式

          input[type=checkbox]{}
          input[type=checkbox]:checked{}
          

          3、巧用css偽類,合理使用原生選擇器,如::focus、@media、input[type=email]:invalid

          4、使用全局樣式sass、scss

          5、優化HTML標簽

          • 文字<p> 、<h1>減少css代碼
          • 表單<form>
          • 列表<ol>、<ul>
          • 圖片<img>、<picture>
          • 鏈接<a>、<button>
          • 根據情況使用input type值
          • 使用HTML5語義化標簽
          //一個語義化的網頁布局
          <nav></nav>
          <header></header>
          <main>
           <section></section>
           <section></section>
          </main>
          <footer></footer>
          

          6、不濫用高消耗的樣式

          • box-shadow、border-radius、float需要瀏覽器進行大量的計算,應減少使用

          7、選擇器合并

          • 把有共同的屬性內容的一系列選擇器組合到一起,能壓縮空間和資源開銷

          8、 0值去單位

          • 對于為0的值,盡量不要加單位,增加兼容性

          1.2、JS優化

          1、減少前端代碼耦合

          • 使用傳參的方法減少耦合
          • 利用策略模式抽離公共組件、參數、封裝請求

          2、JS書寫優化

          • 按照強類型風格去寫代碼,指明變量類型和返回類型
          • 字面量與局部變量的訪問速度最快,數組元素和對象成員相對較慢
           //bad
           let num,
           str,
           obj;
           //good
           let num = 0;
           str = '',
           obj = null;
           //bad
           getPrice:function(price){
           if (price < 0) {
           return false;
           }else {
           return price * 10
           }
           }
           //good
           getPrice:function(price){
           if (price < 0) {
           return -1;
           }else {
           return price * 10
           }
           }
           //類型確定,解析器不會去做一些額外的的工作,類型不確定的情況下回發生優化回滾
           //優化回滾:編譯器已經編譯完成函數,類型變化導致回滾到通用狀態,重新生成函數
          

          3、減少作用域查找

          • 盡量少的不要讓代碼暴露在全局作用域下,變量從局部作用域到全局作用域的搜索過程越長速度越慢
           //bad
           <script>
           var map = document.querySelector('#imap');
           map.style.height = '10px';
           </script>
           //good
           <script>
           !function() {
           var map = document.querySelector('#imap');
           map.style.height = '10px';
           }
           </script>
          

          4、對象嵌套的越深,讀取速度就越慢

          • 無意義的對象嵌套拖累讀取速度

          5、避免 == 的使用

          • 確定類型的情況下直接使用 ===

          6、合并表達式

          • 用三目運算符代替簡單的if-else
           //bad
           function getPrice(count){
           if(count < 0){
           return -1;
           }else {
           return count * 100;
           }
           }
           //good
           function getPrice(count){
           return count <0 ? return -1 : count * 100;
           }
           //在進行代碼壓縮的時候,即時書寫的是if-else,壓縮工具也會幫你把它改成三目運算符的形式
          

          1.3、使用ES6簡化代碼

          1、使用箭頭函數取代小函數

           var num = [4,6,8,3,1,0]
           //bad
           num.sort(function (a,b){
           return a-b;
           })
           //good
           num.sort(a,b => a-b);
           ```
           * 使用ES6的class
           ```
           class Person {
           constructor(name, age) {
           this.name = name;
           this.age = age;
           }
           addAge() {
           this.age++;
           }
           setName(name) {
           this.name = name;
           }
           }
          

          2、字符串拼接

           let url = `/list.html?page=${page}&type=${type}`;
          

          3、塊級作用域變量,使用let代替var


          尾聲

          總結的內容到這里差不多就結束了,大多數來自工作中的一些總結和整理。文中若有不當之處,歡迎指出共同交流~~

          orm表單復雜demo制作與涉及到的方法講解,深入理解form基本屬性與使用方法

          天給大家帶來的是新浪微博PC端的模擬登陸。

          工具

          這次使用的工具是Charles和chrome瀏覽器,看過我之前文章的同學應該知道我使用的Mac電腦,Fiddler不能用,之前用虛擬機很麻煩。很早的時候有裝過Charles,但是不太會用,后來發現一篇比較詳細的文章,忘了記錄了。發現Charles還是非常好用的,而且有個很好的功能,就是可以開啟多個Session進行抓取對比,這個功能非常,如果經常做爬蟲調試的人一定能知道。我們抓取一個網站的登錄過程,然后在模擬的過程中,可以再另一個session中抓取自己模擬登錄的過程,然后對比一下自己的請求發送的數據和瀏覽器請求發送的數據是否一致。之前我調試一直都是通過打印查看,這樣一方面很不方便,另外一方面打印也不完整。所以非常推薦大家使用Charles,網上破解也有很多。

          Charles

          打開Charles,要開啟SSL代理抓取,這樣才能抓取到HTTPS請求,畢竟現在很多網站都已經使用HTTPS請求了

          HTTPS抓取設置

          Host填*表示匹配所有網址,HTTP請求端口是80端口,HTTPS請求端口是443端口,設置好就可以開始抓取了。

          抓取請求

          打開chrome瀏覽器,最好清理緩存,然后使用隱身模式訪問https://weibo.com/

          打開隱身窗口

          無痕模式

          在網頁上執行一遍登錄操作

          微博登錄過程

          抓取到登錄過程后,我們就可以開始分析了,記住一定要清理緩存。我有好幾次抓取都不一樣,后來換了Safari瀏覽器(因為我很少用這個),其實這一步用什么瀏覽器都無所謂,chrome瀏覽器主要是用來調試JS用的。

          過程分析

          查找登錄請求

          登錄一般url里面應該都會有login,而且是post請求,當然不排除其他方式。

          https://login.sina.com.cn/sso/login.php?client=ssologin.js(v1.4.19)

          登錄請求url

          找到登錄請求后,這里主要關注Form表單信息,參數很多,我們需要先大概區分一下哪些可能是固定參數,哪些是變化的參數。

          參數確定

          一目了然可以看到那些是固定的了吧,這些所有的參數其實我們都是可以追根溯源的,但是沒那個必要,在這種參數比較多的情況下,太費事了,可以采用多次抓取登錄過程,對比請求參數的方式確定部分固定的或者不重要的參數,那么需要我們通過其他方式獲取的參數有pcid、door、su、servertime、nonce、rsakv、sp、prelt,這里servertime比較有爭議,一般看到這種time或者151開頭的10位或者13位數字,都是時間戳,用time.time()獲取就可以,但是這里是servertime,我們應該引起注意。

          參數分析

          下面我們一一來看這幾個參數怎么獲取

          • su
          • 我們要先說一下這個su,因為其他的參數都和它有關系。這個su在js調試的時候可以看到它的算法,但是其實我們可以根據它的特點先猜測一下,有可能是base64加密的。為什么?
          Base64是一種基于64個可打印字符來表示二進制數據的方法,哪64個字符呢? 
          A-Z、a-z、0-9和"+"、"/",很多時候base64加密的字符串尾部為 1個或2個 "=",
          因為它是把3個字節的二進制拼接,如果最后剩下一個,那么尾部就會添加2個=,
          如果剩下兩個,尾部就添加1個=,如果剛合適那當然就沒有=了
          

          推薦一個工具網站https://tool.lu/encdec/

          image.png

          使用編解碼試試看,最終我發現是賬號,而且是采用了url encode和base64編碼,所有最終我們的su就是

          image.png

          • pcid、servertime、nonce、rsakv
          • 它的值時gz-48fb749c5c715e0d5caeed045716492e153c,我們先在Charles中搜索一下


          • pcid
          • 我們一般都是搜索response的數據,主要是看一下是不是在某一個請求的返回值里面,這里非常棒,我們找到了pcid和值出現的地方https://login.sina.com.cn/sso/prelogin.php?entry=weibo&callback=sinaSSOController.preloginCallBack&su=MTgwOTE3MzQxMzY%3D&rsakt=mod&checkpin=1&client=ssologin.js(v1.4.19)&_=1518956150179,在這個請求的返回值里面,而且我們還有意外的收獲,我們得到了四個參數,和登錄請求里面的一樣,我們現在確定了四個參數的來源,


          • image.png
          • 看一下請求的參數


          • image.png
          • 除了su和下面的時間戳其他的參數基本固定,時間戳沒什么特點,我們就用int(time.time() * 1000)生成,因為是13位的。su我們上面已經知道了。那么這四個參數也搞定了??
          • door
          • door很熟悉吧,是驗證碼。那么驗證碼的請求怎么確定,非常簡單因為我們的驗證碼是一張圖片,所以找圖片請求就可以了


          • 驗證碼
          • 這個往上翻一翻就能很快找到,找到后我們看看它的參數


          • 參數
          • p的值就是pcid的值,我們已經知道了。r有點不太好找了,先在Charles里搜一下62026273,沒找到,那么應該就是本地生成的,其實你可以寫死試試,有沒有問題。除了搜這個值以外,我們還可以搜一下這個請求是在哪里生成的,看它附近有沒有有用的數據。


          • image.png
          • 搜一部分就行了,先用小部分搜,如果結果太多,在多加一些搜索,這里我們找到了一條,點擊去看一看,點到JavaScript那個頁簽,Charles會幫我們格式化js


          • image.png
          • 找到了pincodeUrl,再搜索一下pincodeUrl


          • image.png
          • 看到沒有,開不開心?激不激動?


          • 驗證碼請求
          • prelt
          • 這個參數和驗證碼請求的那個r參數類似,值搜不到,但是我們可以搜這個prelt,你問r那個為啥不搜?[鄙視眼]你猜猜能搜到多少?


          • image.png
          • 同樣點進去,切換到JavaScript頁簽,發現了preloginTime,再搜它吧



          • image.png
          • 多搜一些你就發現它應該是個時間段,結合prelt本身的值,我們就可以構造出一個值。可以通過多次請求來確定一個范圍,另外時間差,而且它用的是本地的時間計算的,那么也不需要多么精確,確定一個范圍應該就可以了,所以在一個范圍內取隨機數就行了


          • -sp
          • 最麻煩的來了,sp這么長一段,觀察其特點,發現應該是16進制,所有字符都是在0-9、a-f之間,而且參數pwencode的值rsa2,基本上我們就可以確定其采用的是rsa加密算法。這串字符肯定是搜索不到的,可以搜sp,刪掉明顯不是的,我們一般看的是sp=xx這樣的,就是看賦值,從賦值的操作上下文去查看


          • image.png
          • 經過過濾分析,只剩下兩個地方https://passport.weibo.com/visitor/visitor?entry=miniblog&a=enter&url=https%3A%2F%2Fweibo.com%2F&domain=.weibo.com&ua=php-sso_sdk_client-0.6.23&_rand=1518956141.4946和https://js1.t.sinajs.cn/t5/register/js/v6/pl/register/loginBox/index.js?version=d7a77880fa9c5f84


          • image.png
          • 然后打開chrome瀏覽器,開發者工具,然后訪問https://weibo.com,切換到source頁簽找到這兩個js文件,并搜索sp,通過觀察特點基本確認為第二個js文件


          • image.png
          • e.sp = b,在b的計算之前打上斷點,然后執行登錄操作,這里我們還發現了su的計算算法,跟我們上面分析的基本一致


          • image.png
          • 通過調試這段代碼我們就得到了其加密方式,這里有幾個變量me.rsaPubkey、me.servertime、me.nonce、b,通過console中查看b是密碼,然后就是這pubkey


          • image.png
          • 在上面pcid參數的請求的返回值里面我們看到有這個值。OK這幾個變量我們都知道了,下面你了解一下rsa加密算法的python實現,直接貼代碼


          • image.png

          執行登錄請求

          登錄請求的所有參數都已經分析完了,登錄后查看response數據

          image.png

          然后再看一下登錄請求的下一個請求,發現是通過登錄請求的返回值中的url,然后發送此請求

          image.png

          返回值中又出現了另外一個url,我們在下面也找到了,提取url發送請求

          image.png

          看到返回狀態了嗎?302重定向。發送請求以后查看一下response的url,發現是在它下面的請求地址

          返回值和下面的請求好像有點關聯,有下一個請求的參數。別急,先等等,我們就這樣一直請求、提取請求、再請求,得有個終點吧,到哪里算一站呢。我們想想登錄以后,顯示一個頁面有用戶名。我們只要能得到這個用戶名那就說明登錄成功了。

          image.png

          這里看到了這個home請求中出現了我的用戶昵稱,然后上面那個請求的返回狀態302,又是重定向。使用上面的方式確認一下。提取userdomain,然后拼接https://weibo.com/

          image.png

          成功了


          主站蜘蛛池模板: 一区二区不卡久久精品| 在线免费一区二区| 国产成人精品视频一区二区不卡 | 成人丝袜激情一区二区| 亚洲.国产.欧美一区二区三区 | 中文字幕精品无码一区二区| 色一情一乱一伦一区二区三区| 国产福利电影一区二区三区,日韩伦理电影在线福 | 国产对白精品刺激一区二区| 无码av免费一区二区三区| 国产精品美女一区二区视频| 久久久久人妻一区精品果冻| 免费人人潮人人爽一区二区| 精品一区二区三区无码视频| 一区二区三区免费电影| 三上悠亚国产精品一区| 少妇激情一区二区三区视频| 亚洲男女一区二区三区| 欧美日韩综合一区二区三区| 免费高清av一区二区三区| 国产视频一区在线播放| 成人国产精品一区二区网站| 波多野结衣高清一区二区三区| 国产精品一区二区久久不卡 | 国产一区二区三区不卡观| 国内偷窥一区二区三区视频| 少妇无码一区二区三区| 日本一区二三区好的精华液 | 国产精品视频一区麻豆| 亚洲一区在线视频| 国产乱码精品一区二区三区四川| 日本一区二区在线免费观看| 成人无码AV一区二区| 精品永久久福利一区二区| 在线精品自拍亚洲第一区| 国产午夜精品一区二区三区不卡| 无码人妻一区二区三区在线视频 | 小泽玛丽无码视频一区| 亚洲AⅤ无码一区二区三区在线| 午夜在线视频一区二区三区| 日亚毛片免费乱码不卡一区|