目前眾多的網文產品中,設計同質化比較高,無論是產品視覺或是品牌運營視覺大多都缺乏獨創性與統一性。番茄小說想要從眾多產品中脫穎而出就需要走出一條合而不同的設計道路。因此提升產品的識別度與消費者對品牌的認知勢在必行,設計需探索構建一套屬于產品的語言體系。
探索番茄小說的設計語言,建立產品認知
傳統文學
文學分為兩類,嚴肅文學(看重語言和細節)、通俗文學(注重情節和故事,淺顯易懂)。
周憲《文學理論導引》里定義「文學是以精致語言書寫的具有藝術價值的以文本為中心的文化系統。」通過定義可以概括出文學的特點就是具有藝術價值,并且能夠通過文字內容帶人用戶反思或者收獲。當人們在閱讀文學書籍時是冷靜的,只有在這樣的心境下讀者才能更好的獨立思考與分析。因此在氛圍上需要給用戶提供一個相對沉浸的空間、安逸的環境,通過分析可以提煉出的傳統文學情緒關鍵詞:沉浸、冷靜、舒適、價值
網絡文學
不同于傳統文學,網絡文學是順應市場價值而誕生,是文學創作的平民化,讓大家能夠以網絡為載體而發表的文字內容。廣義來說,網絡文學屬于通俗文學的一類,注重情節和故事,通過文字傳遞的內容更加的樸實、接地氣,在創作分類上也更加的多樣化,作者可以天馬行空的表達自己感受,可以說是在傳統文學的基礎上,給文字增加了幾分煙火氣息,也多了幾分熱鬧的感受。
因此通過文學關鍵詞可擴展出網絡文學情緒關鍵詞:沉浸、愉悅、煙火氣
前期通過對小說用戶群體與市場的走訪調研,并通過數據分析,我們得到了如下結論:
產品用戶類型
12-50歲青中年人;后GenX時代;一二三線城市有閱讀小說習慣的人群;目前為對生活充滿向往的學生與藍領
產品品牌人格
樂觀愉悅(輕松);品質(書好);親民、豐富(書多)
產品視覺風格
品牌色貫穿產品,但不過分使用;視覺為產品功能服務,不做多余的設計;視覺表現多樣化,但需要表達相同的產品氣質;適度的留白,增強設計空間感
產品核心詞:「沉浸中的愉悅」
正如我們對文學的分析,小說閱讀同樣是一種獨立個體的行為方式,在讀書時,我們不希望被人打擾,不希望被瑣事細節阻斷,我們希望在一個相對安靜、舒適的環境下閱讀,這是一種沉浸式的感受。
因此這里我們就根據用戶的想要的感受,引入「沉浸」的概念——希望能夠給讀者留下一定的空間,并拋除繁雜打擾,讓大家享受閱讀與獨立思考。其核心是圍繞信息內容本身而呈現,設計不再作為獨立于內容之外的元素存在,而將著眼于內容本身,為用戶打造直觀的視覺體驗。拉大層級對比,增加適當的留白,在一定程度上增加少許修飾,打破絕對的冷淡。其既能體現出文學的特點,又能夠在簡約的基礎上增加畫面的構成感,給用戶愉悅的感受。
觸感
網絡小說與傳統文學另外一個最大的區別是觸感。
傳統文學大多以實體書籍紙張為承載,而網絡文學來自于互聯網是虛擬的。我們在閱讀時,觸摸紙張與書本樸實的質感,也能夠給讀者帶來額外的舒適感受,因此如果能以視覺的形式還原用戶對書籍的「觸感」,不僅能夠將網絡與實體相鏈接,也可以幫助用戶增加電子閱讀的樂趣。
根據歸納出的文學特征,以及調研用戶年齡層與喜好,我們可以歸納出番茄小說基礎原生關鍵詞。
基礎原生關鍵詞
拓展衍生關鍵詞
根據網絡文學原生關鍵詞,我們拓展出衍生詞
圖片搜索、提取情緒版
根據相關的衍生關鍵詞,我們收集大量的視覺圖片并將其匯總,借以分析其視覺特征
色彩提取
視覺映射
通過對情緒版的分析,我們可以得出結論并整理出番茄小說設計語言,輕量的色彩、寫意式元素、非對稱布局、紙紋理噪點
將傳統的冷靜沉浸與網絡文學的熱鬧向融合是番茄小說設計語言的重要視覺呈現方式風格
多元化的簡約設計+情感化修飾
Logo
番茄的品牌名稱基于「、優質」的產品理念,服務于產品設計、品牌設計中。番茄相對于紅果是一個更加具象的表達,不僅可提高用戶對產品的認知,也能傳遞小說品牌的理念和態度?;诖?,這個理念框架是講述品牌故事的關鍵載體。
logo動畫展示
小說相關產品logo匯總
在logo的設計上我們將番茄的圖形概念化,保留番茄籽,局部的留白讓標志同樣能表達空間與白的概念。我們選擇在白色底上用紅色非對稱性式logo ,既區別了市面上大多產品logo樣式,又能夠加深用戶對產品的印象,突出了「愉悅」的特性。
選定 logo 并設計圖形+文字組合:
在文字設計上,相比正常宋體弱化文字襯線,為了突出空間感,我們擴大了字面拉伸了中宮的占比,這樣做不僅提高文字識別度,整體氣質也也能夠與沉浸的定義相耦合。
品牌色
前期通過情緒版的分析,摘取關鍵詞配色,綜合歸納出符合番茄小說特性的的色彩搭配
通過對情緒版色彩的歸納,我們抽取具有代表性的顏色,作為番茄小說的品牌色
輔助圖形
從logo中番茄圖形的概念出發,提取出以圓、番茄籽、番茄輪廓為基本型的品牌圖形元素
官方字體
考慮到官方字體在沉浸式頁面中的運用,番茄官方字體的選擇與品牌屬性相契合的蘋方體、宋體。
VI 呈現:
品牌視覺感受:
品牌體現—產品場景
番茄小說給人的感覺是安靜、平和、友好。因此在顏色使用中以品牌色配合低飽和度背景色做搭配,突出產品的帶給用戶的沉浸、愉悅感。
運營場景—運營設計對品牌塑造的意義
第一眼的感受,往往決定了用戶對產品的整體印象。目前在番茄小說的產品中,最直觀的品牌視覺展示主要以書單活動banner為載體,其做為活動入口本身就處在一個前置的位置,占用空間大且更能吸引到用戶的注意。因此,需要對運營焦點圖設計精細化的打磨,讓用戶在打開產品的瞬間,快速塑造產品在用戶心中的視覺形象。
番茄小說運營設計——和而不同
運營設計的基本原則
因此番茄小說的運營視覺需要緊密圍繞在這個大前提下進行設計,快速傳達信息=保證信息的簡單化、文字有效性,促使用戶行動=畫面內容的趣味性、吸引性。
視覺呈現形式
遵循番茄體系,體現小說內核的「煙火」氣質,視覺呈現多元化。以運營文案為中心,畫面設計貼近內容,降低用戶信息識別成本。
品牌運營視覺一期構建:手繪元素+非對稱構圖+質感
設計規范
運營視覺與品牌調性應是統一的,因此在運營設計的色彩選擇需要與品牌配色相呼應,保證視覺與整個產品的和諧性。
運營插圖案例
在運營活動中,依然要以產品所傳遞的氣質來進行畫面設計,即是保留沉浸的前提下,抽取關鍵詞的某個方向來表達品牌運營所傳遞的理念。在色彩的使用上可以圍繞關鍵詞的方向來選擇顏色,以表達內容所傳遞的信息,可適當使用品牌色作為點綴,但依然需要的保持視覺給人帶來的平和感。
作為一個從 0 到1的品牌,番茄小說的設計語言依然在不斷的打磨、優化。整體清晰的品牌規劃能夠保證線上、線下、產品與營銷的各個視覺設計環節更加統一,同時也為后續的設計指明方向,助力業務持續發展。
文章來源:優設 作者:今日頭條UED
his是一個關鍵字,表示執行當前函數的對象
function fn(){
console.log(this); //window
console.log(typeof this); //object
}
fn();
- 嚴格模式下,this指向undefiend
"use strict";
function fn(){
console.log(this); //undefined
}
fn();
文章目錄
0.官方文檔:
1.webpack概述:
2.webpack的基本使用:
3.在項目中安裝和配置 webpack:
4.配置自定義打包的自定義入口和出口:
4.配置自動打包功能:
5.配置生成預覽頁面功能:
6.配置自動打包相關參數:
7.webpack 中的加載器:
8.loader加載器的基本使用:
9.Vue單文件組件:
10.webpack 打包發布:
11.以上所有配置 webpack.config.js 截圖
1.webpack概述:
webpack是一個流行的前端項目構建工具(打包工具) ,可以解決當前web開發中所面臨的困境
webpack提供了友好的模塊化支持,以及代碼壓縮混淆、處理js兼容問題、性能優化等強大的功能,從而讓程序員把工作的重心放到具體的功能實現上,提高了開發效率和項目的可維護性
2.webpack的基本使用:
2.1:打開終端運行命令 npm init -y 初始化包管理配置文件 package.json
2.2:新建 src 源文件目錄(里面放程序員自己寫的代碼比如 html css js images …)
2.3:如果需要引入 jquery 庫 終端運行以下命令npm install jquery -S 安裝 jquery
自己在src文件夾中創建 index.js 引入下載的jquery包import $ from 'jquery'
3.在項目中安裝和配置 webpack:
3.1:終端運行 npm install webpack-cli -D 命令,安裝webpack相關的包
這里要注意一個問題 : package.json 和 package-lock.json 文件里的名字默認為 “name”=“webpack”,在配置 webpack-cli 之前要把name 改成 其他名字 比如 “name”=“webpack_” 不然的話為出現無法安裝的問題
具體可點擊這里 Webpack依賴包安裝問題解決方案
3.2:在項目根目錄中 ,創建名為 webpack.config.js 的 webpack 配置文件
3.3:在 webpack.config.js 中,初始化一下基本配置
建議選擇 development (打包速度快,體積大),項目上線是才改成 production (如果選擇production會進行代碼的壓縮和混淆,打包速度慢,體積小)
3.4:在package.json中的 script節點 新增一個dev腳本 值為 webpack ,就可以實現打包功能
在終端運行命令:npm run dev
就可以打包 默認打包成main.js在 dist文件夾中
在src自己新建的index.html 中引入打包后的 js
屬性描述符就是一個屬性除了屬性名與屬性值之外的其他相關信息
通過Object.getOwnPropertyDescriptor(對象, 屬性名)
可以得到一個對象的某個屬性的屬性描述符
let obj = { a: 1 } console.log(Object.getOwnPropertyDescriptor(obj, 'a')); // { // value: 1, // writable: true, // enumerable: true, // configurable: true // }
通過Object.getOwnPropertyDescriptors(對象)
可以得到某個對象的所有屬性描述符
let obj = { a: 1, b: 2 } console.log(Object.getOwnPropertyDescriptors(obj)); // { // a: { // value: 1, // writable: true, // enumerable: true, // configurable: true // } // b: { // value: 2, // writable: true, // enumerable: true, // configurable: true // } // }
接下來,說一說每一個屬性描述符的作用
不多逼逼
當我們設置configurable為false以后,再去修改屬性描述符的話,會報錯
let obj = { a: 1, b: 2 } Object.defineProperty(obj, 'a', { value: 'a', configurable: false }) Object.defineProperty(obj, 'a', { value: 'a', configurable: true }) // Uncaught TypeError: Cannot redefine property: a // at Function.defineProperty (<anonymous>)
當設置一個屬性的enumerable為false時,該屬性不可被forin循環
但是不影響forof循環,因為forof循環看有沒有Symbol(Symbol.iterator)
forin循環的是屬性名,forof循環的是屬性值
不用看時間,你沒有穿越,現在是 2020 年,不是 2000 年。這復古的字體設計和這帶有年代感的落日背景,以及悠揚壯闊的背景音樂,甚至讓我以為是在看二十年前新年晚會的演出視頻。
△ 視頻鏈接:https://v.youku.com/v_show/id_XNDYzNTE2MzgxNg==.html
不得了,不得了,恒大足球場的宣傳視頻甚至登上了央視的廣告舞臺,展示給了全國觀眾,壕氣十足,花開富貴,這絢爛的煙花背景,讓我瞬間夢回三十年前。
建筑不僅外表華麗,其實文化內涵還很深厚,與中老年表情包冥冥之中有了一個巧妙的對應,蘊含著給你帶來好運,祝你平安健康。
據網友考據,設計理念可能來自于一盆多肉,為了更加貼近人民群眾的生活,讓人們時時感受到自然的美妙。
還有網友幻想出最終建設完成時的終極形態,積極對建筑進行了自己的解讀和創作,看這廣泛的聯合角色設計,佛祖、紅孩兒;這跨越多個時代的風格雜糅,上個世紀的吉祥如意、這個世紀的游戲建模;涵蓋多個領域的蓮花主題,植物、彩燈,應有盡有,真是妙??!
什么?你覺得不好看嗎?這可是恒大總裁許家印從 9 種蓮花寶座設計方案中精挑細選出來的一個!九種不同的蓮花設計方案,深淺不同的粉紅色,看不出有多大不同的開合程度,微微不一樣的花瓣設計,供你瞪大雙眼選擇。
你問:可以阻止這個色彩絢麗的建筑修建起來么?來晚了,蓮花寶座已經于 4 月 16 日開始修建,屆時會成為世界規模最大的頂尖專業足球場。開心一點,說不定以后能在中國看世界杯了呢。
既然是世界規模最大的頂尖足球場!為什么不修好看一點?這什么設計師,這種紅配綠,亮瞎人眼的設計是哪個沙雕公司設計的?許老板這么有錢,怎么不請好一點的設計師呢。廣州這么時尚的城市配上這樣的土味建筑,真是令人頭大。其實,你可能罵錯人了。背后的設計公司可是 Gensler,現在世界上數一數二的的設計團隊。這不是變魔術,設計出上面土味十足的建筑和下面高級感撲面而來的建筑的就是一個團隊。
上海中心大廈(右一),憑借其獨特的造型和樓高,榮獲諸多大獎,成為上海地標性的建筑之一。
還有菲律賓金融中心大廈,與周圍的建筑對比起來,科技感和現代感十足,在 CBD 群中獨占鰲頭。
又或者是在波士頓起到樞紐作用的綜合體建筑設計,一眼望去稱霸整個地區。
這怎么看,都不像是一個團隊設計出來的作品。蓮花球場和高級感相關在哪里?這不是隨隨便便一個設計師都可以設計出來的么?其實,這也不是許老板第一次這么偏愛蓮花了,看看?;◢u項目就知道了,網友調侃說到,果然設計師還是敗給了金錢。
不過同樣是以蓮花為設計元素,印度的蓮花寺怎么看起來就這么高端優雅呢?與蓮花球場「土味建筑」不同的是,蓮花寺廣受好評,被稱為新德里的「悉尼歌劇院」。
類似蓮花球場這樣的案例在中國還有很多。之前被評為 2017 年中國最丑陋的十大建筑之一的廣州圓大廈,由意大利米蘭設計師 Joseph di Pasquale 設計,他在采訪中說到:「中國改變了他,讓他知道了文化如何融于建筑,如何更好地滿足客戶的欲望。」其實建筑的寓意「雙環玉璧」是很好的,但是最終的效果不盡人意,建筑類似于黃金的外表顏色,被網友們吐槽,稱其為「土豪圓」。
不過設計這個事情,有時候也很難去用單純的美丑判別。例如設計出臺北 101 大廈的李祖原老師,在同年設計出的沈陽方圓大廈,是參考銅錢的形狀設計而成。在 2000 年威尼斯世界建筑設計展覽會上被稱贊為是「世界上最具創意性和革命性的完美建筑」,但在 2012 年卻被 CNN 旗下的生活旅游網評選為全球最丑的十大建筑之一。
你以為這就結束了嗎?別走,奇葩建筑還有很多,中國各個省都互不相讓。首先我們從南看起,海南三亞的「美麗之冠」,就是后面那些像樹一樣的建筑,一模一樣的樓不知道為什么要修建九個。
往北走,我們來到了官方宣傳視頻里寫到的「不來萬家麗,枉來中國行」,之中的世界最大建筑「長沙萬家麗」。這棟同樣金碧輝煌、中西結合的建筑讓你深刻體會到一句話「有錢就是可以為所欲為」。不論是美是丑是否合適,只要是自己喜歡的元素,通通都堆砌在一棟建筑里。
接著我們來到了山東的文成城堡,沈騰的《西虹市首富》取景地,看看這個豪華程度,一晃神還以為自己來到了歐洲。
最后我們來到河北,學習魔法不需要出國,直接來河北美術學院,一個被戲稱為「霍格沃茨華北分校」的美術帝國,由于其仿照魔法學院進行的設計,在中國眾多美院中獨樹一幟。
以上這些奇葩建筑的盤點,均來自于 B 站 up 主史里芬 Schlieffen,一個被長沙萬家麗老板黃總盛情邀請再次體驗萬家麗的男人。盤點中國奇葩建筑,現代青年當仁不讓。想要了解中國建筑底層設計的朋友,可以前去品鑒和觀賞,不要怪我用丑陋和土味蒙蔽了你們的雙眼。押韻的解說詞,第一視角的全方位建筑講解,你值得擁有。
主頁鏈接:https://space.bilibili.com/323733137/
這樣的建筑作品很新鮮但是確實不美觀。且不說中國其實有很多好的設計師,為什么和國外知名設計團隊合作,做出來的作品依舊差強人意呢?難不成是我們的審美水平真的已經淪落成這個地步了?如果哪天全民都覺得這樣的建筑是美的,都欣賞這樣的建筑,那我們整個社會才算是陷入了「惡趣味審美」之中,就真正完蛋了。標榜著以「蓮花綻放」這一美好寓意為核心的蓮花球場設計,何嘗不是披著虛偽外衣的土味建筑設計呢?美能夠讓人感到幸福,反過來,丑則使人感到不適。
對于蓮花寶座外形的足球場設計,我想開了,畢竟我不是亞洲第五富,眾位設計師,你們是怎樣看待的呢?
文章來源:優設
feed 單詞釋義:v. 喂養;進食;為……提供充足的食物;施肥;為(某人)提供(信息、主意等);
n. 飼料;飼養;(尤指給動物或嬰兒)喂食;進食;(計算機的)訂閱源
形象來講,如今新浪微博、微信朋友圈、抖音、今日頭條、小紅書、Facebook、QQ 空間等等內容平臺每時每刻都在不斷投喂給我們賴以維系健康生活(廢柴生活)的精神食糧——信息內容。而這些信息組合起來的格式便是 feed。
1. Feed
feed 是一種信息格式,平臺通過它將資訊傳遞給用戶。feed 是信息聚合的最小單元,每一條狀態或者消息都是 Feed,比如朋友圈中的一個動態就是一個Feed,微博中的一條微博就是一個 Feed。
2. Feed流
feed 流即持續更新并呈現給用戶內容的信息流。每個人的朋友圈,微博關注頁,頭條新聞等等都是一個 Feed 流。
Feed 源于早期的 RSS(Really Simple Syndication )
RSS(簡易信息聚合):將用戶主動訂閱的若干消息源組合在一起形成內容(aggregator),幫助用戶持續地獲取的訂閱源內容。對用戶而言,聚合器是專門用來訂閱網站的軟件,一般亦稱為 RSS 閱讀器、feed 閱讀器、新聞閱讀器等。用戶選擇訂閱多個訂閱源,網站提供 feed 網址 ,用戶將 feed 網址登記到聚合器里,在聚合器里形成聚合頁,用戶便能持續地獲取的訂閱源內容。
在早期的 Web 時代,訂閱源一般是新聞網站以及博客。用戶主動訂閱感興趣的多個訂閱源,訂閱器幫用戶及時更新訂閱源信息,然后按照 timeline 時間順序展示出來。這樣,用戶可以通過訂閱器獲取即時信息,而不用每天都檢查各個訂閱源是否有更新。
轉折出現在 2006 年,Facebook 宣布了一項新的首頁形式「News Feed」,這一形式打破了傳統 RSS 的訂閱方式。News Feed 可以看做一個新型聚合器,訂閱源不僅僅是某個網址、某個新聞網站或者某個內容,而是生產內容的人或者團體,而內容即是好友或關注對象的動態(發布的內容以及其他的社交行為)。News Feed 的出現使得 RSS 被迫淡出歷史舞臺。News Feed 發展至今已經拓展出多種多樣的模式和呈現方式。
推模式:每當用戶發帖,對所有粉絲推送一條該用戶的動態消息記錄。需要考慮的是如果一個粉絲量級非常大的用戶(大 V),發布一條動態那么需要在每個粉絲頁推送一條動態,多個大 V 級別用戶同時發帖對數據的存儲負荷是非常大的。
拉模式:每當請求好友動態,拉取用戶所有關注者的最近動態,然后匯總排序。如果用戶同時關注非常多的用戶,那么查詢這類型的用戶的關注列表也是很大的數據成本。
推拉模式:在線推,離線拉;定時推,離線拉。
除了關注 feed 流的主要模式之外,feed 流的排序方式也值得一提:
Timeline:按發布的時間順序排序,先發布的先看到,后發布的排列在最頂端,類似于微信朋友圈等。這也是一種最常見的形式。產品如果選擇 Timeline 類型,那么就是認為 feed 流中的 feed 不多,但是每個 feed 都很重要,都需要用戶看到。
Rank:按某個非時間的因子排序,一般是按照用戶的喜好度排序,用戶最喜歡的排在最前面,次喜歡的排在后面。這種一般假定用戶可能看到的 Feed 非常多,而用戶花費在這里的時間有限,那么就為用戶選擇出用戶最想看的 Top N 結果,場景的應用場景有微博、頭條新聞推薦類、商品、視頻推薦等。
目前 feed 流的主流排序方式不再嚴格按照 timeline,而是廣泛使用智能 feed 排序。
智能排序基于趨勢 trending、熱門 hot、用戶生產 UGC 、編輯推薦 PGC、相似 Similarity 等等因素綜合考慮,隨著技術的進步,智能算法將會更加懂得用戶的喜好。新的 feed 流不再需要用戶主動訂閱或者搜索,只要監測我們的瀏覽時長、點贊分享等動作,或者建立用戶畫像類別,就可以主動推薦我們感興趣的內容。它對我們了如指掌,給我們想了解的,讓我們不停刷新沉溺于其中。就現在 feed 流中的廣告,女性用戶對化妝品的喜好,男性用戶對車的偏愛,臨時借錢的窘迫,這些暖廣告已經不再像牛皮癬一樣惹人討厭,甚至變成了一顆我們愿意吃下的安利。
可以有以下大致分類:
feed 作為信息聚合的最小單元,每一個 feed 都會具備相應的內容。其中包括發布的時間、發布者、文字內容、圖片內容,還包含點贊、轉發、評論、關注等操作、根據應用場景、業務目標不同,其表現方式也大有不同,任何表現形式都應該是為了更好地呈現功能及內容。
新聞資訊類產品和社交互動類產品 feed 元素大體相同,區別在于新聞資訊類產品通常著重展現新聞內容,標題,簡介,匹配的圖片等,而發布時間和發布作者等會在單個 feed 的底部出現。在圖文兼備的排版布局中,左文右圖適合文字內容類比如文章或者知乎、豆瓣等長答案評論等,圖片是輔助信息支撐文字內容。左圖右文圖片更加吸引人的注意通常出現在商品信息比如什么值得買。
社交互動類產品,其最終目的是發現和拓展社交關系,融入相應的社交圈。而這時候社交拓展的基本單位人或者團體發揮著至關重要的作用。所以我們可以發現,通常的社交互動軟件都會將發布者頭像放在上部展示的位置,也會在底部突出點贊,評論,分享等互動操作。
視頻直播類產品與前兩者相異,頁面的大部分空間留給視頻內容的展示,一般一屏只承載一個 feed 信息單元,內容等提示元素在左側呈現,除回復評論等操作元素列在右側。
feed 中各元素的位置關系、所占比例與產品自身定位密切相關。如微博作為泛社交應用產品,社交關系主要建立在內容上,社交關系質量較弱,多為單向傳播,注重的是傳播的速度和內容公開。所以其 feed 的呈現方式發布者與發布內容不做明顯的設計排布區分。以卡片間隔的形式在 feed 與 feed 之間做區隔。評論頁面在下一層級。
微信是作為一個社交工具,社交關系質量較強,多為雙向關系,注重的是私人內容的交流和互動,信息的傳播速度不快,但受眾信息消化率很高。所以將發布者頭像與發布內容做出較明顯區分,feed 與 feed 之間因為已經有了頭像元素這一明顯區別要素,僅用分割線做區隔。且注重評論區域的互動與展示。
無論怎樣的設計布局方式,遵循的核心思想始終是根據場景需求、業務目標去發展深化設計方案。每一個設計點都要有足夠的支撐,多問問自己為什么這么設計,解決了用戶什么樣的問題?還有沒有更好的替代方案?而不是這樣設計是不是新穎,出奇制勝。
文章來源:優設 作者:Nicole
性能優化(網絡方向)
web應用無非是兩臺主機之間互相傳輸數據包的一個過程; 如何減少傳輸過程的耗時就是網絡方向優化的重點, 優化出發點從第一篇文章中說起
DNS解析過程的優化
當瀏覽器從第三方服務跨域請求資源的時候,在瀏覽器發起請求之前,這個第三方的跨域域名需要被解析為一個IP地址,這個過程就是DNS解析;
DNS緩存可以用來減少這個過程的耗時,DNS解析可能會增加請求的延遲,對于那些需要請求許多第三方的資源的網站而言,DNS解析的耗時延遲可能會大大降低網頁加載性能。
dns-prefetch
當站點引用跨域域上的資源時,都應在<head>元素中放置dns-prefetch提示,但是要記住一些注意事項。首先,dns-prefetch僅對跨域域上的DNS查找有效,因此請避免將其用于您當前訪問的站點
<link rel="dns-prefetch" >
preconnect
由于dns-prefetch僅執行DNS查找,但preconnect會建立與服務器的連接。如果站點是通過HTTPS服務的,則此過程包括DNS解析,建立TCP連接以及執行TLS握手。將兩者結合起來可提供機會,進一步減少跨源請求的感知延遲
<!-- 注意順序, precontent和dns-prefetch的兼容性 -->
<link rel="preconnect" crossorigin>
<link rel="dns-prefetch" >
TCP傳輸階段優化
這個前端方面好像能做的有限, 我們都知道 http協議 是基于 tcp的;
升級http協議版本可以考慮下, 比如把 http/1.0 -> http/1.1 -> http/2;
這個需要我們在應用服務器上配置(nginx, Apache等), 不做概述了, 另外還需要客戶端和服務器都支持哦, 目前還沒開發出穩定版本,好多只支持https,不過也不遠了...
http2 的優勢
# 1.多路復用: 同一個tcp連接傳輸多個資源
這樣可以突破統一域名下只允許有限個tcp同時連接,
這樣http1.1所做的減少請求數優化就沒有太大必要了
如多張小圖合成一張大圖(雪碧圖),合并js和css文件
# 2.報文頭壓縮和二進制編碼: 減少傳輸體積
http1 中第一次請求有完整的http報文頭部,第二次請求的也是;
http2 中第一次請求有完整的http報文頭部,第二次請求只會攜帶 path 字段;
這樣就大大減少了發送的量。這個的實現要求客戶端和服務同時維護一個報文頭表。
# 3.Server Push
http2可以讓服務先把其它很可能客戶端會請求的資源(比如圖片)先push發給你,
不用等到請求的時候再發送,這樣可以提高頁面整體的加載速度
但目前支持性不太好...emm...
總的來說, 在 c 端業務下不會太普及, 畢竟需要軟件支持才行...
http 請求響應階段優化
為了讓數據包傳輸的更快, 我們可以從兩個方面入手: 請求的數據包大小(服務器), 請求數據包的頻率(客戶端)
減少請求文件的大小
請求文件對應的是我們項目完成后,打包所指的靜態資源文件(會被部署到服務器), 文件越小, 傳輸的數據包也會相對較小, 講道理也會更快到達客戶端
how to reduce a package size?
目前我們都會使用打包工具了(比如webpack, rollup, glup 等), 如何使用工具來減小包的體積呢? 這邊建議您去官網文檔呢...當然這里列舉一下常用的手段(webpack 的), 但是注意要插件版本更新哦
JS文件壓縮
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
plugins: [
new UglifyJsPlugin({
// 允許并發
parallel: true,
// 開啟緩存
cache: true,
compress: {
// 刪除所有的console語句
drop_console: true,
// 把使用多次的靜態值自動定義為變量
reduce_vars: true,
},
output: {
// 不保留注釋
comment: false,
// 使輸出的代碼盡可能緊湊
beautify: false
}
})
]
}
CSS 文件壓縮
// optimize-css-assets-webpack-plugin
plugins: [
new OptimizeCSSAssetsPlugin({
assetNameRegExp: /\.css$/g,
cssProcessor: require('cssnano'),
}),
];
html 文件壓縮
// html-webpack-plugin
plugins: [
new HtmlWebpackPlugin({
template: path.join(__dirname, 'src/index.html'),
filename: 'index.html',
chunks: ['index'],
inject: true,
minify: {
html5: true,
collapseWhitespace: true,
preserveLineBreaks: false,
minifyCSS: true,
minifyJS: true,
removeComments: false,
},
}),
];
source map 文件關閉
tree shaking
1.代碼不會被執行,不可到達,比如 if(false){// 這里邊的代碼}
2.代碼執行的結果不會被用到
3.代碼只會影響死變量(只寫不讀)
4.方法不能有副作用
// 原理相關: 以后在研究
利用 ES6 模塊的特點:
只能作為模塊頂層的語句出現
import 的模塊名只能是字符串常量
import binding 是 immutable 的
代碼擦除: uglify 階段刪除無用代碼
scope hoisting(作用域提升)
分析出模塊之間的依賴關系,盡可能的把打散的模塊合并到一個函數中去,但前提是不能造成代碼冗余
const ModuleConcatenationPlugin = require('webpack/lib/optimize/ModuleConcatenationPlugin');
module.exports = {
resolve: {
// 針對 Npm 中的第三方模塊優先采用 jsnext:main 中指向的 ES6 模塊化語法的文件
mainFields: ['jsnext:main', 'browser', 'main']
},
plugins: [
// 開啟 Scope Hoisting
new ModuleConcatenationPlugin(),
],
};
項目中使用按需加載,懶加載(路由,組件級)
const router = new VueRouter({
routes: [
{ path: '/foo', component: () => import(/* webpackChunkName: "foo" */ './Foo.vue') }
{ path: '/bar', component: () => import(/* webpackChunkName: "bar" */ './Bar.vue') }
]
})
開啟 gizp 壓縮
有時候啟用也會消耗服務器性能, 看情況使用吧
暫時先提這么些吧...后續想到了再加
減少請求頻率
因為同一域名下 tcp 連接數的限制導致過多的請求會排隊阻塞, 所以我們需要盡量控制請求的數量和頻率
常見措施
將靜態資源的內聯到HTML中
這樣這些資源無需從服務器獲取, 但可能影響到渲染進程...
<!-- 1.小圖片內聯 base64 (url-loader) -->
<!-- 2.css內聯 -->
<!-- 3.js內聯 -->
<script>
${require('raw-loader!babel-loader!./node_modules/lib-flexible/flexible.js')}
</script>
利用各級緩存(下一篇存儲方面介紹)
通常都是在服務端做相關配置, 但你要知道
我們可以利用http緩存(瀏覽器端)來減少和攔截二次請求, 當然一般都是在服務端設置的;
服務器端也可以設置緩存(redis等), 減少數據查詢的時間同樣可以縮短整個請求時間
利用本地存儲
我們可以將常用不變的信息存在本地(cookie,storage API 等);
判斷存在就不去請求相關的接口, 或者定期去請求也是可以的
花錢買 CDN 加速
CDN 又叫內容分發網絡,通過把資源部署到世界各地,用戶在訪問時按照就近原則從離用戶最近的服務器獲取資源,從而加速資源的獲取速度。 CDN 其實是通過優化物理鏈路層傳輸過程中的網速有限、丟包等問題來提升網速的...
購買 cdn 服務器;
然后把網頁的靜態資源上傳到 CDN 服務上去,
在請求這些靜態資源的時候需要通過 CDN 服務提供的 URL 地址去訪問;
# 注意, cdn 緩存導致的新版本發布后不生效的問題
所以打包的時候常在文件后面加上 hash 值
然后在 HTML 文件中的資源引入地址也需要換成 CDN 服務提供的地址
/alicdn/xx12dsa311.js
# 利用不同域名的 cdn 去存放資源, (tcp連接限制)
webpack 構建時添加 cdn
// 靜態資源的導入 URL 需要變成指向 CDN 服務的絕對路徑的 URL 而不是相對于 HTML 文件的 URL。
// 靜態資源的文件名稱需要帶上有文件內容算出來的 Hash 值,以防止被緩存。
// 不同類型的資源放到不同域名的 CDN 服務上去,以防止資源的并行加載被阻塞。
module.exports = {
// 省略 entry 配置...
output: {
// 給輸出的 JavaScript 文件名稱加上 Hash 值
filename: '[name]_[chunkhash:8].js',
path: path.resolve(__dirname, './dist'),
// 指定存放 JavaScript 文件的 CDN 目錄 URL
publicPath: '//js.cdn.com/id/',
},
module: {
rules: [
{
// 增加對 CSS 文件的支持
test: /\.css$/,
// 提取出 Chunk 中的 CSS 代碼到單獨的文件中
use: ExtractTextPlugin.extract({
// 壓縮 CSS 代碼
use: ['css-loader?minimize'],
// 指定存放 CSS 中導入的資源(例如圖片)的 CDN 目錄 URL
publicPath: '//img.cdn.com/id/'
}),
},
{
// 增加對 PNG 文件的支持
test: /\.png$/,
// 給輸出的 PNG 文件名稱加上 Hash 值
use: ['file-loader?name=[name]_[hash:8].[ext]'],
},
// 省略其它 Loader 配置...
]
},
plugins: [
// 使用 WebPlugin 自動生成 HTML
new WebPlugin({
// HTML 模版文件所在的文件路徑
template: './template.html',
// 輸出的 HTML 的文件名稱
filename: 'index.html',
// 指定存放 CSS 文件的 CDN 目錄 URL
stylePublicPath: '//css.cdn.com/id/',
}),
new ExtractTextPlugin({
// 給輸出的 CSS 文件名稱加上 Hash 值
filename: `[name]_[contenthash:8].css`,
}),
// 省略代碼壓縮插件配置...
],
};
/*
以上代碼中最核心的部分是通過 publicPath 參數設置存放靜態資源的 CDN 目錄 URL,
為了讓不同類型的資源輸出到不同的 CDN,需要分別在:
output.publicPath 中設置 JavaScript 的地址。
css-loader.publicPath 中設置被 CSS 導入的資源的的地址。
WebPlugin.stylePublicPath 中設置 CSS 文件的地址。
設置好 publicPath 后,WebPlugin 在生成 HTML 文件和 css-loader 轉換 CSS 代碼時,會考慮到配置中的 publicPath,用對應的線上地址替換原來的相對地址。
*/
參考
DNS MDN]
webpack 文檔
深入淺出 Webpack
Scope Hoisting
IOS下的webview頁面,內嵌iframe元素,將其樣式指定為寬高100%:
.iframe { width: 100%; height: 100%;
}
在安卓下運行均無問題,但是在IOS下會出現異常。
具體表現為iframe頁面內的子元素一旦超出原先的邊界,只要能影響到html元素的寬高,就會自動撐開iframe,即使html元素設置了overflow:hidden
也沒用。
比如一個body元素下的彈層需要從下往上滑動進場,這個彈層的位置就會導致html高度的變化,因此頁面底部的tabbar就會在彈層運動期間先消失再出現。
解決方法就是使用具體的寬高數值鎖定iframe元素:
function onLoadIFrame (index) { // 修復IOS下輪播圖初始化瞬間會讓iframe寬度自行擴大問題 if (this.ENV.isIOS) { const iframe = this.$el.querySelector('#iframe' + index)
iframe.style.width = iframe.clientWidth + 'px' iframe.style.height = iframe.clientHeight + 'px' }
}
在了解了javascript的語言基礎和特性后
javascript真正大放光彩的地方來了——這就是javascript DOM
Javascript DOM
DOM(Document Object Model),文檔對象模型。
是W3C組織推薦的處理可擴展標記語言(HTML或者XML)的標準編程接口;W3C已經定義了一系列DOM接口,通過這些DOM接口可以改變網頁的內容、結構和樣式。
簡單的說就是一套操作文檔內容的方法。
需要注意的是,我們需要把DOM當作一個整體,不能分割看待,即DOM(文檔對象模型)是一套操作文檔內容的方法。
DOM把以上內容看作都是對象
<!DOCTYPE html> <html> <head> <title>Shopping list</title> <meta charset="utf-8"> </head> <body> <h1>What to buy</h1> <p id="buy" title="a gentle reminder">Don't forget to buy this stuff</p> <ul id="purchases"> <li>A tin od beans</li> <li>Cheese</li> <li>Milk</li> </ul> </body> </html>
1、獲取DOM四種基本方法
1、getElementById()
2、getElementsByTagname()
3、getAttribute()
4、setAttribute()
常用的兩種解析:
1. getElementById():
參數:元素的ID值。 (元素節點簡稱元素)
返回值:一個有指定ID的元素對象(元素是對象)
注:這個方法是與document對象相關聯,只能由document對象調用。
用法:document.getElementById(Id)
例:
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="time">2020-04-16</div> <script> // 1. 因為我們文檔頁面從上往下加載,所以先得有標簽 所以我們script寫到標簽的下面 // 2. get 獲得 element 元素 by 通過 駝峰命名法 // 3. 參數 id是大小寫敏感的字符串 // 4. 返回的是一個元素對象 var timer = document.getElementById('time'); console.log(timer); console.log(typeof timer); // 5. console.dir 打印我們返回的元素對象 更好的查看里面的屬性和方法 console.dir(timer); </script> </body> </html>
看一下控制臺打印的是什么
可以看到 console.log(timer)打印出來的是整個div標簽
timer類型是個對象
2. getElementsByTagName():
參數:元素名
返回值:一個對象數組。這個數組里每個元素都是對象,每個對象分別對應著文檔里給定標簽的一個元素。
注:這個方法可和一般元素關聯。這個方法允許我們把通配符當作它的參數,返回在某份html文檔里總共有多少個元素節點。
用法:element.getElementsByTagName(TagName)
例:
var items=document.getElementsByTagName("li");
items.length;//3
document.getElementsByTagName(“*”);//12
2、事件基礎
3.1 事件概述
JavaScript使我們有能力創建動態頁面,而事件是可以被JavaScript偵測到的行為。
簡單理解:觸發——>響應機制
網頁中每個元素都可以產生某些可以觸發JavaScript的事件,例如,我們可以在用戶點擊某按鈕產生一個事件,然后去執行某些操作
3.2 事件三要素
事件源 、事件類型、事件處理程序,我們也稱為事件三要素
(1) 事件源 事件被觸發的對象 誰
(2) 事件類型 如何觸發 什么事件 比如鼠標點擊(onclick) 還是鼠標經過 還是鍵盤按下
(3) 事件處理程序 通過一個函數賦值的方式 完成
代碼實例
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <button id="btn">唐伯虎</button> <script> // 點擊一個按鈕,彈出對話框 // 1. 事件是有三部分組成 事件源 事件類型 事件處理程序 我們也稱為事件三要素 //(1) 事件源 事件被觸發的對象 誰 按鈕 var btn = document.getElementById('btn'); //(2) 事件類型 如何觸發 什么事件 比如鼠標點擊(onclick) 還是鼠標經過 還是鍵盤按下 //(3) 事件處理程序 通過一個函數賦值的方式 完成 btn.onclick = function() { alert('點秋香'); } </script> </body> </html>
運行結果
1、獲取事件源
2、注冊事件(綁定事件)
3、添加事件處理程序(采取函數賦值形式)
代碼實戰
-
<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div>123</div> <script> // 執行事件步驟 // 點擊div 控制臺輸出 我被選中了 // 1. 獲取事件源 var div = document.querySelector('div'); // 2.綁定事件 注冊事件 // div.onclick // 3.添加事件處理程序 div.onclick = function() { console.log('我被選中了'); } </script> </body> </html>
常用的DOM事件
onclick事件---當用戶點擊時執行
onload事件---當用戶進入時執行
onunload事件---用用戶離開時執行
onmouseover事件---當用戶鼠標指針移入時執行
onmouseout事件---當用戶鼠標指針移出時執行
onmousedown事件---當用戶鼠標摁下時執行
onmouseup事件---當用戶鼠標松開時執行
————————————————
版權聲明:本文為CSDN博主「那是我吶」的原創文章,遵循CC 4.0 BY-SA版權協議,轉載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/weixin_42402867/article/details/105567787
文章目錄
繼承性的描述:
繼承性是指被包在內部的標簽將擁有外部標簽的樣式性,即子元素可以繼承父類的屬性。
例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> div{ color: blue; } </style> </head> <body> <div>父元素 <div>子元素 <p>我依舊是子元素</p> </div> </div> </body> </html>
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> p{ font-size: 32px; } </style> </head> <body> <p style="color: blue;">我這里體現了層疊性呀</p> </body> </html>
使用結論
由于內容有限,但是結論是一定的,所以我直接給出結論:
若多個選擇器定義的樣式不沖突,則元素應用所有選擇器定義的樣式。
若多個選擇器定義的樣式發生沖突(比如:同時定義了字體顏色屬性),則CSS按照選擇器的優先級,讓元素應用優先級搞得選擇器樣式。
CSS定義的選擇器優先級從高到低為:行內樣式–>ID樣式–>類樣式–>標記樣式。
如若想直接定義使用哪個樣式,不考慮優先級的話,則使用!important,把這個加在樣式后面就行了。
優先級
定義CSS樣式時,經常出現兩個或更多規則應用在同一個元素上,這時就會出現優先級的問題。層疊性和選擇器的圈中有很大的關系。
優先級的使用說明
權重分析:
內聯樣式:如:style="",權重為1000。
ID選擇器,如:#content,權重為100。
類,偽類和屬性選擇器,如.content,權重為10。
標簽選擇器和偽元素選擇器,如div p,權重為1。
繼承樣式,權重為0。
將基本選擇器的權重相加之和,就是權重大小,值越大,權重越高。
計算權重方法
數標簽:先數權重最高的標簽,然后數第二高權重的標簽,以此類推,就會生成一個數組,里面包含四個數字。
比如(0,0,0,0)分別對應(行內式個數,id選擇器個數,類選擇器個數,標簽選擇器個數)
然后兩個選擇器通過對別四個數字的大小,確定權重關系。
例:
#box ul li a.cur有1個id標簽,1個類,3個標簽,那么4個0就是(0,1,1,3)
.nav ul .active .cur有0個id,3個類,1個標簽,那么4個0就是(0,0,3,1)
例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <style> .p1{ color: blue; } #p1{ color: red; } </style> </head> <body> <p id="p1" class="p1">我們來試一下優先級</p> </body> </html>
先推測一波,因為前面講到了ID選擇器的權重是大于類選擇器的,所以這里顏色應該為red。
效果如下:
推測正確!優先級GET!
藍藍設計的小編 http://www.syprn.cn